From 64b3e488da807351e03081b04ef07bdd6dbae3c5 Mon Sep 17 00:00:00 2001 From: bathfire <> Date: Mon, 27 Apr 2026 16:55:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E7=A1=80=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 41 + .../STM32F4xx_StdPeriph_Driver/inc/misc.h | 172 + .../inc/stm32f4xx_adc.h | 643 + .../inc/stm32f4xx_can.h | 638 + .../inc/stm32f4xx_crc.h | 77 + .../inc/stm32f4xx_cryp.h | 338 + .../inc/stm32f4xx_dac.h | 298 + .../inc/stm32f4xx_dbgmcu.h | 103 + .../inc/stm32f4xx_dcmi.h | 306 + .../inc/stm32f4xx_dma.h | 603 + .../inc/stm32f4xx_exti.h | 177 + .../inc/stm32f4xx_flash.h | 334 + .../inc/stm32f4xx_fsmc.h | 669 + .../inc/stm32f4xx_gpio.h | 406 + .../inc/stm32f4xx_hash.h | 244 + .../inc/stm32f4xx_i2c.h | 692 + .../inc/stm32f4xx_iwdg.h | 125 + .../inc/stm32f4xx_pwr.h | 179 + .../inc/stm32f4xx_rcc.h | 510 + .../inc/stm32f4xx_rng.h | 114 + .../inc/stm32f4xx_rtc.h | 875 + .../inc/stm32f4xx_sdio.h | 530 + .../inc/stm32f4xx_spi.h | 537 + .../inc/stm32f4xx_syscfg.h | 173 + .../inc/stm32f4xx_tim.h | 1144 ++ .../inc/stm32f4xx_usart.h | 423 + .../inc/stm32f4xx_wwdg.h | 105 + .../STM32F4xx_StdPeriph_Driver/src/misc.c | 243 + .../src/stm32f4xx_adc.c | 1742 ++ .../src/stm32f4xx_can.c | 1698 ++ .../src/stm32f4xx_crc.c | 127 + .../src/stm32f4xx_cryp.c | 850 + .../src/stm32f4xx_cryp_aes.c | 638 + .../src/stm32f4xx_cryp_des.c | 291 + .../src/stm32f4xx_cryp_tdes.c | 308 + .../src/stm32f4xx_dac.c | 701 + .../src/stm32f4xx_dbgmcu.c | 174 + .../src/stm32f4xx_dcmi.c | 534 + .../src/stm32f4xx_dma.c | 1283 ++ .../src/stm32f4xx_exti.c | 306 + .../src/stm32f4xx_flash.c | 1056 ++ .../src/stm32f4xx_fsmc.c | 982 ++ .../src/stm32f4xx_gpio.c | 561 + .../src/stm32f4xx_hash.c | 700 + .../src/stm32f4xx_hash_md5.c | 314 + .../src/stm32f4xx_hash_sha1.c | 317 + .../src/stm32f4xx_i2c.c | 1395 ++ .../src/stm32f4xx_iwdg.c | 263 + .../src/stm32f4xx_pwr.c | 656 + .../src/stm32f4xx_rcc.c | 1808 ++ .../src/stm32f4xx_rng.c | 399 + .../src/stm32f4xx_rtc.c | 2732 +++ .../src/stm32f4xx_sdio.c | 1004 ++ .../src/stm32f4xx_spi.c | 1286 ++ .../src/stm32f4xx_syscfg.c | 197 + .../src/stm32f4xx_tim.c | 3352 ++++ .../src/stm32f4xx_usart.c | 1463 ++ .../src/stm32f4xx_wwdg.c | 303 + .../Class/audio/inc/usbd_audio_core.h | 158 + .../Class/audio/inc/usbd_audio_out_if.h | 117 + .../Class/audio/src/usbd_audio_core.c | 665 + .../Class/audio/src/usbd_audio_out_if.c | 318 + .../Class/cdc/inc/usbd_cdc_core.h | 137 + .../Class/cdc/inc/usbd_cdc_if_template.h | 45 + .../Class/cdc/src/usbd_cdc_core.c | 811 + .../Class/cdc/src/usbd_cdc_if_template.c | 202 + .../Class/dfu/inc/usbd_dfu_core.h | 187 + .../Class/dfu/inc/usbd_dfu_mal.h | 79 + .../Class/dfu/inc/usbd_flash_if.h | 49 + .../Class/dfu/inc/usbd_mem_if_template.h | 46 + .../Class/dfu/inc/usbd_otp_if.h | 43 + .../Class/dfu/src/usbd_dfu_core.c | 1046 ++ .../Class/dfu/src/usbd_dfu_mal.c | 281 + .../Class/dfu/src/usbd_flash_if.c | 221 + .../Class/dfu/src/usbd_mem_if_template.c | 133 + .../Class/dfu/src/usbd_otp_if.c | 120 + .../Class/hid/inc/usbd_hid_core.h | 110 + .../Class/hid/src/usbd_hid_core.c | 460 + .../Class/msc/inc/usbd_msc_bot.h | 147 + .../Class/msc/inc/usbd_msc_core.h | 72 + .../Class/msc/inc/usbd_msc_data.h | 98 + .../Class/msc/inc/usbd_msc_mem.h | 106 + .../Class/msc/inc/usbd_msc_scsi.h | 189 + .../Class/msc/src/usbd_msc_bot.c | 393 + .../Class/msc/src/usbd_msc_core.c | 490 + .../Class/msc/src/usbd_msc_data.c | 128 + .../Class/msc/src/usbd_msc_scsi.c | 722 + .../Class/msc/src/usbd_storage_template.c | 179 + .../Core/inc/usbd_conf_template.h | 78 + .../Core/inc/usbd_core.h | 114 + .../Core/inc/usbd_def.h | 149 + .../Core/inc/usbd_ioreq.h | 115 + .../Core/inc/usbd_req.h | 102 + .../Core/inc/usbd_usr.h | 135 + .../Core/src/usbd_core.c | 476 + .../Core/src/usbd_ioreq.c | 237 + .../Core/src/usbd_req.c | 868 + .../Release_Notes.html | 941 + .../Class/HID/inc/usbh_hid_core.h | 195 + .../Class/HID/inc/usbh_hid_keybd.h | 122 + .../Class/HID/inc/usbh_hid_mouse.h | 114 + .../Class/HID/src/usbh_hid_core.c | 640 + .../Class/HID/src/usbh_hid_keybd.c | 338 + .../Class/HID/src/usbh_hid_mouse.c | 155 + .../Class/MSC/inc/usbh_msc_bot.h | 221 + .../Class/MSC/inc/usbh_msc_core.h | 141 + .../Class/MSC/inc/usbh_msc_scsi.h | 163 + .../Class/MSC/src/usbh_msc_bot.c | 613 + .../Class/MSC/src/usbh_msc_core.c | 559 + .../Class/MSC/src/usbh_msc_fatfs.c | 186 + .../Class/MSC/src/usbh_msc_scsi.c | 674 + .../Core/inc/usbh_conf_template.h | 94 + .../Core/inc/usbh_core.h | 289 + .../Core/inc/usbh_def.h | 280 + .../Core/inc/usbh_hcs.h | 125 + .../Core/inc/usbh_ioreq.h | 140 + .../Core/inc/usbh_stdreq.h | 148 + .../Core/src/usbh_core.c | 842 + .../Core/src/usbh_hcs.c | 253 + .../Core/src/usbh_ioreq.c | 419 + .../Core/src/usbh_stdreq.c | 551 + .../STM32_USB_HOST_Library/Release_Notes.html | 944 + .../STM32_USB_OTG_Driver/Release_Notes.html | 941 + Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h | 97 + .../inc/usb_conf_template.h | 287 + Libraries/STM32_USB_OTG_Driver/inc/usb_core.h | 408 + Libraries/STM32_USB_OTG_Driver/inc/usb_dcd.h | 158 + .../STM32_USB_OTG_Driver/inc/usb_dcd_int.h | 121 + .../STM32_USB_OTG_Driver/inc/usb_defines.h | 244 + Libraries/STM32_USB_OTG_Driver/inc/usb_hcd.h | 102 + .../STM32_USB_OTG_Driver/inc/usb_hcd_int.h | 126 + Libraries/STM32_USB_OTG_Driver/inc/usb_otg.h | 94 + Libraries/STM32_USB_OTG_Driver/inc/usb_regs.h | 1206 ++ .../src/usb_bsp_template.c | 200 + Libraries/STM32_USB_OTG_Driver/src/usb_core.c | 2187 +++ Libraries/STM32_USB_OTG_Driver/src/usb_dcd.c | 472 + .../STM32_USB_OTG_Driver/src/usb_dcd_int.c | 886 + Libraries/STM32_USB_OTG_Driver/src/usb_hcd.c | 256 + .../STM32_USB_OTG_Driver/src/usb_hcd_int.c | 832 + Libraries/STM32_USB_OTG_Driver/src/usb_otg.c | 175 + System/arm_common_tables.h | 35 + System/arm_math.h | 7051 ++++++++ System/core_cm0.h | 665 + System/core_cm3.h | 1236 ++ System/core_cm4.h | 1378 ++ System/core_cm4_simd.h | 701 + System/core_cmFunc.h | 609 + System/core_cmInstr.h | 585 + System/startup_stm32f4xx.s | 427 + System/stm32f4xx.h | 7011 ++++++++ System/system_stm32f4xx.h | 99 + User/AT45DB/at45db.c | 347 + User/AT45DB/at45db.h | 95 + User/Analog/Analog.c | 275 + User/Analog/Analog.h | 26 + User/CH376_Driver/CH376INC.h | 916 + User/CH376_Driver/FILE_SYS.H | 170 + User/CH376_Driver/FILE_SYS.c | 1899 ++ User/DS1307/DS1307.c | 242 + User/DS1307/DS1307.h | 32 + User/Delay/delay.c | 39 + User/Delay/delay.h | 10 + User/FRam/FRam.c | 436 + User/FRam/FRam.h | 191 + User/FRam/FRam.h~RF1bdf050.TMP | 445 + User/GPS/GPS.c | 403 + User/GPS/GPS.h | 57 + User/Log/Log.c | 201 + User/Log/Log.h | 16 + User/MD_Connect/MD_Connect.c | 7480 ++++++++ User/MD_Connect/MD_Connect.h | 293 + User/Multiplex_Port/Multiplex_Port.c | 829 + User/Multiplex_Port/Multiplex_Port.h | 47 + User/OLED/bmp.h | 43 + User/OLED/oled.c | 449 + User/OLED/oled.h | 42 + User/OLED/oledfont.h | 426 + User/POS_Connect/POS_Connect.c | 3615 ++++ User/POS_Connect/POS_Connect.h | 137 + User/Printf/Printf.c | 176 + User/Printf/Printf.h | 75 + User/Printf/print.c | 219 + User/Printf/print.h | 71 + User/Pulse_InPut/Pluse_InPut.c | 160 + User/Pulse_InPut/Pluse_InPut.h | 52 + User/Pulse_PutOut/Pluse_Putout.c | 43 + User/Pulse_PutOut/Pluse_Putout.h | 18 + User/SensorCount/SensorCount.c | 295 + User/SensorCount/SensorCount.h | 50 + User/Surface/Surface.c | 1433 ++ User/Surface/Surface.h | 56 + User/TXH.bin | Bin 0 -> 234936 bytes User/TXH/TXH.c | 259 + User/TXH/TXH.h | 729 + User/Timer/time_count.c | 154 + User/Timer/time_count.h | 34 + User/config.h | 47 + User/main.c | 30 + User/stm32f4xx_conf.h | 142 + User/stm32f4xx_it.c | 95 + User/stm32f4xx_it.h | 46 + User/system_stm32f4xx.c | 553 + User/加密/TXH_V0.1.6.bin | Bin 0 -> 70296 bytes User/加密/TXH_V0.1.7.bin | Bin 0 -> 72816 bytes User/加密/TXH_V0.1.9.bin | Bin 0 -> 72800 bytes User/加密/TXH_V1.1.4.bin | Bin 0 -> 78948 bytes User/加密/TXH_V1.1.7.bin | Bin 0 -> 71872 bytes User/加密/TXH_V1.1.8.bin | Bin 0 -> 72792 bytes User/加密/TXH_V1.2.0.bin | Bin 0 -> 78704 bytes User/加密/TXH_V1.2.1.bin | Bin 0 -> 79512 bytes User/加密/TXH_V1.2.1_BIN.zip | Bin 0 -> 40735 bytes User/加密/TXH_V1.2.2.bin | Bin 0 -> 80568 bytes User/加密/TXH_V1.2.2.zip | Bin 0 -> 41635 bytes User/加密/TXH_V1.2.3.bin | Bin 0 -> 82568 bytes User/加密/TXH_V1.2.3.zip | Bin 0 -> 42535 bytes User/加密/TXH_V1.2.4.bin | Bin 0 -> 82568 bytes User/加密/TXH_V1.2.4.zip | Bin 0 -> 42535 bytes User/加密/TXH_V1.2.5.bin | Bin 0 -> 86544 bytes User/加密/TXH_V1.2.5.zip | Bin 0 -> 43603 bytes User/加密/TXH_V1.2.7.bin | Bin 0 -> 95492 bytes User/加密/TXH_V1.2.7.zip | Bin 0 -> 47747 bytes User/加密/TXH_V1.2.8.bin | Bin 0 -> 95556 bytes User/加密/TXH_V1.2.8.zip | Bin 0 -> 48181 bytes User/加密/TXH_V1.2.9.bin | Bin 0 -> 100780 bytes User/加密/TXH_V1.3.1.bin | Bin 0 -> 205848 bytes User/加密/TXH_V1.3.2.bin | Bin 0 -> 208000 bytes User/加密/TXH_V1.3.3.bin | Bin 0 -> 183304 bytes User/加密/TXH_V1.3.4.bin | Bin 0 -> 187728 bytes User/加密/TXH_V1.3.4.zip | Bin 0 -> 67909 bytes User/加密/TXH_V1.3.5.bin | Bin 0 -> 188072 bytes User/加密/TXH_V1.3.5.zip | Bin 0 -> 67948 bytes User/加密/TXH_V1.3.6.bin | Bin 0 -> 187928 bytes User/加密/TXH_V1.3.6.zip | Bin 0 -> 67854 bytes User/加密/TXH_V1.3.7.bin | Bin 0 -> 227800 bytes User/加密/TXH_V1.3.8.bin | Bin 0 -> 227944 bytes User/加密/TXH_V1.3.9.bin | Bin 0 -> 228120 bytes User/加密/TXH_V1.4.0.bin | Bin 0 -> 231416 bytes User/加密/TXH_V1.4.1.bin | Bin 0 -> 231512 bytes User/加密/TXH_V1.4.2.bin | Bin 0 -> 231504 bytes User/加密/TXH_V1.4.3.bin | Bin 0 -> 231424 bytes User/加密/TXH_V1.4.4.bin | Bin 0 -> 234232 bytes User/加密/TXH_V1.4.5.bin | Bin 0 -> 234712 bytes User/加密/TXH_V1.4.6.bin | Bin 0 -> 234960 bytes obj/TXH.hex | 14691 ++++++++++++++++ obj/TXH_V0.3.0.hex | 11765 +++++++++++++ obj/TXH_V1.2.0.hex | 4963 ++++++ obj/TXH_V1.2.1.hex | 4974 ++++++ obj/TXH_V1.2.2.hex | 5051 ++++++ obj/TXH_V1.2.5.hex | 5423 ++++++ obj/TXH_V1.2.6.hex | 5678 ++++++ obj/TXH_V1.2.7.hex | 5973 +++++++ obj/TXH_V1.2.8.hex | 5964 +++++++ obj/TXH_V1.2.9.hex | 6522 +++++++ obj/TXH_V1.3.0.hex | 11768 +++++++++++++ obj/TXH_V1.3.2.hex | 12955 ++++++++++++++ obj/TXH_V1.3.3.hex | 11390 ++++++++++++ obj/TXH_V1.3.4.hex | 11389 ++++++++++++ obj/TXH_V1.3.6.hex | 11752 ++++++++++++ obj/TXH_V1.3.7.hex | 13818 +++++++++++++++ obj/TXH_V1.3.8.hex | 14251 +++++++++++++++ obj/TXH_V1.3.9.hex | 14264 +++++++++++++++ obj/TXH_V1.4.0.hex | 14471 +++++++++++++++ obj/TXH_V1.4.1.hex | 14470 +++++++++++++++ obj/TXH_V1.4.2.hex | 14471 +++++++++++++++ obj/TXH_V1.4.3.hex | 14471 +++++++++++++++ obj/TXH_V1.4.4.hex | 14658 +++++++++++++++ obj/TXH_V1.4.5.hex | 14658 +++++++++++++++ obj/build/Target 1/TXH.bin | Bin 0 -> 228088 bytes obj/build/Target 1/TXH.hex | 14262 +++++++++++++++ 269 files changed, 383851 insertions(+) create mode 100644 .gitignore create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/misc.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_adc.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_can.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_crc.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_cryp.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dac.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dcmi.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_exti.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_flash.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_fsmc.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_hash.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_iwdg.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rng.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rtc.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_syscfg.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_usart.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_wwdg.h create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/misc.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_can.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_crc.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_aes.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_des.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_tdes.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dac.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dbgmcu.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dcmi.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_flash.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_fsmc.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash_md5.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash_sha1.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_i2c.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_iwdg.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rng.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_sdio.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c create mode 100644 Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_wwdg.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h create mode 100644 Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c create mode 100644 Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c create mode 100644 Libraries/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h create mode 100644 Libraries/STM32_USB_Device_Library/Core/inc/usbd_core.h create mode 100644 Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h create mode 100644 Libraries/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h create mode 100644 Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h create mode 100644 Libraries/STM32_USB_Device_Library/Core/inc/usbd_usr.h create mode 100644 Libraries/STM32_USB_Device_Library/Core/src/usbd_core.c create mode 100644 Libraries/STM32_USB_Device_Library/Core/src/usbd_ioreq.c create mode 100644 Libraries/STM32_USB_Device_Library/Core/src/usbd_req.c create mode 100644 Libraries/STM32_USB_Device_Library/Release_Notes.html create mode 100644 Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_core.h create mode 100644 Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_keybd.h create mode 100644 Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_mouse.h create mode 100644 Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_core.c create mode 100644 Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_keybd.c create mode 100644 Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_mouse.c create mode 100644 Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_bot.h create mode 100644 Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_core.h create mode 100644 Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_scsi.h create mode 100644 Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_bot.c create mode 100644 Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_core.c create mode 100644 Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_fatfs.c create mode 100644 Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_scsi.c create mode 100644 Libraries/STM32_USB_HOST_Library/Core/inc/usbh_conf_template.h create mode 100644 Libraries/STM32_USB_HOST_Library/Core/inc/usbh_core.h create mode 100644 Libraries/STM32_USB_HOST_Library/Core/inc/usbh_def.h create mode 100644 Libraries/STM32_USB_HOST_Library/Core/inc/usbh_hcs.h create mode 100644 Libraries/STM32_USB_HOST_Library/Core/inc/usbh_ioreq.h create mode 100644 Libraries/STM32_USB_HOST_Library/Core/inc/usbh_stdreq.h create mode 100644 Libraries/STM32_USB_HOST_Library/Core/src/usbh_core.c create mode 100644 Libraries/STM32_USB_HOST_Library/Core/src/usbh_hcs.c create mode 100644 Libraries/STM32_USB_HOST_Library/Core/src/usbh_ioreq.c create mode 100644 Libraries/STM32_USB_HOST_Library/Core/src/usbh_stdreq.c create mode 100644 Libraries/STM32_USB_HOST_Library/Release_Notes.html create mode 100644 Libraries/STM32_USB_OTG_Driver/Release_Notes.html create mode 100644 Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h create mode 100644 Libraries/STM32_USB_OTG_Driver/inc/usb_conf_template.h create mode 100644 Libraries/STM32_USB_OTG_Driver/inc/usb_core.h create mode 100644 Libraries/STM32_USB_OTG_Driver/inc/usb_dcd.h create mode 100644 Libraries/STM32_USB_OTG_Driver/inc/usb_dcd_int.h create mode 100644 Libraries/STM32_USB_OTG_Driver/inc/usb_defines.h create mode 100644 Libraries/STM32_USB_OTG_Driver/inc/usb_hcd.h create mode 100644 Libraries/STM32_USB_OTG_Driver/inc/usb_hcd_int.h create mode 100644 Libraries/STM32_USB_OTG_Driver/inc/usb_otg.h create mode 100644 Libraries/STM32_USB_OTG_Driver/inc/usb_regs.h create mode 100644 Libraries/STM32_USB_OTG_Driver/src/usb_bsp_template.c create mode 100644 Libraries/STM32_USB_OTG_Driver/src/usb_core.c create mode 100644 Libraries/STM32_USB_OTG_Driver/src/usb_dcd.c create mode 100644 Libraries/STM32_USB_OTG_Driver/src/usb_dcd_int.c create mode 100644 Libraries/STM32_USB_OTG_Driver/src/usb_hcd.c create mode 100644 Libraries/STM32_USB_OTG_Driver/src/usb_hcd_int.c create mode 100644 Libraries/STM32_USB_OTG_Driver/src/usb_otg.c create mode 100644 System/arm_common_tables.h create mode 100644 System/arm_math.h create mode 100644 System/core_cm0.h create mode 100644 System/core_cm3.h create mode 100644 System/core_cm4.h create mode 100644 System/core_cm4_simd.h create mode 100644 System/core_cmFunc.h create mode 100644 System/core_cmInstr.h create mode 100644 System/startup_stm32f4xx.s create mode 100644 System/stm32f4xx.h create mode 100644 System/system_stm32f4xx.h create mode 100644 User/AT45DB/at45db.c create mode 100644 User/AT45DB/at45db.h create mode 100644 User/Analog/Analog.c create mode 100644 User/Analog/Analog.h create mode 100644 User/CH376_Driver/CH376INC.h create mode 100644 User/CH376_Driver/FILE_SYS.H create mode 100644 User/CH376_Driver/FILE_SYS.c create mode 100644 User/DS1307/DS1307.c create mode 100644 User/DS1307/DS1307.h create mode 100644 User/Delay/delay.c create mode 100644 User/Delay/delay.h create mode 100644 User/FRam/FRam.c create mode 100644 User/FRam/FRam.h create mode 100644 User/FRam/FRam.h~RF1bdf050.TMP create mode 100644 User/GPS/GPS.c create mode 100644 User/GPS/GPS.h create mode 100644 User/Log/Log.c create mode 100644 User/Log/Log.h create mode 100644 User/MD_Connect/MD_Connect.c create mode 100644 User/MD_Connect/MD_Connect.h create mode 100644 User/Multiplex_Port/Multiplex_Port.c create mode 100644 User/Multiplex_Port/Multiplex_Port.h create mode 100644 User/OLED/bmp.h create mode 100644 User/OLED/oled.c create mode 100644 User/OLED/oled.h create mode 100644 User/OLED/oledfont.h create mode 100644 User/POS_Connect/POS_Connect.c create mode 100644 User/POS_Connect/POS_Connect.h create mode 100644 User/Printf/Printf.c create mode 100644 User/Printf/Printf.h create mode 100644 User/Printf/print.c create mode 100644 User/Printf/print.h create mode 100644 User/Pulse_InPut/Pluse_InPut.c create mode 100644 User/Pulse_InPut/Pluse_InPut.h create mode 100644 User/Pulse_PutOut/Pluse_Putout.c create mode 100644 User/Pulse_PutOut/Pluse_Putout.h create mode 100644 User/SensorCount/SensorCount.c create mode 100644 User/SensorCount/SensorCount.h create mode 100644 User/Surface/Surface.c create mode 100644 User/Surface/Surface.h create mode 100644 User/TXH.bin create mode 100644 User/TXH/TXH.c create mode 100644 User/TXH/TXH.h create mode 100644 User/Timer/time_count.c create mode 100644 User/Timer/time_count.h create mode 100644 User/config.h create mode 100644 User/main.c create mode 100644 User/stm32f4xx_conf.h create mode 100644 User/stm32f4xx_it.c create mode 100644 User/stm32f4xx_it.h create mode 100644 User/system_stm32f4xx.c create mode 100644 User/加密/TXH_V0.1.6.bin create mode 100644 User/加密/TXH_V0.1.7.bin create mode 100644 User/加密/TXH_V0.1.9.bin create mode 100644 User/加密/TXH_V1.1.4.bin create mode 100644 User/加密/TXH_V1.1.7.bin create mode 100644 User/加密/TXH_V1.1.8.bin create mode 100644 User/加密/TXH_V1.2.0.bin create mode 100644 User/加密/TXH_V1.2.1.bin create mode 100644 User/加密/TXH_V1.2.1_BIN.zip create mode 100644 User/加密/TXH_V1.2.2.bin create mode 100644 User/加密/TXH_V1.2.2.zip create mode 100644 User/加密/TXH_V1.2.3.bin create mode 100644 User/加密/TXH_V1.2.3.zip create mode 100644 User/加密/TXH_V1.2.4.bin create mode 100644 User/加密/TXH_V1.2.4.zip create mode 100644 User/加密/TXH_V1.2.5.bin create mode 100644 User/加密/TXH_V1.2.5.zip create mode 100644 User/加密/TXH_V1.2.7.bin create mode 100644 User/加密/TXH_V1.2.7.zip create mode 100644 User/加密/TXH_V1.2.8.bin create mode 100644 User/加密/TXH_V1.2.8.zip create mode 100644 User/加密/TXH_V1.2.9.bin create mode 100644 User/加密/TXH_V1.3.1.bin create mode 100644 User/加密/TXH_V1.3.2.bin create mode 100644 User/加密/TXH_V1.3.3.bin create mode 100644 User/加密/TXH_V1.3.4.bin create mode 100644 User/加密/TXH_V1.3.4.zip create mode 100644 User/加密/TXH_V1.3.5.bin create mode 100644 User/加密/TXH_V1.3.5.zip create mode 100644 User/加密/TXH_V1.3.6.bin create mode 100644 User/加密/TXH_V1.3.6.zip create mode 100644 User/加密/TXH_V1.3.7.bin create mode 100644 User/加密/TXH_V1.3.8.bin create mode 100644 User/加密/TXH_V1.3.9.bin create mode 100644 User/加密/TXH_V1.4.0.bin create mode 100644 User/加密/TXH_V1.4.1.bin create mode 100644 User/加密/TXH_V1.4.2.bin create mode 100644 User/加密/TXH_V1.4.3.bin create mode 100644 User/加密/TXH_V1.4.4.bin create mode 100644 User/加密/TXH_V1.4.5.bin create mode 100644 User/加密/TXH_V1.4.6.bin create mode 100644 obj/TXH.hex create mode 100644 obj/TXH_V0.3.0.hex create mode 100644 obj/TXH_V1.2.0.hex create mode 100644 obj/TXH_V1.2.1.hex create mode 100644 obj/TXH_V1.2.2.hex create mode 100644 obj/TXH_V1.2.5.hex create mode 100644 obj/TXH_V1.2.6.hex create mode 100644 obj/TXH_V1.2.7.hex create mode 100644 obj/TXH_V1.2.8.hex create mode 100644 obj/TXH_V1.2.9.hex create mode 100644 obj/TXH_V1.3.0.hex create mode 100644 obj/TXH_V1.3.2.hex create mode 100644 obj/TXH_V1.3.3.hex create mode 100644 obj/TXH_V1.3.4.hex create mode 100644 obj/TXH_V1.3.6.hex create mode 100644 obj/TXH_V1.3.7.hex create mode 100644 obj/TXH_V1.3.8.hex create mode 100644 obj/TXH_V1.3.9.hex create mode 100644 obj/TXH_V1.4.0.hex create mode 100644 obj/TXH_V1.4.1.hex create mode 100644 obj/TXH_V1.4.2.hex create mode 100644 obj/TXH_V1.4.3.hex create mode 100644 obj/TXH_V1.4.4.hex create mode 100644 obj/TXH_V1.4.5.hex create mode 100644 obj/build/Target 1/TXH.bin create mode 100644 obj/build/Target 1/TXH.hex diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b4c109 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# ===== obj 目录:只保留 .hex 和 .bin,忽略其他所有文件 ===== +# 先忽略 obj 下所有内容(但不忽略目录本身,以便 git 能遍历子目录) +obj/**/* +# 重新允许目录进入(否则 git 不会进入被忽略的目录查找 .hex/.bin) +!obj/**/ +# 允许 .hex 和 .bin +!obj/**/*.hex +!obj/**/*.bin + +# ===== 通用忽略规则 ===== +# Keil / IDE 生成文件 +*.lst +*.crf +*.d +*.axf +*.htm +*.lnp +*.dep +*.iex +*.scvd +*.uvguix.* + +# 日志和临时文件 +JLinkLog.txt +*.build_log.htm + +# 压缩包(obj 目录内的 zip) +obj/*.zip + +# IDE 和编辑器 +.vscode/ +.settings/ +.eide/ +.idea/ +*.ept +*.eide-template + +# 系统文件 +Thumbs.db +Desktop.ini +.DS_Store diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/misc.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/misc.h new file mode 100644 index 0000000..cedbd01 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/misc.h @@ -0,0 +1,172 @@ +/** + ****************************************************************************** + * @file misc.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the miscellaneous + * firmware library functions (add-on to CMSIS functions). + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_ADC_H +#define __STM32F4xx_ADC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup ADC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief ADC Init structure definition + */ +typedef struct +{ + uint32_t ADC_Resolution; /*!< Configures the ADC resolution dual mode. + This parameter can be a value of @ref ADC_resolution */ + FunctionalState ADC_ScanConvMode; /*!< Specifies whether the conversion + is performed in Scan (multichannels) + or Single (one channel) mode. + This parameter can be set to ENABLE or DISABLE */ + FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion + is performed in Continuous or Single mode. + This parameter can be set to ENABLE or DISABLE. */ + uint32_t ADC_ExternalTrigConvEdge; /*!< Select the external trigger edge and + enable the trigger of a regular group. + This parameter can be a value of + @ref ADC_external_trigger_edge_for_regular_channels_conversion */ + uint32_t ADC_ExternalTrigConv; /*!< Select the external event used to trigger + the start of conversion of a regular group. + This parameter can be a value of + @ref ADC_extrenal_trigger_sources_for_regular_channels_conversion */ + uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment + is left or right. This parameter can be + a value of @ref ADC_data_align */ + uint8_t ADC_NbrOfConversion; /*!< Specifies the number of ADC conversions + that will be done using the sequencer for + regular channel group. + This parameter must range from 1 to 16. */ +}ADC_InitTypeDef; + +/** + * @brief ADC Common Init structure definition + */ +typedef struct +{ + uint32_t ADC_Mode; /*!< Configures the ADC to operate in + independent or multi mode. + This parameter can be a value of @ref ADC_Common_mode */ + uint32_t ADC_Prescaler; /*!< Select the frequency of the clock + to the ADC. The clock is common for all the ADCs. + This parameter can be a value of @ref ADC_Prescaler */ + uint32_t ADC_DMAAccessMode; /*!< Configures the Direct memory access + mode for multi ADC mode. + This parameter can be a value of + @ref ADC_Direct_memory_access_mode_for_multi_mode */ + uint32_t ADC_TwoSamplingDelay; /*!< Configures the Delay between 2 sampling phases. + This parameter can be a value of + @ref ADC_delay_between_2_sampling_phases */ + +}ADC_CommonInitTypeDef; + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup ADC_Exported_Constants + * @{ + */ +#define IS_ADC_ALL_PERIPH(PERIPH) (((PERIPH) == ADC1) || \ + ((PERIPH) == ADC2) || \ + ((PERIPH) == ADC3)) + +/** @defgroup ADC_Common_mode + * @{ + */ +#define ADC_Mode_Independent ((uint32_t)0x00000000) +#define ADC_DualMode_RegSimult_InjecSimult ((uint32_t)0x00000001) +#define ADC_DualMode_RegSimult_AlterTrig ((uint32_t)0x00000002) +#define ADC_DualMode_InjecSimult ((uint32_t)0x00000005) +#define ADC_DualMode_RegSimult ((uint32_t)0x00000006) +#define ADC_DualMode_Interl ((uint32_t)0x00000007) +#define ADC_DualMode_AlterTrig ((uint32_t)0x00000009) +#define ADC_TripleMode_RegSimult_InjecSimult ((uint32_t)0x00000011) +#define ADC_TripleMode_RegSimult_AlterTrig ((uint32_t)0x00000012) +#define ADC_TripleMode_InjecSimult ((uint32_t)0x00000015) +#define ADC_TripleMode_RegSimult ((uint32_t)0x00000016) +#define ADC_TripleMode_Interl ((uint32_t)0x00000017) +#define ADC_TripleMode_AlterTrig ((uint32_t)0x00000019) +#define IS_ADC_MODE(MODE) (((MODE) == ADC_Mode_Independent) || \ + ((MODE) == ADC_DualMode_RegSimult_InjecSimult) || \ + ((MODE) == ADC_DualMode_RegSimult_AlterTrig) || \ + ((MODE) == ADC_DualMode_InjecSimult) || \ + ((MODE) == ADC_DualMode_RegSimult) || \ + ((MODE) == ADC_DualMode_Interl) || \ + ((MODE) == ADC_DualMode_AlterTrig) || \ + ((MODE) == ADC_TripleMode_RegSimult_InjecSimult) || \ + ((MODE) == ADC_TripleMode_RegSimult_AlterTrig) || \ + ((MODE) == ADC_TripleMode_InjecSimult) || \ + ((MODE) == ADC_TripleMode_RegSimult) || \ + ((MODE) == ADC_TripleMode_Interl) || \ + ((MODE) == ADC_TripleMode_AlterTrig)) +/** + * @} + */ + + +/** @defgroup ADC_Prescaler + * @{ + */ +#define ADC_Prescaler_Div2 ((uint32_t)0x00000000) +#define ADC_Prescaler_Div4 ((uint32_t)0x00010000) +#define ADC_Prescaler_Div6 ((uint32_t)0x00020000) +#define ADC_Prescaler_Div8 ((uint32_t)0x00030000) +#define IS_ADC_PRESCALER(PRESCALER) (((PRESCALER) == ADC_Prescaler_Div2) || \ + ((PRESCALER) == ADC_Prescaler_Div4) || \ + ((PRESCALER) == ADC_Prescaler_Div6) || \ + ((PRESCALER) == ADC_Prescaler_Div8)) +/** + * @} + */ + + +/** @defgroup ADC_Direct_memory_access_mode_for_multi_mode + * @{ + */ +#define ADC_DMAAccessMode_Disabled ((uint32_t)0x00000000) /* DMA mode disabled */ +#define ADC_DMAAccessMode_1 ((uint32_t)0x00004000) /* DMA mode 1 enabled (2 / 3 half-words one by one - 1 then 2 then 3)*/ +#define ADC_DMAAccessMode_2 ((uint32_t)0x00008000) /* DMA mode 2 enabled (2 / 3 half-words by pairs - 2&1 then 1&3 then 3&2)*/ +#define ADC_DMAAccessMode_3 ((uint32_t)0x0000C000) /* DMA mode 3 enabled (2 / 3 bytes by pairs - 2&1 then 1&3 then 3&2) */ +#define IS_ADC_DMA_ACCESS_MODE(MODE) (((MODE) == ADC_DMAAccessMode_Disabled) || \ + ((MODE) == ADC_DMAAccessMode_1) || \ + ((MODE) == ADC_DMAAccessMode_2) || \ + ((MODE) == ADC_DMAAccessMode_3)) + +/** + * @} + */ + + +/** @defgroup ADC_delay_between_2_sampling_phases + * @{ + */ +#define ADC_TwoSamplingDelay_5Cycles ((uint32_t)0x00000000) +#define ADC_TwoSamplingDelay_6Cycles ((uint32_t)0x00000100) +#define ADC_TwoSamplingDelay_7Cycles ((uint32_t)0x00000200) +#define ADC_TwoSamplingDelay_8Cycles ((uint32_t)0x00000300) +#define ADC_TwoSamplingDelay_9Cycles ((uint32_t)0x00000400) +#define ADC_TwoSamplingDelay_10Cycles ((uint32_t)0x00000500) +#define ADC_TwoSamplingDelay_11Cycles ((uint32_t)0x00000600) +#define ADC_TwoSamplingDelay_12Cycles ((uint32_t)0x00000700) +#define ADC_TwoSamplingDelay_13Cycles ((uint32_t)0x00000800) +#define ADC_TwoSamplingDelay_14Cycles ((uint32_t)0x00000900) +#define ADC_TwoSamplingDelay_15Cycles ((uint32_t)0x00000A00) +#define ADC_TwoSamplingDelay_16Cycles ((uint32_t)0x00000B00) +#define ADC_TwoSamplingDelay_17Cycles ((uint32_t)0x00000C00) +#define ADC_TwoSamplingDelay_18Cycles ((uint32_t)0x00000D00) +#define ADC_TwoSamplingDelay_19Cycles ((uint32_t)0x00000E00) +#define ADC_TwoSamplingDelay_20Cycles ((uint32_t)0x00000F00) +#define IS_ADC_SAMPLING_DELAY(DELAY) (((DELAY) == ADC_TwoSamplingDelay_5Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_6Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_7Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_8Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_9Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_10Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_11Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_12Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_13Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_14Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_15Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_16Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_17Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_18Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_19Cycles) || \ + ((DELAY) == ADC_TwoSamplingDelay_20Cycles)) + +/** + * @} + */ + + +/** @defgroup ADC_resolution + * @{ + */ +#define ADC_Resolution_12b ((uint32_t)0x00000000) +#define ADC_Resolution_10b ((uint32_t)0x01000000) +#define ADC_Resolution_8b ((uint32_t)0x02000000) +#define ADC_Resolution_6b ((uint32_t)0x03000000) +#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_Resolution_12b) || \ + ((RESOLUTION) == ADC_Resolution_10b) || \ + ((RESOLUTION) == ADC_Resolution_8b) || \ + ((RESOLUTION) == ADC_Resolution_6b)) + +/** + * @} + */ + + +/** @defgroup ADC_external_trigger_edge_for_regular_channels_conversion + * @{ + */ +#define ADC_ExternalTrigConvEdge_None ((uint32_t)0x00000000) +#define ADC_ExternalTrigConvEdge_Rising ((uint32_t)0x10000000) +#define ADC_ExternalTrigConvEdge_Falling ((uint32_t)0x20000000) +#define ADC_ExternalTrigConvEdge_RisingFalling ((uint32_t)0x30000000) +#define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigConvEdge_None) || \ + ((EDGE) == ADC_ExternalTrigConvEdge_Rising) || \ + ((EDGE) == ADC_ExternalTrigConvEdge_Falling) || \ + ((EDGE) == ADC_ExternalTrigConvEdge_RisingFalling)) +/** + * @} + */ + + +/** @defgroup ADC_extrenal_trigger_sources_for_regular_channels_conversion + * @{ + */ +#define ADC_ExternalTrigConv_T1_CC1 ((uint32_t)0x00000000) +#define ADC_ExternalTrigConv_T1_CC2 ((uint32_t)0x01000000) +#define ADC_ExternalTrigConv_T1_CC3 ((uint32_t)0x02000000) +#define ADC_ExternalTrigConv_T2_CC2 ((uint32_t)0x03000000) +#define ADC_ExternalTrigConv_T2_CC3 ((uint32_t)0x04000000) +#define ADC_ExternalTrigConv_T2_CC4 ((uint32_t)0x05000000) +#define ADC_ExternalTrigConv_T2_TRGO ((uint32_t)0x06000000) +#define ADC_ExternalTrigConv_T3_CC1 ((uint32_t)0x07000000) +#define ADC_ExternalTrigConv_T3_TRGO ((uint32_t)0x08000000) +#define ADC_ExternalTrigConv_T4_CC4 ((uint32_t)0x09000000) +#define ADC_ExternalTrigConv_T5_CC1 ((uint32_t)0x0A000000) +#define ADC_ExternalTrigConv_T5_CC2 ((uint32_t)0x0B000000) +#define ADC_ExternalTrigConv_T5_CC3 ((uint32_t)0x0C000000) +#define ADC_ExternalTrigConv_T8_CC1 ((uint32_t)0x0D000000) +#define ADC_ExternalTrigConv_T8_TRGO ((uint32_t)0x0E000000) +#define ADC_ExternalTrigConv_Ext_IT11 ((uint32_t)0x0F000000) +#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_ExternalTrigConv_T1_CC1) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T1_CC2) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T1_CC3) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T2_CC2) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T2_CC3) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T2_CC4) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T2_TRGO) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T3_CC1) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T3_TRGO) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T4_CC4) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T5_CC1) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T5_CC2) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T5_CC3) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T8_CC1) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T8_TRGO) || \ + ((REGTRIG) == ADC_ExternalTrigConv_Ext_IT11)) +/** + * @} + */ + + +/** @defgroup ADC_data_align + * @{ + */ +#define ADC_DataAlign_Right ((uint32_t)0x00000000) +#define ADC_DataAlign_Left ((uint32_t)0x00000800) +#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \ + ((ALIGN) == ADC_DataAlign_Left)) +/** + * @} + */ + + +/** @defgroup ADC_channels + * @{ + */ +#define ADC_Channel_0 ((uint8_t)0x00) +#define ADC_Channel_1 ((uint8_t)0x01) +#define ADC_Channel_2 ((uint8_t)0x02) +#define ADC_Channel_3 ((uint8_t)0x03) +#define ADC_Channel_4 ((uint8_t)0x04) +#define ADC_Channel_5 ((uint8_t)0x05) +#define ADC_Channel_6 ((uint8_t)0x06) +#define ADC_Channel_7 ((uint8_t)0x07) +#define ADC_Channel_8 ((uint8_t)0x08) +#define ADC_Channel_9 ((uint8_t)0x09) +#define ADC_Channel_10 ((uint8_t)0x0A) +#define ADC_Channel_11 ((uint8_t)0x0B) +#define ADC_Channel_12 ((uint8_t)0x0C) +#define ADC_Channel_13 ((uint8_t)0x0D) +#define ADC_Channel_14 ((uint8_t)0x0E) +#define ADC_Channel_15 ((uint8_t)0x0F) +#define ADC_Channel_16 ((uint8_t)0x10) +#define ADC_Channel_17 ((uint8_t)0x11) +#define ADC_Channel_18 ((uint8_t)0x12) + +#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_16) +#define ADC_Channel_Vrefint ((uint8_t)ADC_Channel_17) +#define ADC_Channel_Vbat ((uint8_t)ADC_Channel_18) + +#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || \ + ((CHANNEL) == ADC_Channel_1) || \ + ((CHANNEL) == ADC_Channel_2) || \ + ((CHANNEL) == ADC_Channel_3) || \ + ((CHANNEL) == ADC_Channel_4) || \ + ((CHANNEL) == ADC_Channel_5) || \ + ((CHANNEL) == ADC_Channel_6) || \ + ((CHANNEL) == ADC_Channel_7) || \ + ((CHANNEL) == ADC_Channel_8) || \ + ((CHANNEL) == ADC_Channel_9) || \ + ((CHANNEL) == ADC_Channel_10) || \ + ((CHANNEL) == ADC_Channel_11) || \ + ((CHANNEL) == ADC_Channel_12) || \ + ((CHANNEL) == ADC_Channel_13) || \ + ((CHANNEL) == ADC_Channel_14) || \ + ((CHANNEL) == ADC_Channel_15) || \ + ((CHANNEL) == ADC_Channel_16) || \ + ((CHANNEL) == ADC_Channel_17) || \ + ((CHANNEL) == ADC_Channel_18)) +/** + * @} + */ + + +/** @defgroup ADC_sampling_times + * @{ + */ +#define ADC_SampleTime_3Cycles ((uint8_t)0x00) +#define ADC_SampleTime_15Cycles ((uint8_t)0x01) +#define ADC_SampleTime_28Cycles ((uint8_t)0x02) +#define ADC_SampleTime_56Cycles ((uint8_t)0x03) +#define ADC_SampleTime_84Cycles ((uint8_t)0x04) +#define ADC_SampleTime_112Cycles ((uint8_t)0x05) +#define ADC_SampleTime_144Cycles ((uint8_t)0x06) +#define ADC_SampleTime_480Cycles ((uint8_t)0x07) +#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_3Cycles) || \ + ((TIME) == ADC_SampleTime_15Cycles) || \ + ((TIME) == ADC_SampleTime_28Cycles) || \ + ((TIME) == ADC_SampleTime_56Cycles) || \ + ((TIME) == ADC_SampleTime_84Cycles) || \ + ((TIME) == ADC_SampleTime_112Cycles) || \ + ((TIME) == ADC_SampleTime_144Cycles) || \ + ((TIME) == ADC_SampleTime_480Cycles)) +/** + * @} + */ + + +/** @defgroup ADC_external_trigger_edge_for_injected_channels_conversion + * @{ + */ +#define ADC_ExternalTrigInjecConvEdge_None ((uint32_t)0x00000000) +#define ADC_ExternalTrigInjecConvEdge_Rising ((uint32_t)0x00100000) +#define ADC_ExternalTrigInjecConvEdge_Falling ((uint32_t)0x00200000) +#define ADC_ExternalTrigInjecConvEdge_RisingFalling ((uint32_t)0x00300000) +#define IS_ADC_EXT_INJEC_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigInjecConvEdge_None) || \ + ((EDGE) == ADC_ExternalTrigInjecConvEdge_Rising) || \ + ((EDGE) == ADC_ExternalTrigInjecConvEdge_Falling) || \ + ((EDGE) == ADC_ExternalTrigInjecConvEdge_RisingFalling)) + +/** + * @} + */ + + +/** @defgroup ADC_extrenal_trigger_sources_for_injected_channels_conversion + * @{ + */ +#define ADC_ExternalTrigInjecConv_T1_CC4 ((uint32_t)0x00000000) +#define ADC_ExternalTrigInjecConv_T1_TRGO ((uint32_t)0x00010000) +#define ADC_ExternalTrigInjecConv_T2_CC1 ((uint32_t)0x00020000) +#define ADC_ExternalTrigInjecConv_T2_TRGO ((uint32_t)0x00030000) +#define ADC_ExternalTrigInjecConv_T3_CC2 ((uint32_t)0x00040000) +#define ADC_ExternalTrigInjecConv_T3_CC4 ((uint32_t)0x00050000) +#define ADC_ExternalTrigInjecConv_T4_CC1 ((uint32_t)0x00060000) +#define ADC_ExternalTrigInjecConv_T4_CC2 ((uint32_t)0x00070000) +#define ADC_ExternalTrigInjecConv_T4_CC3 ((uint32_t)0x00080000) +#define ADC_ExternalTrigInjecConv_T4_TRGO ((uint32_t)0x00090000) +#define ADC_ExternalTrigInjecConv_T5_CC4 ((uint32_t)0x000A0000) +#define ADC_ExternalTrigInjecConv_T5_TRGO ((uint32_t)0x000B0000) +#define ADC_ExternalTrigInjecConv_T8_CC2 ((uint32_t)0x000C0000) +#define ADC_ExternalTrigInjecConv_T8_CC3 ((uint32_t)0x000D0000) +#define ADC_ExternalTrigInjecConv_T8_CC4 ((uint32_t)0x000E0000) +#define ADC_ExternalTrigInjecConv_Ext_IT15 ((uint32_t)0x000F0000) +#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_ExternalTrigInjecConv_T1_CC4) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T1_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_CC1) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC2) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC4) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC1) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC2) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC3) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_CC4) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC2) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC3) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC4) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_Ext_IT15)) +/** + * @} + */ + + +/** @defgroup ADC_injected_channel_selection + * @{ + */ +#define ADC_InjectedChannel_1 ((uint8_t)0x14) +#define ADC_InjectedChannel_2 ((uint8_t)0x18) +#define ADC_InjectedChannel_3 ((uint8_t)0x1C) +#define ADC_InjectedChannel_4 ((uint8_t)0x20) +#define IS_ADC_INJECTED_CHANNEL(CHANNEL) (((CHANNEL) == ADC_InjectedChannel_1) || \ + ((CHANNEL) == ADC_InjectedChannel_2) || \ + ((CHANNEL) == ADC_InjectedChannel_3) || \ + ((CHANNEL) == ADC_InjectedChannel_4)) +/** + * @} + */ + + +/** @defgroup ADC_analog_watchdog_selection + * @{ + */ +#define ADC_AnalogWatchdog_SingleRegEnable ((uint32_t)0x00800200) +#define ADC_AnalogWatchdog_SingleInjecEnable ((uint32_t)0x00400200) +#define ADC_AnalogWatchdog_SingleRegOrInjecEnable ((uint32_t)0x00C00200) +#define ADC_AnalogWatchdog_AllRegEnable ((uint32_t)0x00800000) +#define ADC_AnalogWatchdog_AllInjecEnable ((uint32_t)0x00400000) +#define ADC_AnalogWatchdog_AllRegAllInjecEnable ((uint32_t)0x00C00000) +#define ADC_AnalogWatchdog_None ((uint32_t)0x00000000) +#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_AnalogWatchdog_SingleRegEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_SingleInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_SingleRegOrInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_AllRegEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_AllInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_AllRegAllInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_None)) +/** + * @} + */ + + +/** @defgroup ADC_interrupts_definition + * @{ + */ +#define ADC_IT_EOC ((uint16_t)0x0205) +#define ADC_IT_AWD ((uint16_t)0x0106) +#define ADC_IT_JEOC ((uint16_t)0x0407) +#define ADC_IT_OVR ((uint16_t)0x201A) +#define IS_ADC_IT(IT) (((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_AWD) || \ + ((IT) == ADC_IT_JEOC)|| ((IT) == ADC_IT_OVR)) +/** + * @} + */ + + +/** @defgroup ADC_flags_definition + * @{ + */ +#define ADC_FLAG_AWD ((uint8_t)0x01) +#define ADC_FLAG_EOC ((uint8_t)0x02) +#define ADC_FLAG_JEOC ((uint8_t)0x04) +#define ADC_FLAG_JSTRT ((uint8_t)0x08) +#define ADC_FLAG_STRT ((uint8_t)0x10) +#define ADC_FLAG_OVR ((uint8_t)0x20) + +#define IS_ADC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint8_t)0xC0) == 0x00) && ((FLAG) != 0x00)) +#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_AWD) || \ + ((FLAG) == ADC_FLAG_EOC) || \ + ((FLAG) == ADC_FLAG_JEOC) || \ + ((FLAG)== ADC_FLAG_JSTRT) || \ + ((FLAG) == ADC_FLAG_STRT) || \ + ((FLAG)== ADC_FLAG_OVR)) +/** + * @} + */ + + +/** @defgroup ADC_thresholds + * @{ + */ +#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF) +/** + * @} + */ + + +/** @defgroup ADC_injected_offset + * @{ + */ +#define IS_ADC_OFFSET(OFFSET) ((OFFSET) <= 0xFFF) +/** + * @} + */ + + +/** @defgroup ADC_injected_length + * @{ + */ +#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x4)) +/** + * @} + */ + + +/** @defgroup ADC_injected_rank + * @{ + */ +#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x4)) +/** + * @} + */ + + +/** @defgroup ADC_regular_length + * @{ + */ +#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x10)) +/** + * @} + */ + + +/** @defgroup ADC_regular_rank + * @{ + */ +#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x10)) +/** + * @} + */ + + +/** @defgroup ADC_regular_discontinuous_mode_number + * @{ + */ +#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 0x1) && ((NUMBER) <= 0x8)) +/** + * @} + */ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the ADC configuration to the default reset state *****/ +void ADC_DeInit(void); + +/* Initialization and Configuration functions *********************************/ +void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); +void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct); +void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct); +void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct); +void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); + +/* Analog Watchdog configuration functions ************************************/ +void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog); +void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,uint16_t LowThreshold); +void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel); + +/* Temperature Sensor, Vrefint and VBAT management functions ******************/ +void ADC_TempSensorVrefintCmd(FunctionalState NewState); +void ADC_VBATCmd(FunctionalState NewState); + +/* Regular Channels Configuration functions ***********************************/ +void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); +void ADC_SoftwareStartConv(ADC_TypeDef* ADCx); +FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx); +void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number); +void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); +uint32_t ADC_GetMultiModeConversionValue(void); + +/* Regular Channels DMA Configuration functions *******************************/ +void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_MultiModeDMARequestAfterLastTransferCmd(FunctionalState NewState); + +/* Injected channels Configuration functions **********************************/ +void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); +void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length); +void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset); +void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv); +void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge); +void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx); +FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx); +void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel); + +/* Interrupts and flags management functions **********************************/ +void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState); +FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG); +void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG); +ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT); +void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_ADC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_can.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_can.h new file mode 100644 index 0000000..900d50f --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_can.h @@ -0,0 +1,638 @@ +/** + ****************************************************************************** + * @file stm32f4xx_can.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the CAN firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_CAN_H +#define __STM32F4xx_CAN_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup CAN + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +#define IS_CAN_ALL_PERIPH(PERIPH) (((PERIPH) == CAN1) || \ + ((PERIPH) == CAN2)) + +/** + * @brief CAN init structure definition + */ +typedef struct +{ + uint16_t CAN_Prescaler; /*!< Specifies the length of a time quantum. + It ranges from 1 to 1024. */ + + uint8_t CAN_Mode; /*!< Specifies the CAN operating mode. + This parameter can be a value of @ref CAN_operating_mode */ + + uint8_t CAN_SJW; /*!< Specifies the maximum number of time quanta + the CAN hardware is allowed to lengthen or + shorten a bit to perform resynchronization. + This parameter can be a value of @ref CAN_synchronisation_jump_width */ + + uint8_t CAN_BS1; /*!< Specifies the number of time quanta in Bit + Segment 1. This parameter can be a value of + @ref CAN_time_quantum_in_bit_segment_1 */ + + uint8_t CAN_BS2; /*!< Specifies the number of time quanta in Bit Segment 2. + This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */ + + FunctionalState CAN_TTCM; /*!< Enable or disable the time triggered communication mode. + This parameter can be set either to ENABLE or DISABLE. */ + + FunctionalState CAN_ABOM; /*!< Enable or disable the automatic bus-off management. + This parameter can be set either to ENABLE or DISABLE. */ + + FunctionalState CAN_AWUM; /*!< Enable or disable the automatic wake-up mode. + This parameter can be set either to ENABLE or DISABLE. */ + + FunctionalState CAN_NART; /*!< Enable or disable the non-automatic retransmission mode. + This parameter can be set either to ENABLE or DISABLE. */ + + FunctionalState CAN_RFLM; /*!< Enable or disable the Receive FIFO Locked mode. + This parameter can be set either to ENABLE or DISABLE. */ + + FunctionalState CAN_TXFP; /*!< Enable or disable the transmit FIFO priority. + This parameter can be set either to ENABLE or DISABLE. */ +} CAN_InitTypeDef; + +/** + * @brief CAN filter init structure definition + */ +typedef struct +{ + uint16_t CAN_FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit + configuration, first one for a 16-bit configuration). + This parameter can be a value between 0x0000 and 0xFFFF */ + + uint16_t CAN_FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit + configuration, second one for a 16-bit configuration). + This parameter can be a value between 0x0000 and 0xFFFF */ + + uint16_t CAN_FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number, + according to the mode (MSBs for a 32-bit configuration, + first one for a 16-bit configuration). + This parameter can be a value between 0x0000 and 0xFFFF */ + + uint16_t CAN_FilterMaskIdLow; /*!< Specifies the filter mask number or identification number, + according to the mode (LSBs for a 32-bit configuration, + second one for a 16-bit configuration). + This parameter can be a value between 0x0000 and 0xFFFF */ + + uint16_t CAN_FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1) which will be assigned to the filter. + This parameter can be a value of @ref CAN_filter_FIFO */ + + uint8_t CAN_FilterNumber; /*!< Specifies the filter which will be initialized. It ranges from 0 to 13. */ + + uint8_t CAN_FilterMode; /*!< Specifies the filter mode to be initialized. + This parameter can be a value of @ref CAN_filter_mode */ + + uint8_t CAN_FilterScale; /*!< Specifies the filter scale. + This parameter can be a value of @ref CAN_filter_scale */ + + FunctionalState CAN_FilterActivation; /*!< Enable or disable the filter. + This parameter can be set either to ENABLE or DISABLE. */ +} CAN_FilterInitTypeDef; + +/** + * @brief CAN Tx message structure definition + */ +typedef struct +{ + uint32_t StdId; /*!< Specifies the standard identifier. + This parameter can be a value between 0 to 0x7FF. */ + + uint32_t ExtId; /*!< Specifies the extended identifier. + This parameter can be a value between 0 to 0x1FFFFFFF. */ + + uint8_t IDE; /*!< Specifies the type of identifier for the message that + will be transmitted. This parameter can be a value + of @ref CAN_identifier_type */ + + uint8_t RTR; /*!< Specifies the type of frame for the message that will + be transmitted. This parameter can be a value of + @ref CAN_remote_transmission_request */ + + uint8_t DLC; /*!< Specifies the length of the frame that will be + transmitted. This parameter can be a value between + 0 to 8 */ + + uint8_t Data[8]; /*!< Contains the data to be transmitted. It ranges from 0 + to 0xFF. */ +} CanTxMsg; + +/** + * @brief CAN Rx message structure definition + */ +typedef struct +{ + uint32_t StdId; /*!< Specifies the standard identifier. + This parameter can be a value between 0 to 0x7FF. */ + + uint32_t ExtId; /*!< Specifies the extended identifier. + This parameter can be a value between 0 to 0x1FFFFFFF. */ + + uint8_t IDE; /*!< Specifies the type of identifier for the message that + will be received. This parameter can be a value of + @ref CAN_identifier_type */ + + uint8_t RTR; /*!< Specifies the type of frame for the received message. + This parameter can be a value of + @ref CAN_remote_transmission_request */ + + uint8_t DLC; /*!< Specifies the length of the frame that will be received. + This parameter can be a value between 0 to 8 */ + + uint8_t Data[8]; /*!< Contains the data to be received. It ranges from 0 to + 0xFF. */ + + uint8_t FMI; /*!< Specifies the index of the filter the message stored in + the mailbox passes through. This parameter can be a + value between 0 to 0xFF */ +} CanRxMsg; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CAN_Exported_Constants + * @{ + */ + +/** @defgroup CAN_InitStatus + * @{ + */ + +#define CAN_InitStatus_Failed ((uint8_t)0x00) /*!< CAN initialization failed */ +#define CAN_InitStatus_Success ((uint8_t)0x01) /*!< CAN initialization OK */ + + +/* Legacy defines */ +#define CANINITFAILED CAN_InitStatus_Failed +#define CANINITOK CAN_InitStatus_Success +/** + * @} + */ + +/** @defgroup CAN_operating_mode + * @{ + */ + +#define CAN_Mode_Normal ((uint8_t)0x00) /*!< normal mode */ +#define CAN_Mode_LoopBack ((uint8_t)0x01) /*!< loopback mode */ +#define CAN_Mode_Silent ((uint8_t)0x02) /*!< silent mode */ +#define CAN_Mode_Silent_LoopBack ((uint8_t)0x03) /*!< loopback combined with silent mode */ + +#define IS_CAN_MODE(MODE) (((MODE) == CAN_Mode_Normal) || \ + ((MODE) == CAN_Mode_LoopBack)|| \ + ((MODE) == CAN_Mode_Silent) || \ + ((MODE) == CAN_Mode_Silent_LoopBack)) +/** + * @} + */ + + + /** + * @defgroup CAN_operating_mode + * @{ + */ +#define CAN_OperatingMode_Initialization ((uint8_t)0x00) /*!< Initialization mode */ +#define CAN_OperatingMode_Normal ((uint8_t)0x01) /*!< Normal mode */ +#define CAN_OperatingMode_Sleep ((uint8_t)0x02) /*!< sleep mode */ + + +#define IS_CAN_OPERATING_MODE(MODE) (((MODE) == CAN_OperatingMode_Initialization) ||\ + ((MODE) == CAN_OperatingMode_Normal)|| \ + ((MODE) == CAN_OperatingMode_Sleep)) +/** + * @} + */ + +/** + * @defgroup CAN_operating_mode_status + * @{ + */ + +#define CAN_ModeStatus_Failed ((uint8_t)0x00) /*!< CAN entering the specific mode failed */ +#define CAN_ModeStatus_Success ((uint8_t)!CAN_ModeStatus_Failed) /*!< CAN entering the specific mode Succeed */ +/** + * @} + */ + +/** @defgroup CAN_synchronisation_jump_width + * @{ + */ +#define CAN_SJW_1tq ((uint8_t)0x00) /*!< 1 time quantum */ +#define CAN_SJW_2tq ((uint8_t)0x01) /*!< 2 time quantum */ +#define CAN_SJW_3tq ((uint8_t)0x02) /*!< 3 time quantum */ +#define CAN_SJW_4tq ((uint8_t)0x03) /*!< 4 time quantum */ + +#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1tq) || ((SJW) == CAN_SJW_2tq)|| \ + ((SJW) == CAN_SJW_3tq) || ((SJW) == CAN_SJW_4tq)) +/** + * @} + */ + +/** @defgroup CAN_time_quantum_in_bit_segment_1 + * @{ + */ +#define CAN_BS1_1tq ((uint8_t)0x00) /*!< 1 time quantum */ +#define CAN_BS1_2tq ((uint8_t)0x01) /*!< 2 time quantum */ +#define CAN_BS1_3tq ((uint8_t)0x02) /*!< 3 time quantum */ +#define CAN_BS1_4tq ((uint8_t)0x03) /*!< 4 time quantum */ +#define CAN_BS1_5tq ((uint8_t)0x04) /*!< 5 time quantum */ +#define CAN_BS1_6tq ((uint8_t)0x05) /*!< 6 time quantum */ +#define CAN_BS1_7tq ((uint8_t)0x06) /*!< 7 time quantum */ +#define CAN_BS1_8tq ((uint8_t)0x07) /*!< 8 time quantum */ +#define CAN_BS1_9tq ((uint8_t)0x08) /*!< 9 time quantum */ +#define CAN_BS1_10tq ((uint8_t)0x09) /*!< 10 time quantum */ +#define CAN_BS1_11tq ((uint8_t)0x0A) /*!< 11 time quantum */ +#define CAN_BS1_12tq ((uint8_t)0x0B) /*!< 12 time quantum */ +#define CAN_BS1_13tq ((uint8_t)0x0C) /*!< 13 time quantum */ +#define CAN_BS1_14tq ((uint8_t)0x0D) /*!< 14 time quantum */ +#define CAN_BS1_15tq ((uint8_t)0x0E) /*!< 15 time quantum */ +#define CAN_BS1_16tq ((uint8_t)0x0F) /*!< 16 time quantum */ + +#define IS_CAN_BS1(BS1) ((BS1) <= CAN_BS1_16tq) +/** + * @} + */ + +/** @defgroup CAN_time_quantum_in_bit_segment_2 + * @{ + */ +#define CAN_BS2_1tq ((uint8_t)0x00) /*!< 1 time quantum */ +#define CAN_BS2_2tq ((uint8_t)0x01) /*!< 2 time quantum */ +#define CAN_BS2_3tq ((uint8_t)0x02) /*!< 3 time quantum */ +#define CAN_BS2_4tq ((uint8_t)0x03) /*!< 4 time quantum */ +#define CAN_BS2_5tq ((uint8_t)0x04) /*!< 5 time quantum */ +#define CAN_BS2_6tq ((uint8_t)0x05) /*!< 6 time quantum */ +#define CAN_BS2_7tq ((uint8_t)0x06) /*!< 7 time quantum */ +#define CAN_BS2_8tq ((uint8_t)0x07) /*!< 8 time quantum */ + +#define IS_CAN_BS2(BS2) ((BS2) <= CAN_BS2_8tq) +/** + * @} + */ + +/** @defgroup CAN_clock_prescaler + * @{ + */ +#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1) && ((PRESCALER) <= 1024)) +/** + * @} + */ + +/** @defgroup CAN_filter_number + * @{ + */ +#define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 27) +/** + * @} + */ + +/** @defgroup CAN_filter_mode + * @{ + */ +#define CAN_FilterMode_IdMask ((uint8_t)0x00) /*!< identifier/mask mode */ +#define CAN_FilterMode_IdList ((uint8_t)0x01) /*!< identifier list mode */ + +#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FilterMode_IdMask) || \ + ((MODE) == CAN_FilterMode_IdList)) +/** + * @} + */ + +/** @defgroup CAN_filter_scale + * @{ + */ +#define CAN_FilterScale_16bit ((uint8_t)0x00) /*!< Two 16-bit filters */ +#define CAN_FilterScale_32bit ((uint8_t)0x01) /*!< One 32-bit filter */ + +#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FilterScale_16bit) || \ + ((SCALE) == CAN_FilterScale_32bit)) +/** + * @} + */ + +/** @defgroup CAN_filter_FIFO + * @{ + */ +#define CAN_Filter_FIFO0 ((uint8_t)0x00) /*!< Filter FIFO 0 assignment for filter x */ +#define CAN_Filter_FIFO1 ((uint8_t)0x01) /*!< Filter FIFO 1 assignment for filter x */ +#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FilterFIFO0) || \ + ((FIFO) == CAN_FilterFIFO1)) + +/* Legacy defines */ +#define CAN_FilterFIFO0 CAN_Filter_FIFO0 +#define CAN_FilterFIFO1 CAN_Filter_FIFO1 +/** + * @} + */ + +/** @defgroup CAN_Start_bank_filter_for_slave_CAN + * @{ + */ +#define IS_CAN_BANKNUMBER(BANKNUMBER) (((BANKNUMBER) >= 1) && ((BANKNUMBER) <= 27)) +/** + * @} + */ + +/** @defgroup CAN_Tx + * @{ + */ +#define IS_CAN_TRANSMITMAILBOX(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= ((uint8_t)0x02)) +#define IS_CAN_STDID(STDID) ((STDID) <= ((uint32_t)0x7FF)) +#define IS_CAN_EXTID(EXTID) ((EXTID) <= ((uint32_t)0x1FFFFFFF)) +#define IS_CAN_DLC(DLC) ((DLC) <= ((uint8_t)0x08)) +/** + * @} + */ + +/** @defgroup CAN_identifier_type + * @{ + */ +#define CAN_Id_Standard ((uint32_t)0x00000000) /*!< Standard Id */ +#define CAN_Id_Extended ((uint32_t)0x00000004) /*!< Extended Id */ +#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_Id_Standard) || \ + ((IDTYPE) == CAN_Id_Extended)) + +/* Legacy defines */ +#define CAN_ID_STD CAN_Id_Standard +#define CAN_ID_EXT CAN_Id_Extended +/** + * @} + */ + +/** @defgroup CAN_remote_transmission_request + * @{ + */ +#define CAN_RTR_Data ((uint32_t)0x00000000) /*!< Data frame */ +#define CAN_RTR_Remote ((uint32_t)0x00000002) /*!< Remote frame */ +#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_Data) || ((RTR) == CAN_RTR_Remote)) + +/* Legacy defines */ +#define CAN_RTR_DATA CAN_RTR_Data +#define CAN_RTR_REMOTE CAN_RTR_Remote +/** + * @} + */ + +/** @defgroup CAN_transmit_constants + * @{ + */ +#define CAN_TxStatus_Failed ((uint8_t)0x00)/*!< CAN transmission failed */ +#define CAN_TxStatus_Ok ((uint8_t)0x01) /*!< CAN transmission succeeded */ +#define CAN_TxStatus_Pending ((uint8_t)0x02) /*!< CAN transmission pending */ +#define CAN_TxStatus_NoMailBox ((uint8_t)0x04) /*!< CAN cell did not provide + an empty mailbox */ +/* Legacy defines */ +#define CANTXFAILED CAN_TxStatus_Failed +#define CANTXOK CAN_TxStatus_Ok +#define CANTXPENDING CAN_TxStatus_Pending +#define CAN_NO_MB CAN_TxStatus_NoMailBox +/** + * @} + */ + +/** @defgroup CAN_receive_FIFO_number_constants + * @{ + */ +#define CAN_FIFO0 ((uint8_t)0x00) /*!< CAN FIFO 0 used to receive */ +#define CAN_FIFO1 ((uint8_t)0x01) /*!< CAN FIFO 1 used to receive */ + +#define IS_CAN_FIFO(FIFO) (((FIFO) == CAN_FIFO0) || ((FIFO) == CAN_FIFO1)) +/** + * @} + */ + +/** @defgroup CAN_sleep_constants + * @{ + */ +#define CAN_Sleep_Failed ((uint8_t)0x00) /*!< CAN did not enter the sleep mode */ +#define CAN_Sleep_Ok ((uint8_t)0x01) /*!< CAN entered the sleep mode */ + +/* Legacy defines */ +#define CANSLEEPFAILED CAN_Sleep_Failed +#define CANSLEEPOK CAN_Sleep_Ok +/** + * @} + */ + +/** @defgroup CAN_wake_up_constants + * @{ + */ +#define CAN_WakeUp_Failed ((uint8_t)0x00) /*!< CAN did not leave the sleep mode */ +#define CAN_WakeUp_Ok ((uint8_t)0x01) /*!< CAN leaved the sleep mode */ + +/* Legacy defines */ +#define CANWAKEUPFAILED CAN_WakeUp_Failed +#define CANWAKEUPOK CAN_WakeUp_Ok +/** + * @} + */ + +/** + * @defgroup CAN_Error_Code_constants + * @{ + */ +#define CAN_ErrorCode_NoErr ((uint8_t)0x00) /*!< No Error */ +#define CAN_ErrorCode_StuffErr ((uint8_t)0x10) /*!< Stuff Error */ +#define CAN_ErrorCode_FormErr ((uint8_t)0x20) /*!< Form Error */ +#define CAN_ErrorCode_ACKErr ((uint8_t)0x30) /*!< Acknowledgment Error */ +#define CAN_ErrorCode_BitRecessiveErr ((uint8_t)0x40) /*!< Bit Recessive Error */ +#define CAN_ErrorCode_BitDominantErr ((uint8_t)0x50) /*!< Bit Dominant Error */ +#define CAN_ErrorCode_CRCErr ((uint8_t)0x60) /*!< CRC Error */ +#define CAN_ErrorCode_SoftwareSetErr ((uint8_t)0x70) /*!< Software Set Error */ +/** + * @} + */ + +/** @defgroup CAN_flags + * @{ + */ +/* If the flag is 0x3XXXXXXX, it means that it can be used with CAN_GetFlagStatus() + and CAN_ClearFlag() functions. */ +/* If the flag is 0x1XXXXXXX, it means that it can only be used with + CAN_GetFlagStatus() function. */ + +/* Transmit Flags */ +#define CAN_FLAG_RQCP0 ((uint32_t)0x38000001) /*!< Request MailBox0 Flag */ +#define CAN_FLAG_RQCP1 ((uint32_t)0x38000100) /*!< Request MailBox1 Flag */ +#define CAN_FLAG_RQCP2 ((uint32_t)0x38010000) /*!< Request MailBox2 Flag */ + +/* Receive Flags */ +#define CAN_FLAG_FMP0 ((uint32_t)0x12000003) /*!< FIFO 0 Message Pending Flag */ +#define CAN_FLAG_FF0 ((uint32_t)0x32000008) /*!< FIFO 0 Full Flag */ +#define CAN_FLAG_FOV0 ((uint32_t)0x32000010) /*!< FIFO 0 Overrun Flag */ +#define CAN_FLAG_FMP1 ((uint32_t)0x14000003) /*!< FIFO 1 Message Pending Flag */ +#define CAN_FLAG_FF1 ((uint32_t)0x34000008) /*!< FIFO 1 Full Flag */ +#define CAN_FLAG_FOV1 ((uint32_t)0x34000010) /*!< FIFO 1 Overrun Flag */ + +/* Operating Mode Flags */ +#define CAN_FLAG_WKU ((uint32_t)0x31000008) /*!< Wake up Flag */ +#define CAN_FLAG_SLAK ((uint32_t)0x31000012) /*!< Sleep acknowledge Flag */ +/* @note When SLAK interrupt is disabled (SLKIE=0), no polling on SLAKI is possible. + In this case the SLAK bit can be polled.*/ + +/* Error Flags */ +#define CAN_FLAG_EWG ((uint32_t)0x10F00001) /*!< Error Warning Flag */ +#define CAN_FLAG_EPV ((uint32_t)0x10F00002) /*!< Error Passive Flag */ +#define CAN_FLAG_BOF ((uint32_t)0x10F00004) /*!< Bus-Off Flag */ +#define CAN_FLAG_LEC ((uint32_t)0x30F00070) /*!< Last error code Flag */ + +#define IS_CAN_GET_FLAG(FLAG) (((FLAG) == CAN_FLAG_LEC) || ((FLAG) == CAN_FLAG_BOF) || \ + ((FLAG) == CAN_FLAG_EPV) || ((FLAG) == CAN_FLAG_EWG) || \ + ((FLAG) == CAN_FLAG_WKU) || ((FLAG) == CAN_FLAG_FOV0) || \ + ((FLAG) == CAN_FLAG_FF0) || ((FLAG) == CAN_FLAG_FMP0) || \ + ((FLAG) == CAN_FLAG_FOV1) || ((FLAG) == CAN_FLAG_FF1) || \ + ((FLAG) == CAN_FLAG_FMP1) || ((FLAG) == CAN_FLAG_RQCP2) || \ + ((FLAG) == CAN_FLAG_RQCP1)|| ((FLAG) == CAN_FLAG_RQCP0) || \ + ((FLAG) == CAN_FLAG_SLAK )) + +#define IS_CAN_CLEAR_FLAG(FLAG)(((FLAG) == CAN_FLAG_LEC) || ((FLAG) == CAN_FLAG_RQCP2) || \ + ((FLAG) == CAN_FLAG_RQCP1) || ((FLAG) == CAN_FLAG_RQCP0) || \ + ((FLAG) == CAN_FLAG_FF0) || ((FLAG) == CAN_FLAG_FOV0) ||\ + ((FLAG) == CAN_FLAG_FF1) || ((FLAG) == CAN_FLAG_FOV1) || \ + ((FLAG) == CAN_FLAG_WKU) || ((FLAG) == CAN_FLAG_SLAK)) +/** + * @} + */ + + +/** @defgroup CAN_interrupts + * @{ + */ +#define CAN_IT_TME ((uint32_t)0x00000001) /*!< Transmit mailbox empty Interrupt*/ + +/* Receive Interrupts */ +#define CAN_IT_FMP0 ((uint32_t)0x00000002) /*!< FIFO 0 message pending Interrupt*/ +#define CAN_IT_FF0 ((uint32_t)0x00000004) /*!< FIFO 0 full Interrupt*/ +#define CAN_IT_FOV0 ((uint32_t)0x00000008) /*!< FIFO 0 overrun Interrupt*/ +#define CAN_IT_FMP1 ((uint32_t)0x00000010) /*!< FIFO 1 message pending Interrupt*/ +#define CAN_IT_FF1 ((uint32_t)0x00000020) /*!< FIFO 1 full Interrupt*/ +#define CAN_IT_FOV1 ((uint32_t)0x00000040) /*!< FIFO 1 overrun Interrupt*/ + +/* Operating Mode Interrupts */ +#define CAN_IT_WKU ((uint32_t)0x00010000) /*!< Wake-up Interrupt*/ +#define CAN_IT_SLK ((uint32_t)0x00020000) /*!< Sleep acknowledge Interrupt*/ + +/* Error Interrupts */ +#define CAN_IT_EWG ((uint32_t)0x00000100) /*!< Error warning Interrupt*/ +#define CAN_IT_EPV ((uint32_t)0x00000200) /*!< Error passive Interrupt*/ +#define CAN_IT_BOF ((uint32_t)0x00000400) /*!< Bus-off Interrupt*/ +#define CAN_IT_LEC ((uint32_t)0x00000800) /*!< Last error code Interrupt*/ +#define CAN_IT_ERR ((uint32_t)0x00008000) /*!< Error Interrupt*/ + +/* Flags named as Interrupts : kept only for FW compatibility */ +#define CAN_IT_RQCP0 CAN_IT_TME +#define CAN_IT_RQCP1 CAN_IT_TME +#define CAN_IT_RQCP2 CAN_IT_TME + + +#define IS_CAN_IT(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FMP0) ||\ + ((IT) == CAN_IT_FF0) || ((IT) == CAN_IT_FOV0) ||\ + ((IT) == CAN_IT_FMP1) || ((IT) == CAN_IT_FF1) ||\ + ((IT) == CAN_IT_FOV1) || ((IT) == CAN_IT_EWG) ||\ + ((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\ + ((IT) == CAN_IT_LEC) || ((IT) == CAN_IT_ERR) ||\ + ((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK)) + +#define IS_CAN_CLEAR_IT(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FF0) ||\ + ((IT) == CAN_IT_FOV0)|| ((IT) == CAN_IT_FF1) ||\ + ((IT) == CAN_IT_FOV1)|| ((IT) == CAN_IT_EWG) ||\ + ((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\ + ((IT) == CAN_IT_LEC) || ((IT) == CAN_IT_ERR) ||\ + ((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the CAN configuration to the default reset state *****/ +void CAN_DeInit(CAN_TypeDef* CANx); + +/* Initialization and Configuration functions *********************************/ +uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct); +void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct); +void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct); +void CAN_SlaveStartBank(uint8_t CAN_BankNumber); +void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState); +void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState); + +/* CAN Frames Transmission functions ******************************************/ +uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage); +uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox); +void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox); + +/* CAN Frames Reception functions *********************************************/ +void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage); +void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber); +uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber); + +/* Operation modes functions **************************************************/ +uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode); +uint8_t CAN_Sleep(CAN_TypeDef* CANx); +uint8_t CAN_WakeUp(CAN_TypeDef* CANx); + +/* CAN Bus Error management functions *****************************************/ +uint8_t CAN_GetLastErrorCode(CAN_TypeDef* CANx); +uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef* CANx); +uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef* CANx); + +/* Interrupts and flags management functions **********************************/ +void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState); +FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG); +void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG); +ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT); +void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_CAN_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_crc.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_crc.h new file mode 100644 index 0000000..9a8c79a --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_crc.h @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file stm32f4xx_crc.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the CRC firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_CRC_H +#define __STM32F4xx_CRC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup CRC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CRC_Exported_Constants + * @{ + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +void CRC_ResetDR(void); +uint32_t CRC_CalcCRC(uint32_t Data); +uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength); +uint32_t CRC_GetCRC(void); +void CRC_SetIDRegister(uint8_t IDValue); +uint8_t CRC_GetIDRegister(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_CRC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_cryp.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_cryp.h new file mode 100644 index 0000000..0b2572a --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_cryp.h @@ -0,0 +1,338 @@ +/** + ****************************************************************************** + * @file stm32f4xx_cryp.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the Cryptographic + * processor(CRYP) firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_CRYP_H +#define __STM32F4xx_CRYP_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup CRYP + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief CRYP Init structure definition + */ +typedef struct +{ + uint16_t CRYP_AlgoDir; /*!< Encrypt or Decrypt. This parameter can be a + value of @ref CRYP_Algorithm_Direction */ + uint16_t CRYP_AlgoMode; /*!< TDES-ECB, TDES-CBC, DES-ECB, DES-CBC, AES-ECB, + AES-CBC, AES-CTR, AES-Key. This parameter can be + a value of @ref CRYP_Algorithm_Mode */ + uint16_t CRYP_DataType; /*!< 32-bit data, 16-bit data, bit data or bit-string. + This parameter can be a value of @ref CRYP_Data_Type */ + uint16_t CRYP_KeySize; /*!< Used only in AES mode only : 128, 192 or 256 bit + key length. This parameter can be a value of + @ref CRYP_Key_Size_for_AES_only */ +}CRYP_InitTypeDef; + +/** + * @brief CRYP Key(s) structure definition + */ +typedef struct +{ + uint32_t CRYP_Key0Left; /*!< Key 0 Left */ + uint32_t CRYP_Key0Right; /*!< Key 0 Right */ + uint32_t CRYP_Key1Left; /*!< Key 1 left */ + uint32_t CRYP_Key1Right; /*!< Key 1 Right */ + uint32_t CRYP_Key2Left; /*!< Key 2 left */ + uint32_t CRYP_Key2Right; /*!< Key 2 Right */ + uint32_t CRYP_Key3Left; /*!< Key 3 left */ + uint32_t CRYP_Key3Right; /*!< Key 3 Right */ +}CRYP_KeyInitTypeDef; +/** + * @brief CRYP Initialization Vectors (IV) structure definition + */ +typedef struct +{ + uint32_t CRYP_IV0Left; /*!< Init Vector 0 Left */ + uint32_t CRYP_IV0Right; /*!< Init Vector 0 Right */ + uint32_t CRYP_IV1Left; /*!< Init Vector 1 left */ + uint32_t CRYP_IV1Right; /*!< Init Vector 1 Right */ +}CRYP_IVInitTypeDef; + +/** + * @brief CRYP context swapping structure definition + */ +typedef struct +{ + /*!< Configuration */ + uint32_t CR_bits9to2; + /*!< KEY */ + uint32_t CRYP_IV0LR; + uint32_t CRYP_IV0RR; + uint32_t CRYP_IV1LR; + uint32_t CRYP_IV1RR; + /*!< IV */ + uint32_t CRYP_K0LR; + uint32_t CRYP_K0RR; + uint32_t CRYP_K1LR; + uint32_t CRYP_K1RR; + uint32_t CRYP_K2LR; + uint32_t CRYP_K2RR; + uint32_t CRYP_K3LR; + uint32_t CRYP_K3RR; +}CRYP_Context; + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CRYP_Exported_Constants + * @{ + */ + +/** @defgroup CRYP_Algorithm_Direction + * @{ + */ +#define CRYP_AlgoDir_Encrypt ((uint16_t)0x0000) +#define CRYP_AlgoDir_Decrypt ((uint16_t)0x0004) +#define IS_CRYP_ALGODIR(ALGODIR) (((ALGODIR) == CRYP_AlgoDir_Encrypt) || \ + ((ALGODIR) == CRYP_AlgoDir_Decrypt)) + +/** + * @} + */ + +/** @defgroup CRYP_Algorithm_Mode + * @{ + */ + +/*!< TDES Modes */ +#define CRYP_AlgoMode_TDES_ECB ((uint16_t)0x0000) +#define CRYP_AlgoMode_TDES_CBC ((uint16_t)0x0008) + +/*!< DES Modes */ +#define CRYP_AlgoMode_DES_ECB ((uint16_t)0x0010) +#define CRYP_AlgoMode_DES_CBC ((uint16_t)0x0018) + +/*!< AES Modes */ +#define CRYP_AlgoMode_AES_ECB ((uint16_t)0x0020) +#define CRYP_AlgoMode_AES_CBC ((uint16_t)0x0028) +#define CRYP_AlgoMode_AES_CTR ((uint16_t)0x0030) +#define CRYP_AlgoMode_AES_Key ((uint16_t)0x0038) + +#define IS_CRYP_ALGOMODE(ALGOMODE) (((ALGOMODE) == CRYP_AlgoMode_TDES_ECB) || \ + ((ALGOMODE) == CRYP_AlgoMode_TDES_CBC)|| \ + ((ALGOMODE) == CRYP_AlgoMode_DES_ECB)|| \ + ((ALGOMODE) == CRYP_AlgoMode_DES_CBC) || \ + ((ALGOMODE) == CRYP_AlgoMode_AES_ECB) || \ + ((ALGOMODE) == CRYP_AlgoMode_AES_CBC) || \ + ((ALGOMODE) == CRYP_AlgoMode_AES_CTR) || \ + ((ALGOMODE) == CRYP_AlgoMode_AES_Key)) +/** + * @} + */ + +/** @defgroup CRYP_Data_Type + * @{ + */ +#define CRYP_DataType_32b ((uint16_t)0x0000) +#define CRYP_DataType_16b ((uint16_t)0x0040) +#define CRYP_DataType_8b ((uint16_t)0x0080) +#define CRYP_DataType_1b ((uint16_t)0x00C0) +#define IS_CRYP_DATATYPE(DATATYPE) (((DATATYPE) == CRYP_DataType_32b) || \ + ((DATATYPE) == CRYP_DataType_16b)|| \ + ((DATATYPE) == CRYP_DataType_8b)|| \ + ((DATATYPE) == CRYP_DataType_1b)) +/** + * @} + */ + +/** @defgroup CRYP_Key_Size_for_AES_only + * @{ + */ +#define CRYP_KeySize_128b ((uint16_t)0x0000) +#define CRYP_KeySize_192b ((uint16_t)0x0100) +#define CRYP_KeySize_256b ((uint16_t)0x0200) +#define IS_CRYP_KEYSIZE(KEYSIZE) (((KEYSIZE) == CRYP_KeySize_128b)|| \ + ((KEYSIZE) == CRYP_KeySize_192b)|| \ + ((KEYSIZE) == CRYP_KeySize_256b)) +/** + * @} + */ + +/** @defgroup CRYP_flags_definition + * @{ + */ +#define CRYP_FLAG_BUSY ((uint8_t)0x10) /*!< The CRYP core is currently + processing a block of data + or a key preparation (for + AES decryption). */ +#define CRYP_FLAG_IFEM ((uint8_t)0x01) /*!< Input Fifo Empty */ +#define CRYP_FLAG_IFNF ((uint8_t)0x02) /*!< Input Fifo is Not Full */ +#define CRYP_FLAG_INRIS ((uint8_t)0x22) /*!< Raw interrupt pending */ +#define CRYP_FLAG_OFNE ((uint8_t)0x04) /*!< Input Fifo service raw + interrupt status */ +#define CRYP_FLAG_OFFU ((uint8_t)0x08) /*!< Output Fifo is Full */ +#define CRYP_FLAG_OUTRIS ((uint8_t)0x21) /*!< Output Fifo service raw + interrupt status */ + +#define IS_CRYP_GET_FLAG(FLAG) (((FLAG) == CRYP_FLAG_IFEM) || \ + ((FLAG) == CRYP_FLAG_IFNF) || \ + ((FLAG) == CRYP_FLAG_OFNE) || \ + ((FLAG) == CRYP_FLAG_OFFU) || \ + ((FLAG) == CRYP_FLAG_BUSY) || \ + ((FLAG) == CRYP_FLAG_OUTRIS)|| \ + ((FLAG) == CRYP_FLAG_INRIS)) +/** + * @} + */ + +/** @defgroup CRYP_interrupts_definition + * @{ + */ +#define CRYP_IT_INI ((uint8_t)0x01) /*!< IN Fifo Interrupt */ +#define CRYP_IT_OUTI ((uint8_t)0x02) /*!< OUT Fifo Interrupt */ +#define IS_CRYP_CONFIG_IT(IT) ((((IT) & (uint8_t)0xFC) == 0x00) && ((IT) != 0x00)) +#define IS_CRYP_GET_IT(IT) (((IT) == CRYP_IT_INI) || ((IT) == CRYP_IT_OUTI)) + +/** + * @} + */ + +/** @defgroup CRYP_Encryption_Decryption_modes_definition + * @{ + */ +#define MODE_ENCRYPT ((uint8_t)0x01) +#define MODE_DECRYPT ((uint8_t)0x00) + +/** + * @} + */ + +/** @defgroup CRYP_DMA_transfer_requests + * @{ + */ +#define CRYP_DMAReq_DataIN ((uint8_t)0x01) +#define CRYP_DMAReq_DataOUT ((uint8_t)0x02) +#define IS_CRYP_DMAREQ(DMAREQ) ((((DMAREQ) & (uint8_t)0xFC) == 0x00) && ((DMAREQ) != 0x00)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the CRYP configuration to the default reset state ****/ +void CRYP_DeInit(void); + +/* CRYP Initialization and Configuration functions ****************************/ +void CRYP_Init(CRYP_InitTypeDef* CRYP_InitStruct); +void CRYP_StructInit(CRYP_InitTypeDef* CRYP_InitStruct); +void CRYP_KeyInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct); +void CRYP_KeyStructInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct); +void CRYP_IVInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct); +void CRYP_IVStructInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct); +void CRYP_Cmd(FunctionalState NewState); + +/* CRYP Data processing functions *********************************************/ +void CRYP_DataIn(uint32_t Data); +uint32_t CRYP_DataOut(void); +void CRYP_FIFOFlush(void); + +/* CRYP Context swapping functions ********************************************/ +ErrorStatus CRYP_SaveContext(CRYP_Context* CRYP_ContextSave, + CRYP_KeyInitTypeDef* CRYP_KeyInitStruct); +void CRYP_RestoreContext(CRYP_Context* CRYP_ContextRestore); + +/* CRYP's DMA interface function **********************************************/ +void CRYP_DMACmd(uint8_t CRYP_DMAReq, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void CRYP_ITConfig(uint8_t CRYP_IT, FunctionalState NewState); +ITStatus CRYP_GetITStatus(uint8_t CRYP_IT); +FlagStatus CRYP_GetFlagStatus(uint8_t CRYP_FLAG); + +/* High Level AES functions **************************************************/ +ErrorStatus CRYP_AES_ECB(uint8_t Mode, + uint8_t *Key, uint16_t Keysize, + uint8_t *Input, uint32_t Ilength, + uint8_t *Output); + +ErrorStatus CRYP_AES_CBC(uint8_t Mode, + uint8_t InitVectors[16], + uint8_t *Key, uint16_t Keysize, + uint8_t *Input, uint32_t Ilength, + uint8_t *Output); + +ErrorStatus CRYP_AES_CTR(uint8_t Mode, + uint8_t InitVectors[16], + uint8_t *Key, uint16_t Keysize, + uint8_t *Input, uint32_t Ilength, + uint8_t *Output); + +/* High Level TDES functions **************************************************/ +ErrorStatus CRYP_TDES_ECB(uint8_t Mode, + uint8_t Key[24], + uint8_t *Input, uint32_t Ilength, + uint8_t *Output); + +ErrorStatus CRYP_TDES_CBC(uint8_t Mode, + uint8_t Key[24], + uint8_t InitVectors[8], + uint8_t *Input, uint32_t Ilength, + uint8_t *Output); + +/* High Level DES functions **************************************************/ +ErrorStatus CRYP_DES_ECB(uint8_t Mode, + uint8_t Key[8], + uint8_t *Input, uint32_t Ilength, + uint8_t *Output); + +ErrorStatus CRYP_DES_CBC(uint8_t Mode, + uint8_t Key[8], + uint8_t InitVectors[8], + uint8_t *Input,uint32_t Ilength, + uint8_t *Output); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_CRYP_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dac.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dac.h new file mode 100644 index 0000000..8d92818 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dac.h @@ -0,0 +1,298 @@ +/** + ****************************************************************************** + * @file stm32f4xx_dac.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the DAC firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_DAC_H +#define __STM32F4xx_DAC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup DAC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief DAC Init structure definition + */ + +typedef struct +{ + uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel. + This parameter can be a value of @ref DAC_trigger_selection */ + + uint32_t DAC_WaveGeneration; /*!< Specifies whether DAC channel noise waves or triangle waves + are generated, or whether no wave is generated. + This parameter can be a value of @ref DAC_wave_generation */ + + uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< Specifies the LFSR mask for noise wave generation or + the maximum amplitude triangle generation for the DAC channel. + This parameter can be a value of @ref DAC_lfsrunmask_triangleamplitude */ + + uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled. + This parameter can be a value of @ref DAC_output_buffer */ +}DAC_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DAC_Exported_Constants + * @{ + */ + +/** @defgroup DAC_trigger_selection + * @{ + */ + +#define DAC_Trigger_None ((uint32_t)0x00000000) /*!< Conversion is automatic once the DAC1_DHRxxxx register + has been loaded, and not by external trigger */ +#define DAC_Trigger_T2_TRGO ((uint32_t)0x00000024) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T4_TRGO ((uint32_t)0x0000002C) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T5_TRGO ((uint32_t)0x0000001C) /*!< TIM5 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T6_TRGO ((uint32_t)0x00000004) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T7_TRGO ((uint32_t)0x00000014) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T8_TRGO ((uint32_t)0x0000000C) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel */ + +#define DAC_Trigger_Ext_IT9 ((uint32_t)0x00000034) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_Software ((uint32_t)0x0000003C) /*!< Conversion started by software trigger for DAC channel */ + +#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_Trigger_None) || \ + ((TRIGGER) == DAC_Trigger_T6_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T8_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T7_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T5_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T2_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T4_TRGO) || \ + ((TRIGGER) == DAC_Trigger_Ext_IT9) || \ + ((TRIGGER) == DAC_Trigger_Software)) + +/** + * @} + */ + +/** @defgroup DAC_wave_generation + * @{ + */ + +#define DAC_WaveGeneration_None ((uint32_t)0x00000000) +#define DAC_WaveGeneration_Noise ((uint32_t)0x00000040) +#define DAC_WaveGeneration_Triangle ((uint32_t)0x00000080) +#define IS_DAC_GENERATE_WAVE(WAVE) (((WAVE) == DAC_WaveGeneration_None) || \ + ((WAVE) == DAC_WaveGeneration_Noise) || \ + ((WAVE) == DAC_WaveGeneration_Triangle)) +/** + * @} + */ + +/** @defgroup DAC_lfsrunmask_triangleamplitude + * @{ + */ + +#define DAC_LFSRUnmask_Bit0 ((uint32_t)0x00000000) /*!< Unmask DAC channel LFSR bit0 for noise wave generation */ +#define DAC_LFSRUnmask_Bits1_0 ((uint32_t)0x00000100) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits2_0 ((uint32_t)0x00000200) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits3_0 ((uint32_t)0x00000300) /*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits4_0 ((uint32_t)0x00000400) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits5_0 ((uint32_t)0x00000500) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits6_0 ((uint32_t)0x00000600) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits7_0 ((uint32_t)0x00000700) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits8_0 ((uint32_t)0x00000800) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits9_0 ((uint32_t)0x00000900) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits10_0 ((uint32_t)0x00000A00) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits11_0 ((uint32_t)0x00000B00) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */ +#define DAC_TriangleAmplitude_1 ((uint32_t)0x00000000) /*!< Select max triangle amplitude of 1 */ +#define DAC_TriangleAmplitude_3 ((uint32_t)0x00000100) /*!< Select max triangle amplitude of 3 */ +#define DAC_TriangleAmplitude_7 ((uint32_t)0x00000200) /*!< Select max triangle amplitude of 7 */ +#define DAC_TriangleAmplitude_15 ((uint32_t)0x00000300) /*!< Select max triangle amplitude of 15 */ +#define DAC_TriangleAmplitude_31 ((uint32_t)0x00000400) /*!< Select max triangle amplitude of 31 */ +#define DAC_TriangleAmplitude_63 ((uint32_t)0x00000500) /*!< Select max triangle amplitude of 63 */ +#define DAC_TriangleAmplitude_127 ((uint32_t)0x00000600) /*!< Select max triangle amplitude of 127 */ +#define DAC_TriangleAmplitude_255 ((uint32_t)0x00000700) /*!< Select max triangle amplitude of 255 */ +#define DAC_TriangleAmplitude_511 ((uint32_t)0x00000800) /*!< Select max triangle amplitude of 511 */ +#define DAC_TriangleAmplitude_1023 ((uint32_t)0x00000900) /*!< Select max triangle amplitude of 1023 */ +#define DAC_TriangleAmplitude_2047 ((uint32_t)0x00000A00) /*!< Select max triangle amplitude of 2047 */ +#define DAC_TriangleAmplitude_4095 ((uint32_t)0x00000B00) /*!< Select max triangle amplitude of 4095 */ + +#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUnmask_Bit0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits1_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits2_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits3_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits4_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits5_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits6_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits7_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits8_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits9_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits10_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits11_0) || \ + ((VALUE) == DAC_TriangleAmplitude_1) || \ + ((VALUE) == DAC_TriangleAmplitude_3) || \ + ((VALUE) == DAC_TriangleAmplitude_7) || \ + ((VALUE) == DAC_TriangleAmplitude_15) || \ + ((VALUE) == DAC_TriangleAmplitude_31) || \ + ((VALUE) == DAC_TriangleAmplitude_63) || \ + ((VALUE) == DAC_TriangleAmplitude_127) || \ + ((VALUE) == DAC_TriangleAmplitude_255) || \ + ((VALUE) == DAC_TriangleAmplitude_511) || \ + ((VALUE) == DAC_TriangleAmplitude_1023) || \ + ((VALUE) == DAC_TriangleAmplitude_2047) || \ + ((VALUE) == DAC_TriangleAmplitude_4095)) +/** + * @} + */ + +/** @defgroup DAC_output_buffer + * @{ + */ + +#define DAC_OutputBuffer_Enable ((uint32_t)0x00000000) +#define DAC_OutputBuffer_Disable ((uint32_t)0x00000002) +#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OutputBuffer_Enable) || \ + ((STATE) == DAC_OutputBuffer_Disable)) +/** + * @} + */ + +/** @defgroup DAC_Channel_selection + * @{ + */ + +#define DAC_Channel_1 ((uint32_t)0x00000000) +#define DAC_Channel_2 ((uint32_t)0x00000010) +#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_Channel_1) || \ + ((CHANNEL) == DAC_Channel_2)) +/** + * @} + */ + +/** @defgroup DAC_data_alignement + * @{ + */ + +#define DAC_Align_12b_R ((uint32_t)0x00000000) +#define DAC_Align_12b_L ((uint32_t)0x00000004) +#define DAC_Align_8b_R ((uint32_t)0x00000008) +#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_Align_12b_R) || \ + ((ALIGN) == DAC_Align_12b_L) || \ + ((ALIGN) == DAC_Align_8b_R)) +/** + * @} + */ + +/** @defgroup DAC_wave_generation + * @{ + */ + +#define DAC_Wave_Noise ((uint32_t)0x00000040) +#define DAC_Wave_Triangle ((uint32_t)0x00000080) +#define IS_DAC_WAVE(WAVE) (((WAVE) == DAC_Wave_Noise) || \ + ((WAVE) == DAC_Wave_Triangle)) +/** + * @} + */ + +/** @defgroup DAC_data + * @{ + */ + +#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0) +/** + * @} + */ + +/** @defgroup DAC_interrupts_definition + * @{ + */ +#define DAC_IT_DMAUDR ((uint32_t)0x00002000) +#define IS_DAC_IT(IT) (((IT) == DAC_IT_DMAUDR)) + +/** + * @} + */ + +/** @defgroup DAC_flags_definition + * @{ + */ + +#define DAC_FLAG_DMAUDR ((uint32_t)0x00002000) +#define IS_DAC_FLAG(FLAG) (((FLAG) == DAC_FLAG_DMAUDR)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the DAC configuration to the default reset state *****/ +void DAC_DeInit(void); + +/* DAC channels configuration: trigger, output buffer, data format functions */ +void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct); +void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct); +void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState); +void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState); +void DAC_DualSoftwareTriggerCmd(FunctionalState NewState); +void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState); +void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data); +void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data); +void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1); +uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel); + +/* DMA management functions ***************************************************/ +void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState); +FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG); +void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG); +ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT); +void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_DAC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h new file mode 100644 index 0000000..da91337 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * @file stm32f4xx_dbgmcu.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the DBGMCU firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_DBGMCU_H +#define __STM32F4xx_DBGMCU_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup DBGMCU + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DBGMCU_Exported_Constants + * @{ + */ +#define DBGMCU_SLEEP ((uint32_t)0x00000001) +#define DBGMCU_STOP ((uint32_t)0x00000002) +#define DBGMCU_STANDBY ((uint32_t)0x00000004) +#define IS_DBGMCU_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFF8) == 0x00) && ((PERIPH) != 0x00)) + +#define DBGMCU_TIM2_STOP ((uint32_t)0x00000001) +#define DBGMCU_TIM3_STOP ((uint32_t)0x00000002) +#define DBGMCU_TIM4_STOP ((uint32_t)0x00000004) +#define DBGMCU_TIM5_STOP ((uint32_t)0x00000008) +#define DBGMCU_TIM6_STOP ((uint32_t)0x00000010) +#define DBGMCU_TIM7_STOP ((uint32_t)0x00000020) +#define DBGMCU_TIM12_STOP ((uint32_t)0x00000040) +#define DBGMCU_TIM13_STOP ((uint32_t)0x00000080) +#define DBGMCU_TIM14_STOP ((uint32_t)0x00000100) +#define DBGMCU_RTC_STOP ((uint32_t)0x00000400) +#define DBGMCU_WWDG_STOP ((uint32_t)0x00000800) +#define DBGMCU_IWDG_STOP ((uint32_t)0x00001000) +#define DBGMCU_I2C1_SMBUS_TIMEOUT ((uint32_t)0x00200000) +#define DBGMCU_I2C2_SMBUS_TIMEOUT ((uint32_t)0x00400000) +#define DBGMCU_I2C3_SMBUS_TIMEOUT ((uint32_t)0x00800000) +#define DBGMCU_CAN1_STOP ((uint32_t)0x02000000) +#define DBGMCU_CAN2_STOP ((uint32_t)0x04000000) +#define IS_DBGMCU_APB1PERIPH(PERIPH) ((((PERIPH) & 0xF91FE200) == 0x00) && ((PERIPH) != 0x00)) + +#define DBGMCU_TIM1_STOP ((uint32_t)0x00000001) +#define DBGMCU_TIM8_STOP ((uint32_t)0x00000002) +#define DBGMCU_TIM9_STOP ((uint32_t)0x00010000) +#define DBGMCU_TIM10_STOP ((uint32_t)0x00020000) +#define DBGMCU_TIM11_STOP ((uint32_t)0x00040000) +#define IS_DBGMCU_APB2PERIPH(PERIPH) ((((PERIPH) & 0xFFF8FFFC) == 0x00) && ((PERIPH) != 0x00)) +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +uint32_t DBGMCU_GetREVID(void); +uint32_t DBGMCU_GetDEVID(void); +void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState); +void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); +void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_DBGMCU_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dcmi.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dcmi.h new file mode 100644 index 0000000..c2631d6 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dcmi.h @@ -0,0 +1,306 @@ +/** + ****************************************************************************** + * @file stm32f4xx_dcmi.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the DCMI firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_DCMI_H +#define __STM32F4xx_DCMI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup DCMI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief DCMI Init structure definition + */ +typedef struct +{ + uint16_t DCMI_CaptureMode; /*!< Specifies the Capture Mode: Continuous or Snapshot. + This parameter can be a value of @ref DCMI_Capture_Mode */ + + uint16_t DCMI_SynchroMode; /*!< Specifies the Synchronization Mode: Hardware or Embedded. + This parameter can be a value of @ref DCMI_Synchronization_Mode */ + + uint16_t DCMI_PCKPolarity; /*!< Specifies the Pixel clock polarity: Falling or Rising. + This parameter can be a value of @ref DCMI_PIXCK_Polarity */ + + uint16_t DCMI_VSPolarity; /*!< Specifies the Vertical synchronization polarity: High or Low. + This parameter can be a value of @ref DCMI_VSYNC_Polarity */ + + uint16_t DCMI_HSPolarity; /*!< Specifies the Horizontal synchronization polarity: High or Low. + This parameter can be a value of @ref DCMI_HSYNC_Polarity */ + + uint16_t DCMI_CaptureRate; /*!< Specifies the frequency of frame capture: All, 1/2 or 1/4. + This parameter can be a value of @ref DCMI_Capture_Rate */ + + uint16_t DCMI_ExtendedDataMode; /*!< Specifies the data width: 8-bit, 10-bit, 12-bit or 14-bit. + This parameter can be a value of @ref DCMI_Extended_Data_Mode */ +} DCMI_InitTypeDef; + +/** + * @brief DCMI CROP Init structure definition + */ +typedef struct +{ + uint16_t DCMI_VerticalStartLine; /*!< Specifies the Vertical start line count from which the image capture + will start. This parameter can be a value between 0x00 and 0x1FFF */ + + uint16_t DCMI_HorizontalOffsetCount; /*!< Specifies the number of pixel clocks to count before starting a capture. + This parameter can be a value between 0x00 and 0x3FFF */ + + uint16_t DCMI_VerticalLineCount; /*!< Specifies the number of lines to be captured from the starting point. + This parameter can be a value between 0x00 and 0x3FFF */ + + uint16_t DCMI_CaptureCount; /*!< Specifies the number of pixel clocks to be captured from the starting + point on the same line. + This parameter can be a value between 0x00 and 0x3FFF */ +} DCMI_CROPInitTypeDef; + +/** + * @brief DCMI Embedded Synchronisation CODE Init structure definition + */ +typedef struct +{ + uint8_t DCMI_FrameStartCode; /*!< Specifies the code of the frame start delimiter. */ + uint8_t DCMI_LineStartCode; /*!< Specifies the code of the line start delimiter. */ + uint8_t DCMI_LineEndCode; /*!< Specifies the code of the line end delimiter. */ + uint8_t DCMI_FrameEndCode; /*!< Specifies the code of the frame end delimiter. */ +} DCMI_CodesInitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DCMI_Exported_Constants + * @{ + */ + +/** @defgroup DCMI_Capture_Mode + * @{ + */ +#define DCMI_CaptureMode_Continuous ((uint16_t)0x0000) /*!< The received data are transferred continuously + into the destination memory through the DMA */ +#define DCMI_CaptureMode_SnapShot ((uint16_t)0x0002) /*!< Once activated, the interface waits for the start of + frame and then transfers a single frame through the DMA */ +#define IS_DCMI_CAPTURE_MODE(MODE)(((MODE) == DCMI_CaptureMode_Continuous) || \ + ((MODE) == DCMI_CaptureMode_SnapShot)) +/** + * @} + */ + + +/** @defgroup DCMI_Synchronization_Mode + * @{ + */ +#define DCMI_SynchroMode_Hardware ((uint16_t)0x0000) /*!< Hardware synchronization data capture (frame/line start/stop) + is synchronized with the HSYNC/VSYNC signals */ +#define DCMI_SynchroMode_Embedded ((uint16_t)0x0010) /*!< Embedded synchronization data capture is synchronized with + synchronization codes embedded in the data flow */ +#define IS_DCMI_SYNCHRO(MODE)(((MODE) == DCMI_SynchroMode_Hardware) || \ + ((MODE) == DCMI_SynchroMode_Embedded)) +/** + * @} + */ + + +/** @defgroup DCMI_PIXCK_Polarity + * @{ + */ +#define DCMI_PCKPolarity_Falling ((uint16_t)0x0000) /*!< Pixel clock active on Falling edge */ +#define DCMI_PCKPolarity_Rising ((uint16_t)0x0020) /*!< Pixel clock active on Rising edge */ +#define IS_DCMI_PCKPOLARITY(POLARITY)(((POLARITY) == DCMI_PCKPolarity_Falling) || \ + ((POLARITY) == DCMI_PCKPolarity_Rising)) +/** + * @} + */ + + +/** @defgroup DCMI_VSYNC_Polarity + * @{ + */ +#define DCMI_VSPolarity_Low ((uint16_t)0x0000) /*!< Vertical synchronization active Low */ +#define DCMI_VSPolarity_High ((uint16_t)0x0080) /*!< Vertical synchronization active High */ +#define IS_DCMI_VSPOLARITY(POLARITY)(((POLARITY) == DCMI_VSPolarity_Low) || \ + ((POLARITY) == DCMI_VSPolarity_High)) +/** + * @} + */ + + +/** @defgroup DCMI_HSYNC_Polarity + * @{ + */ +#define DCMI_HSPolarity_Low ((uint16_t)0x0000) /*!< Horizontal synchronization active Low */ +#define DCMI_HSPolarity_High ((uint16_t)0x0040) /*!< Horizontal synchronization active High */ +#define IS_DCMI_HSPOLARITY(POLARITY)(((POLARITY) == DCMI_HSPolarity_Low) || \ + ((POLARITY) == DCMI_HSPolarity_High)) +/** + * @} + */ + + +/** @defgroup DCMI_Capture_Rate + * @{ + */ +#define DCMI_CaptureRate_All_Frame ((uint16_t)0x0000) /*!< All frames are captured */ +#define DCMI_CaptureRate_1of2_Frame ((uint16_t)0x0100) /*!< Every alternate frame captured */ +#define DCMI_CaptureRate_1of4_Frame ((uint16_t)0x0200) /*!< One frame in 4 frames captured */ +#define IS_DCMI_CAPTURE_RATE(RATE) (((RATE) == DCMI_CaptureRate_All_Frame) || \ + ((RATE) == DCMI_CaptureRate_1of2_Frame) ||\ + ((RATE) == DCMI_CaptureRate_1of4_Frame)) +/** + * @} + */ + + +/** @defgroup DCMI_Extended_Data_Mode + * @{ + */ +#define DCMI_ExtendedDataMode_8b ((uint16_t)0x0000) /*!< Interface captures 8-bit data on every pixel clock */ +#define DCMI_ExtendedDataMode_10b ((uint16_t)0x0400) /*!< Interface captures 10-bit data on every pixel clock */ +#define DCMI_ExtendedDataMode_12b ((uint16_t)0x0800) /*!< Interface captures 12-bit data on every pixel clock */ +#define DCMI_ExtendedDataMode_14b ((uint16_t)0x0C00) /*!< Interface captures 14-bit data on every pixel clock */ +#define IS_DCMI_EXTENDED_DATA(DATA)(((DATA) == DCMI_ExtendedDataMode_8b) || \ + ((DATA) == DCMI_ExtendedDataMode_10b) ||\ + ((DATA) == DCMI_ExtendedDataMode_12b) ||\ + ((DATA) == DCMI_ExtendedDataMode_14b)) +/** + * @} + */ + + +/** @defgroup DCMI_interrupt_sources + * @{ + */ +#define DCMI_IT_FRAME ((uint16_t)0x0001) +#define DCMI_IT_OVF ((uint16_t)0x0002) +#define DCMI_IT_ERR ((uint16_t)0x0004) +#define DCMI_IT_VSYNC ((uint16_t)0x0008) +#define DCMI_IT_LINE ((uint16_t)0x0010) +#define IS_DCMI_CONFIG_IT(IT) ((((IT) & (uint16_t)0xFFE0) == 0x0000) && ((IT) != 0x0000)) +#define IS_DCMI_GET_IT(IT) (((IT) == DCMI_IT_FRAME) || \ + ((IT) == DCMI_IT_OVF) || \ + ((IT) == DCMI_IT_ERR) || \ + ((IT) == DCMI_IT_VSYNC) || \ + ((IT) == DCMI_IT_LINE)) +/** + * @} + */ + + +/** @defgroup DCMI_Flags + * @{ + */ +/** + * @brief DCMI SR register + */ +#define DCMI_FLAG_HSYNC ((uint16_t)0x2001) +#define DCMI_FLAG_VSYNC ((uint16_t)0x2002) +#define DCMI_FLAG_FNE ((uint16_t)0x2004) +/** + * @brief DCMI RISR register + */ +#define DCMI_FLAG_FRAMERI ((uint16_t)0x0001) +#define DCMI_FLAG_OVFRI ((uint16_t)0x0002) +#define DCMI_FLAG_ERRRI ((uint16_t)0x0004) +#define DCMI_FLAG_VSYNCRI ((uint16_t)0x0008) +#define DCMI_FLAG_LINERI ((uint16_t)0x0010) +/** + * @brief DCMI MISR register + */ +#define DCMI_FLAG_FRAMEMI ((uint16_t)0x1001) +#define DCMI_FLAG_OVFMI ((uint16_t)0x1002) +#define DCMI_FLAG_ERRMI ((uint16_t)0x1004) +#define DCMI_FLAG_VSYNCMI ((uint16_t)0x1008) +#define DCMI_FLAG_LINEMI ((uint16_t)0x1010) +#define IS_DCMI_GET_FLAG(FLAG) (((FLAG) == DCMI_FLAG_HSYNC) || \ + ((FLAG) == DCMI_FLAG_VSYNC) || \ + ((FLAG) == DCMI_FLAG_FNE) || \ + ((FLAG) == DCMI_FLAG_FRAMERI) || \ + ((FLAG) == DCMI_FLAG_OVFRI) || \ + ((FLAG) == DCMI_FLAG_ERRRI) || \ + ((FLAG) == DCMI_FLAG_VSYNCRI) || \ + ((FLAG) == DCMI_FLAG_LINERI) || \ + ((FLAG) == DCMI_FLAG_FRAMEMI) || \ + ((FLAG) == DCMI_FLAG_OVFMI) || \ + ((FLAG) == DCMI_FLAG_ERRMI) || \ + ((FLAG) == DCMI_FLAG_VSYNCMI) || \ + ((FLAG) == DCMI_FLAG_LINEMI)) + +#define IS_DCMI_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFFE0) == 0x0000) && ((FLAG) != 0x0000)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the DCMI configuration to the default reset state ****/ +void DCMI_DeInit(void); + +/* Initialization and Configuration functions *********************************/ +void DCMI_Init(DCMI_InitTypeDef* DCMI_InitStruct); +void DCMI_StructInit(DCMI_InitTypeDef* DCMI_InitStruct); +void DCMI_CROPConfig(DCMI_CROPInitTypeDef* DCMI_CROPInitStruct); +void DCMI_CROPCmd(FunctionalState NewState); +void DCMI_SetEmbeddedSynchroCodes(DCMI_CodesInitTypeDef* DCMI_CodesInitStruct); +void DCMI_JPEGCmd(FunctionalState NewState); + +/* Image capture functions ****************************************************/ +void DCMI_Cmd(FunctionalState NewState); +void DCMI_CaptureCmd(FunctionalState NewState); +uint32_t DCMI_ReadData(void); + +/* Interrupts and flags management functions **********************************/ +void DCMI_ITConfig(uint16_t DCMI_IT, FunctionalState NewState); +FlagStatus DCMI_GetFlagStatus(uint16_t DCMI_FLAG); +void DCMI_ClearFlag(uint16_t DCMI_FLAG); +ITStatus DCMI_GetITStatus(uint16_t DCMI_IT); +void DCMI_ClearITPendingBit(uint16_t DCMI_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_DCMI_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma.h new file mode 100644 index 0000000..a081e3d --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma.h @@ -0,0 +1,603 @@ +/** + ****************************************************************************** + * @file stm32f4xx_dma.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the DMA firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_DMA_H +#define __STM32F4xx_DMA_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup DMA + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief DMA Init structure definition + */ + +typedef struct +{ + uint32_t DMA_Channel; /*!< Specifies the channel used for the specified stream. + This parameter can be a value of @ref DMA_channel */ + + uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Streamx. */ + + uint32_t DMA_Memory0BaseAddr; /*!< Specifies the memory 0 base address for DMAy Streamx. + This memory is the default memory used when double buffer mode is + not enabled. */ + + uint32_t DMA_DIR; /*!< Specifies if the data will be transferred from memory to peripheral, + from memory to memory or from peripheral to memory. + This parameter can be a value of @ref DMA_data_transfer_direction */ + + uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Stream. + The data unit is equal to the configuration set in DMA_PeripheralDataSize + or DMA_MemoryDataSize members depending in the transfer direction. */ + + uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register should be incremented or not. + This parameter can be a value of @ref DMA_peripheral_incremented_mode */ + + uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register should be incremented or not. + This parameter can be a value of @ref DMA_memory_incremented_mode */ + + uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width. + This parameter can be a value of @ref DMA_peripheral_data_size */ + + uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width. + This parameter can be a value of @ref DMA_memory_data_size */ + + uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Streamx. + This parameter can be a value of @ref DMA_circular_normal_mode + @note The circular buffer mode cannot be used if the memory-to-memory + data transfer is configured on the selected Stream */ + + uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Streamx. + This parameter can be a value of @ref DMA_priority_level */ + + uint32_t DMA_FIFOMode; /*!< Specifies if the FIFO mode or Direct mode will be used for the specified Stream. + This parameter can be a value of @ref DMA_fifo_direct_mode + @note The Direct mode (FIFO mode disabled) cannot be used if the + memory-to-memory data transfer is configured on the selected Stream */ + + uint32_t DMA_FIFOThreshold; /*!< Specifies the FIFO threshold level. + This parameter can be a value of @ref DMA_fifo_threshold_level */ + + uint32_t DMA_MemoryBurst; /*!< Specifies the Burst transfer configuration for the memory transfers. + It specifies the amount of data to be transferred in a single non interruptable + transaction. This parameter can be a value of @ref DMA_memory_burst + @note The burst mode is possible only if the address Increment mode is enabled. */ + + uint32_t DMA_PeripheralBurst; /*!< Specifies the Burst transfer configuration for the peripheral transfers. + It specifies the amount of data to be transferred in a single non interruptable + transaction. This parameter can be a value of @ref DMA_peripheral_burst + @note The burst mode is possible only if the address Increment mode is enabled. */ +}DMA_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DMA_Exported_Constants + * @{ + */ + +#define IS_DMA_ALL_PERIPH(PERIPH) (((PERIPH) == DMA1_Stream0) || \ + ((PERIPH) == DMA1_Stream1) || \ + ((PERIPH) == DMA1_Stream2) || \ + ((PERIPH) == DMA1_Stream3) || \ + ((PERIPH) == DMA1_Stream4) || \ + ((PERIPH) == DMA1_Stream5) || \ + ((PERIPH) == DMA1_Stream6) || \ + ((PERIPH) == DMA1_Stream7) || \ + ((PERIPH) == DMA2_Stream0) || \ + ((PERIPH) == DMA2_Stream1) || \ + ((PERIPH) == DMA2_Stream2) || \ + ((PERIPH) == DMA2_Stream3) || \ + ((PERIPH) == DMA2_Stream4) || \ + ((PERIPH) == DMA2_Stream5) || \ + ((PERIPH) == DMA2_Stream6) || \ + ((PERIPH) == DMA2_Stream7)) + +#define IS_DMA_ALL_CONTROLLER(CONTROLLER) (((CONTROLLER) == DMA1) || \ + ((CONTROLLER) == DMA2)) + +/** @defgroup DMA_channel + * @{ + */ +#define DMA_Channel_0 ((uint32_t)0x00000000) +#define DMA_Channel_1 ((uint32_t)0x02000000) +#define DMA_Channel_2 ((uint32_t)0x04000000) +#define DMA_Channel_3 ((uint32_t)0x06000000) +#define DMA_Channel_4 ((uint32_t)0x08000000) +#define DMA_Channel_5 ((uint32_t)0x0A000000) +#define DMA_Channel_6 ((uint32_t)0x0C000000) +#define DMA_Channel_7 ((uint32_t)0x0E000000) + +#define IS_DMA_CHANNEL(CHANNEL) (((CHANNEL) == DMA_Channel_0) || \ + ((CHANNEL) == DMA_Channel_1) || \ + ((CHANNEL) == DMA_Channel_2) || \ + ((CHANNEL) == DMA_Channel_3) || \ + ((CHANNEL) == DMA_Channel_4) || \ + ((CHANNEL) == DMA_Channel_5) || \ + ((CHANNEL) == DMA_Channel_6) || \ + ((CHANNEL) == DMA_Channel_7)) +/** + * @} + */ + + +/** @defgroup DMA_data_transfer_direction + * @{ + */ +#define DMA_DIR_PeripheralToMemory ((uint32_t)0x00000000) +#define DMA_DIR_MemoryToPeripheral ((uint32_t)0x00000040) +#define DMA_DIR_MemoryToMemory ((uint32_t)0x00000080) + +#define IS_DMA_DIRECTION(DIRECTION) (((DIRECTION) == DMA_DIR_PeripheralToMemory ) || \ + ((DIRECTION) == DMA_DIR_MemoryToPeripheral) || \ + ((DIRECTION) == DMA_DIR_MemoryToMemory)) +/** + * @} + */ + + +/** @defgroup DMA_data_buffer_size + * @{ + */ +#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1) && ((SIZE) < 0x10000)) +/** + * @} + */ + + +/** @defgroup DMA_peripheral_incremented_mode + * @{ + */ +#define DMA_PeripheralInc_Enable ((uint32_t)0x00000200) +#define DMA_PeripheralInc_Disable ((uint32_t)0x00000000) + +#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PeripheralInc_Enable) || \ + ((STATE) == DMA_PeripheralInc_Disable)) +/** + * @} + */ + + +/** @defgroup DMA_memory_incremented_mode + * @{ + */ +#define DMA_MemoryInc_Enable ((uint32_t)0x00000400) +#define DMA_MemoryInc_Disable ((uint32_t)0x00000000) + +#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MemoryInc_Enable) || \ + ((STATE) == DMA_MemoryInc_Disable)) +/** + * @} + */ + + +/** @defgroup DMA_peripheral_data_size + * @{ + */ +#define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000) +#define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000800) +#define DMA_PeripheralDataSize_Word ((uint32_t)0x00001000) + +#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PeripheralDataSize_Byte) || \ + ((SIZE) == DMA_PeripheralDataSize_HalfWord) || \ + ((SIZE) == DMA_PeripheralDataSize_Word)) +/** + * @} + */ + + +/** @defgroup DMA_memory_data_size + * @{ + */ +#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000) +#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00002000) +#define DMA_MemoryDataSize_Word ((uint32_t)0x00004000) + +#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MemoryDataSize_Byte) || \ + ((SIZE) == DMA_MemoryDataSize_HalfWord) || \ + ((SIZE) == DMA_MemoryDataSize_Word )) +/** + * @} + */ + + +/** @defgroup DMA_circular_normal_mode + * @{ + */ +#define DMA_Mode_Normal ((uint32_t)0x00000000) +#define DMA_Mode_Circular ((uint32_t)0x00000100) + +#define IS_DMA_MODE(MODE) (((MODE) == DMA_Mode_Normal ) || \ + ((MODE) == DMA_Mode_Circular)) +/** + * @} + */ + + +/** @defgroup DMA_priority_level + * @{ + */ +#define DMA_Priority_Low ((uint32_t)0x00000000) +#define DMA_Priority_Medium ((uint32_t)0x00010000) +#define DMA_Priority_High ((uint32_t)0x00020000) +#define DMA_Priority_VeryHigh ((uint32_t)0x00030000) + +#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_Priority_Low ) || \ + ((PRIORITY) == DMA_Priority_Medium) || \ + ((PRIORITY) == DMA_Priority_High) || \ + ((PRIORITY) == DMA_Priority_VeryHigh)) +/** + * @} + */ + + +/** @defgroup DMA_fifo_direct_mode + * @{ + */ +#define DMA_FIFOMode_Disable ((uint32_t)0x00000000) +#define DMA_FIFOMode_Enable ((uint32_t)0x00000004) + +#define IS_DMA_FIFO_MODE_STATE(STATE) (((STATE) == DMA_FIFOMode_Disable ) || \ + ((STATE) == DMA_FIFOMode_Enable)) +/** + * @} + */ + + +/** @defgroup DMA_fifo_threshold_level + * @{ + */ +#define DMA_FIFOThreshold_1QuarterFull ((uint32_t)0x00000000) +#define DMA_FIFOThreshold_HalfFull ((uint32_t)0x00000001) +#define DMA_FIFOThreshold_3QuartersFull ((uint32_t)0x00000002) +#define DMA_FIFOThreshold_Full ((uint32_t)0x00000003) + +#define IS_DMA_FIFO_THRESHOLD(THRESHOLD) (((THRESHOLD) == DMA_FIFOThreshold_1QuarterFull ) || \ + ((THRESHOLD) == DMA_FIFOThreshold_HalfFull) || \ + ((THRESHOLD) == DMA_FIFOThreshold_3QuartersFull) || \ + ((THRESHOLD) == DMA_FIFOThreshold_Full)) +/** + * @} + */ + + +/** @defgroup DMA_memory_burst + * @{ + */ +#define DMA_MemoryBurst_Single ((uint32_t)0x00000000) +#define DMA_MemoryBurst_INC4 ((uint32_t)0x00800000) +#define DMA_MemoryBurst_INC8 ((uint32_t)0x01000000) +#define DMA_MemoryBurst_INC16 ((uint32_t)0x01800000) + +#define IS_DMA_MEMORY_BURST(BURST) (((BURST) == DMA_MemoryBurst_Single) || \ + ((BURST) == DMA_MemoryBurst_INC4) || \ + ((BURST) == DMA_MemoryBurst_INC8) || \ + ((BURST) == DMA_MemoryBurst_INC16)) +/** + * @} + */ + + +/** @defgroup DMA_peripheral_burst + * @{ + */ +#define DMA_PeripheralBurst_Single ((uint32_t)0x00000000) +#define DMA_PeripheralBurst_INC4 ((uint32_t)0x00200000) +#define DMA_PeripheralBurst_INC8 ((uint32_t)0x00400000) +#define DMA_PeripheralBurst_INC16 ((uint32_t)0x00600000) + +#define IS_DMA_PERIPHERAL_BURST(BURST) (((BURST) == DMA_PeripheralBurst_Single) || \ + ((BURST) == DMA_PeripheralBurst_INC4) || \ + ((BURST) == DMA_PeripheralBurst_INC8) || \ + ((BURST) == DMA_PeripheralBurst_INC16)) +/** + * @} + */ + + +/** @defgroup DMA_fifo_status_level + * @{ + */ +#define DMA_FIFOStatus_Less1QuarterFull ((uint32_t)0x00000000 << 3) +#define DMA_FIFOStatus_1QuarterFull ((uint32_t)0x00000001 << 3) +#define DMA_FIFOStatus_HalfFull ((uint32_t)0x00000002 << 3) +#define DMA_FIFOStatus_3QuartersFull ((uint32_t)0x00000003 << 3) +#define DMA_FIFOStatus_Empty ((uint32_t)0x00000004 << 3) +#define DMA_FIFOStatus_Full ((uint32_t)0x00000005 << 3) + +#define IS_DMA_FIFO_STATUS(STATUS) (((STATUS) == DMA_FIFOStatus_Less1QuarterFull ) || \ + ((STATUS) == DMA_FIFOStatus_HalfFull) || \ + ((STATUS) == DMA_FIFOStatus_1QuarterFull) || \ + ((STATUS) == DMA_FIFOStatus_3QuartersFull) || \ + ((STATUS) == DMA_FIFOStatus_Full) || \ + ((STATUS) == DMA_FIFOStatus_Empty)) +/** + * @} + */ + +/** @defgroup DMA_flags_definition + * @{ + */ +#define DMA_FLAG_FEIF0 ((uint32_t)0x10800001) +#define DMA_FLAG_DMEIF0 ((uint32_t)0x10800004) +#define DMA_FLAG_TEIF0 ((uint32_t)0x10000008) +#define DMA_FLAG_HTIF0 ((uint32_t)0x10000010) +#define DMA_FLAG_TCIF0 ((uint32_t)0x10000020) +#define DMA_FLAG_FEIF1 ((uint32_t)0x10000040) +#define DMA_FLAG_DMEIF1 ((uint32_t)0x10000100) +#define DMA_FLAG_TEIF1 ((uint32_t)0x10000200) +#define DMA_FLAG_HTIF1 ((uint32_t)0x10000400) +#define DMA_FLAG_TCIF1 ((uint32_t)0x10000800) +#define DMA_FLAG_FEIF2 ((uint32_t)0x10010000) +#define DMA_FLAG_DMEIF2 ((uint32_t)0x10040000) +#define DMA_FLAG_TEIF2 ((uint32_t)0x10080000) +#define DMA_FLAG_HTIF2 ((uint32_t)0x10100000) +#define DMA_FLAG_TCIF2 ((uint32_t)0x10200000) +#define DMA_FLAG_FEIF3 ((uint32_t)0x10400000) +#define DMA_FLAG_DMEIF3 ((uint32_t)0x11000000) +#define DMA_FLAG_TEIF3 ((uint32_t)0x12000000) +#define DMA_FLAG_HTIF3 ((uint32_t)0x14000000) +#define DMA_FLAG_TCIF3 ((uint32_t)0x18000000) +#define DMA_FLAG_FEIF4 ((uint32_t)0x20000001) +#define DMA_FLAG_DMEIF4 ((uint32_t)0x20000004) +#define DMA_FLAG_TEIF4 ((uint32_t)0x20000008) +#define DMA_FLAG_HTIF4 ((uint32_t)0x20000010) +#define DMA_FLAG_TCIF4 ((uint32_t)0x20000020) +#define DMA_FLAG_FEIF5 ((uint32_t)0x20000040) +#define DMA_FLAG_DMEIF5 ((uint32_t)0x20000100) +#define DMA_FLAG_TEIF5 ((uint32_t)0x20000200) +#define DMA_FLAG_HTIF5 ((uint32_t)0x20000400) +#define DMA_FLAG_TCIF5 ((uint32_t)0x20000800) +#define DMA_FLAG_FEIF6 ((uint32_t)0x20010000) +#define DMA_FLAG_DMEIF6 ((uint32_t)0x20040000) +#define DMA_FLAG_TEIF6 ((uint32_t)0x20080000) +#define DMA_FLAG_HTIF6 ((uint32_t)0x20100000) +#define DMA_FLAG_TCIF6 ((uint32_t)0x20200000) +#define DMA_FLAG_FEIF7 ((uint32_t)0x20400000) +#define DMA_FLAG_DMEIF7 ((uint32_t)0x21000000) +#define DMA_FLAG_TEIF7 ((uint32_t)0x22000000) +#define DMA_FLAG_HTIF7 ((uint32_t)0x24000000) +#define DMA_FLAG_TCIF7 ((uint32_t)0x28000000) + +#define IS_DMA_CLEAR_FLAG(FLAG) ((((FLAG) & 0x30000000) != 0x30000000) && (((FLAG) & 0x30000000) != 0) && \ + (((FLAG) & 0xC082F082) == 0x00) && ((FLAG) != 0x00)) + +#define IS_DMA_GET_FLAG(FLAG) (((FLAG) == DMA_FLAG_TCIF0) || ((FLAG) == DMA_FLAG_HTIF0) || \ + ((FLAG) == DMA_FLAG_TEIF0) || ((FLAG) == DMA_FLAG_DMEIF0) || \ + ((FLAG) == DMA_FLAG_FEIF0) || ((FLAG) == DMA_FLAG_TCIF1) || \ + ((FLAG) == DMA_FLAG_HTIF1) || ((FLAG) == DMA_FLAG_TEIF1) || \ + ((FLAG) == DMA_FLAG_DMEIF1) || ((FLAG) == DMA_FLAG_FEIF1) || \ + ((FLAG) == DMA_FLAG_TCIF2) || ((FLAG) == DMA_FLAG_HTIF2) || \ + ((FLAG) == DMA_FLAG_TEIF2) || ((FLAG) == DMA_FLAG_DMEIF2) || \ + ((FLAG) == DMA_FLAG_FEIF2) || ((FLAG) == DMA_FLAG_TCIF3) || \ + ((FLAG) == DMA_FLAG_HTIF3) || ((FLAG) == DMA_FLAG_TEIF3) || \ + ((FLAG) == DMA_FLAG_DMEIF3) || ((FLAG) == DMA_FLAG_FEIF3) || \ + ((FLAG) == DMA_FLAG_TCIF4) || ((FLAG) == DMA_FLAG_HTIF4) || \ + ((FLAG) == DMA_FLAG_TEIF4) || ((FLAG) == DMA_FLAG_DMEIF4) || \ + ((FLAG) == DMA_FLAG_FEIF4) || ((FLAG) == DMA_FLAG_TCIF5) || \ + ((FLAG) == DMA_FLAG_HTIF5) || ((FLAG) == DMA_FLAG_TEIF5) || \ + ((FLAG) == DMA_FLAG_DMEIF5) || ((FLAG) == DMA_FLAG_FEIF5) || \ + ((FLAG) == DMA_FLAG_TCIF6) || ((FLAG) == DMA_FLAG_HTIF6) || \ + ((FLAG) == DMA_FLAG_TEIF6) || ((FLAG) == DMA_FLAG_DMEIF6) || \ + ((FLAG) == DMA_FLAG_FEIF6) || ((FLAG) == DMA_FLAG_TCIF7) || \ + ((FLAG) == DMA_FLAG_HTIF7) || ((FLAG) == DMA_FLAG_TEIF7) || \ + ((FLAG) == DMA_FLAG_DMEIF7) || ((FLAG) == DMA_FLAG_FEIF7)) +/** + * @} + */ + + +/** @defgroup DMA_interrupt_enable_definitions + * @{ + */ +#define DMA_IT_TC ((uint32_t)0x00000010) +#define DMA_IT_HT ((uint32_t)0x00000008) +#define DMA_IT_TE ((uint32_t)0x00000004) +#define DMA_IT_DME ((uint32_t)0x00000002) +#define DMA_IT_FE ((uint32_t)0x00000080) + +#define IS_DMA_CONFIG_IT(IT) ((((IT) & 0xFFFFFF61) == 0x00) && ((IT) != 0x00)) +/** + * @} + */ + + +/** @defgroup DMA_interrupts_definitions + * @{ + */ +#define DMA_IT_FEIF0 ((uint32_t)0x90000001) +#define DMA_IT_DMEIF0 ((uint32_t)0x10001004) +#define DMA_IT_TEIF0 ((uint32_t)0x10002008) +#define DMA_IT_HTIF0 ((uint32_t)0x10004010) +#define DMA_IT_TCIF0 ((uint32_t)0x10008020) +#define DMA_IT_FEIF1 ((uint32_t)0x90000040) +#define DMA_IT_DMEIF1 ((uint32_t)0x10001100) +#define DMA_IT_TEIF1 ((uint32_t)0x10002200) +#define DMA_IT_HTIF1 ((uint32_t)0x10004400) +#define DMA_IT_TCIF1 ((uint32_t)0x10008800) +#define DMA_IT_FEIF2 ((uint32_t)0x90010000) +#define DMA_IT_DMEIF2 ((uint32_t)0x10041000) +#define DMA_IT_TEIF2 ((uint32_t)0x10082000) +#define DMA_IT_HTIF2 ((uint32_t)0x10104000) +#define DMA_IT_TCIF2 ((uint32_t)0x10208000) +#define DMA_IT_FEIF3 ((uint32_t)0x90400000) +#define DMA_IT_DMEIF3 ((uint32_t)0x11001000) +#define DMA_IT_TEIF3 ((uint32_t)0x12002000) +#define DMA_IT_HTIF3 ((uint32_t)0x14004000) +#define DMA_IT_TCIF3 ((uint32_t)0x18008000) +#define DMA_IT_FEIF4 ((uint32_t)0xA0000001) +#define DMA_IT_DMEIF4 ((uint32_t)0x20001004) +#define DMA_IT_TEIF4 ((uint32_t)0x20002008) +#define DMA_IT_HTIF4 ((uint32_t)0x20004010) +#define DMA_IT_TCIF4 ((uint32_t)0x20008020) +#define DMA_IT_FEIF5 ((uint32_t)0xA0000040) +#define DMA_IT_DMEIF5 ((uint32_t)0x20001100) +#define DMA_IT_TEIF5 ((uint32_t)0x20002200) +#define DMA_IT_HTIF5 ((uint32_t)0x20004400) +#define DMA_IT_TCIF5 ((uint32_t)0x20008800) +#define DMA_IT_FEIF6 ((uint32_t)0xA0010000) +#define DMA_IT_DMEIF6 ((uint32_t)0x20041000) +#define DMA_IT_TEIF6 ((uint32_t)0x20082000) +#define DMA_IT_HTIF6 ((uint32_t)0x20104000) +#define DMA_IT_TCIF6 ((uint32_t)0x20208000) +#define DMA_IT_FEIF7 ((uint32_t)0xA0400000) +#define DMA_IT_DMEIF7 ((uint32_t)0x21001000) +#define DMA_IT_TEIF7 ((uint32_t)0x22002000) +#define DMA_IT_HTIF7 ((uint32_t)0x24004000) +#define DMA_IT_TCIF7 ((uint32_t)0x28008000) + +#define IS_DMA_CLEAR_IT(IT) ((((IT) & 0x30000000) != 0x30000000) && \ + (((IT) & 0x30000000) != 0) && ((IT) != 0x00) && \ + (((IT) & 0x40820082) == 0x00)) + +#define IS_DMA_GET_IT(IT) (((IT) == DMA_IT_TCIF0) || ((IT) == DMA_IT_HTIF0) || \ + ((IT) == DMA_IT_TEIF0) || ((IT) == DMA_IT_DMEIF0) || \ + ((IT) == DMA_IT_FEIF0) || ((IT) == DMA_IT_TCIF1) || \ + ((IT) == DMA_IT_HTIF1) || ((IT) == DMA_IT_TEIF1) || \ + ((IT) == DMA_IT_DMEIF1)|| ((IT) == DMA_IT_FEIF1) || \ + ((IT) == DMA_IT_TCIF2) || ((IT) == DMA_IT_HTIF2) || \ + ((IT) == DMA_IT_TEIF2) || ((IT) == DMA_IT_DMEIF2) || \ + ((IT) == DMA_IT_FEIF2) || ((IT) == DMA_IT_TCIF3) || \ + ((IT) == DMA_IT_HTIF3) || ((IT) == DMA_IT_TEIF3) || \ + ((IT) == DMA_IT_DMEIF3)|| ((IT) == DMA_IT_FEIF3) || \ + ((IT) == DMA_IT_TCIF4) || ((IT) == DMA_IT_HTIF4) || \ + ((IT) == DMA_IT_TEIF4) || ((IT) == DMA_IT_DMEIF4) || \ + ((IT) == DMA_IT_FEIF4) || ((IT) == DMA_IT_TCIF5) || \ + ((IT) == DMA_IT_HTIF5) || ((IT) == DMA_IT_TEIF5) || \ + ((IT) == DMA_IT_DMEIF5)|| ((IT) == DMA_IT_FEIF5) || \ + ((IT) == DMA_IT_TCIF6) || ((IT) == DMA_IT_HTIF6) || \ + ((IT) == DMA_IT_TEIF6) || ((IT) == DMA_IT_DMEIF6) || \ + ((IT) == DMA_IT_FEIF6) || ((IT) == DMA_IT_TCIF7) || \ + ((IT) == DMA_IT_HTIF7) || ((IT) == DMA_IT_TEIF7) || \ + ((IT) == DMA_IT_DMEIF7)|| ((IT) == DMA_IT_FEIF7)) +/** + * @} + */ + + +/** @defgroup DMA_peripheral_increment_offset + * @{ + */ +#define DMA_PINCOS_Psize ((uint32_t)0x00000000) +#define DMA_PINCOS_WordAligned ((uint32_t)0x00008000) + +#define IS_DMA_PINCOS_SIZE(SIZE) (((SIZE) == DMA_PINCOS_Psize) || \ + ((SIZE) == DMA_PINCOS_WordAligned)) +/** + * @} + */ + + +/** @defgroup DMA_flow_controller_definitions + * @{ + */ +#define DMA_FlowCtrl_Memory ((uint32_t)0x00000000) +#define DMA_FlowCtrl_Peripheral ((uint32_t)0x00000020) + +#define IS_DMA_FLOW_CTRL(CTRL) (((CTRL) == DMA_FlowCtrl_Memory) || \ + ((CTRL) == DMA_FlowCtrl_Peripheral)) +/** + * @} + */ + + +/** @defgroup DMA_memory_targets_definitions + * @{ + */ +#define DMA_Memory_0 ((uint32_t)0x00000000) +#define DMA_Memory_1 ((uint32_t)0x00080000) + +#define IS_DMA_CURRENT_MEM(MEM) (((MEM) == DMA_Memory_0) || ((MEM) == DMA_Memory_1)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the DMA configuration to the default reset state *****/ +void DMA_DeInit(DMA_Stream_TypeDef* DMAy_Streamx); + +/* Initialization and Configuration functions *********************************/ +void DMA_Init(DMA_Stream_TypeDef* DMAy_Streamx, DMA_InitTypeDef* DMA_InitStruct); +void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct); +void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState); + +/* Optional Configuration functions *******************************************/ +void DMA_PeriphIncOffsetSizeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_Pincos); +void DMA_FlowControllerConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FlowCtrl); + +/* Data Counter functions *****************************************************/ +void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter); +uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx); + +/* Double Buffer mode functions ***********************************************/ +void DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t Memory1BaseAddr, + uint32_t DMA_CurrentMemory); +void DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState); +void DMA_MemoryTargetConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t MemoryBaseAddr, + uint32_t DMA_MemoryTarget); +uint32_t DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx); + +/* Interrupts and flags management functions **********************************/ +FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx); +uint32_t DMA_GetFIFOStatus(DMA_Stream_TypeDef* DMAy_Streamx); +FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG); +void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG); +void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState); +ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT); +void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_DMA_H */ + +/** + * @} + */ + +/** + * @} + */ + + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_exti.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_exti.h new file mode 100644 index 0000000..e25f152 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_exti.h @@ -0,0 +1,177 @@ +/** + ****************************************************************************** + * @file stm32f4xx_exti.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the EXTI firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_EXTI_H +#define __STM32F4xx_EXTI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup EXTI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief EXTI mode enumeration + */ + +typedef enum +{ + EXTI_Mode_Interrupt = 0x00, + EXTI_Mode_Event = 0x04 +}EXTIMode_TypeDef; + +#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event)) + +/** + * @brief EXTI Trigger enumeration + */ + +typedef enum +{ + EXTI_Trigger_Rising = 0x08, + EXTI_Trigger_Falling = 0x0C, + EXTI_Trigger_Rising_Falling = 0x10 +}EXTITrigger_TypeDef; + +#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \ + ((TRIGGER) == EXTI_Trigger_Falling) || \ + ((TRIGGER) == EXTI_Trigger_Rising_Falling)) +/** + * @brief EXTI Init Structure definition + */ + +typedef struct +{ + uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled. + This parameter can be any combination value of @ref EXTI_Lines */ + + EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines. + This parameter can be a value of @ref EXTIMode_TypeDef */ + + EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. + This parameter can be a value of @ref EXTITrigger_TypeDef */ + + FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines. + This parameter can be set either to ENABLE or DISABLE */ +}EXTI_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup EXTI_Exported_Constants + * @{ + */ + +/** @defgroup EXTI_Lines + * @{ + */ + +#define EXTI_Line0 ((uint32_t)0x00001) /*!< External interrupt line 0 */ +#define EXTI_Line1 ((uint32_t)0x00002) /*!< External interrupt line 1 */ +#define EXTI_Line2 ((uint32_t)0x00004) /*!< External interrupt line 2 */ +#define EXTI_Line3 ((uint32_t)0x00008) /*!< External interrupt line 3 */ +#define EXTI_Line4 ((uint32_t)0x00010) /*!< External interrupt line 4 */ +#define EXTI_Line5 ((uint32_t)0x00020) /*!< External interrupt line 5 */ +#define EXTI_Line6 ((uint32_t)0x00040) /*!< External interrupt line 6 */ +#define EXTI_Line7 ((uint32_t)0x00080) /*!< External interrupt line 7 */ +#define EXTI_Line8 ((uint32_t)0x00100) /*!< External interrupt line 8 */ +#define EXTI_Line9 ((uint32_t)0x00200) /*!< External interrupt line 9 */ +#define EXTI_Line10 ((uint32_t)0x00400) /*!< External interrupt line 10 */ +#define EXTI_Line11 ((uint32_t)0x00800) /*!< External interrupt line 11 */ +#define EXTI_Line12 ((uint32_t)0x01000) /*!< External interrupt line 12 */ +#define EXTI_Line13 ((uint32_t)0x02000) /*!< External interrupt line 13 */ +#define EXTI_Line14 ((uint32_t)0x04000) /*!< External interrupt line 14 */ +#define EXTI_Line15 ((uint32_t)0x08000) /*!< External interrupt line 15 */ +#define EXTI_Line16 ((uint32_t)0x10000) /*!< External interrupt line 16 Connected to the PVD Output */ +#define EXTI_Line17 ((uint32_t)0x20000) /*!< External interrupt line 17 Connected to the RTC Alarm event */ +#define EXTI_Line18 ((uint32_t)0x40000) /*!< External interrupt line 18 Connected to the USB OTG FS Wakeup from suspend event */ +#define EXTI_Line19 ((uint32_t)0x80000) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */ +#define EXTI_Line20 ((uint32_t)0x00100000) /*!< External interrupt line 20 Connected to the USB OTG HS (configured in FS) Wakeup event */ +#define EXTI_Line21 ((uint32_t)0x00200000) /*!< External interrupt line 21 Connected to the RTC Tamper and Time Stamp events */ +#define EXTI_Line22 ((uint32_t)0x00400000) /*!< External interrupt line 22 Connected to the RTC Wakeup event */ + +#define IS_EXTI_LINE(LINE) ((((LINE) & (uint32_t)0xFF800000) == 0x00) && ((LINE) != (uint16_t)0x00)) + +#define IS_GET_EXTI_LINE(LINE) (((LINE) == EXTI_Line0) || ((LINE) == EXTI_Line1) || \ + ((LINE) == EXTI_Line2) || ((LINE) == EXTI_Line3) || \ + ((LINE) == EXTI_Line4) || ((LINE) == EXTI_Line5) || \ + ((LINE) == EXTI_Line6) || ((LINE) == EXTI_Line7) || \ + ((LINE) == EXTI_Line8) || ((LINE) == EXTI_Line9) || \ + ((LINE) == EXTI_Line10) || ((LINE) == EXTI_Line11) || \ + ((LINE) == EXTI_Line12) || ((LINE) == EXTI_Line13) || \ + ((LINE) == EXTI_Line14) || ((LINE) == EXTI_Line15) || \ + ((LINE) == EXTI_Line16) || ((LINE) == EXTI_Line17) || \ + ((LINE) == EXTI_Line18) || ((LINE) == EXTI_Line19) || \ + ((LINE) == EXTI_Line20) || ((LINE) == EXTI_Line21) ||\ + ((LINE) == EXTI_Line22)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the EXTI configuration to the default reset state *****/ +void EXTI_DeInit(void); + +/* Initialization and Configuration functions *********************************/ +void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); +void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct); +void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line); + +/* Interrupts and flags management functions **********************************/ +FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line); +void EXTI_ClearFlag(uint32_t EXTI_Line); +ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); +void EXTI_ClearITPendingBit(uint32_t EXTI_Line); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_EXTI_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_flash.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_flash.h new file mode 100644 index 0000000..458f1d8 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_flash.h @@ -0,0 +1,334 @@ +/** + ****************************************************************************** + * @file stm32f4xx_flash.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the FLASH + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_FLASH_H +#define __STM32F4xx_FLASH_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup FLASH + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief FLASH Status + */ +typedef enum +{ + FLASH_BUSY = 1, + FLASH_ERROR_PGS, + FLASH_ERROR_PGP, + FLASH_ERROR_PGA, + FLASH_ERROR_WRP, + FLASH_ERROR_PROGRAM, + FLASH_ERROR_OPERATION, + FLASH_COMPLETE +}FLASH_Status; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup FLASH_Exported_Constants + * @{ + */ + +/** @defgroup Flash_Latency + * @{ + */ +#define FLASH_Latency_0 ((uint8_t)0x0000) /*!< FLASH Zero Latency cycle */ +#define FLASH_Latency_1 ((uint8_t)0x0001) /*!< FLASH One Latency cycle */ +#define FLASH_Latency_2 ((uint8_t)0x0002) /*!< FLASH Two Latency cycles */ +#define FLASH_Latency_3 ((uint8_t)0x0003) /*!< FLASH Three Latency cycles */ +#define FLASH_Latency_4 ((uint8_t)0x0004) /*!< FLASH Four Latency cycles */ +#define FLASH_Latency_5 ((uint8_t)0x0005) /*!< FLASH Five Latency cycles */ +#define FLASH_Latency_6 ((uint8_t)0x0006) /*!< FLASH Six Latency cycles */ +#define FLASH_Latency_7 ((uint8_t)0x0007) /*!< FLASH Seven Latency cycles */ + +#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_Latency_0) || \ + ((LATENCY) == FLASH_Latency_1) || \ + ((LATENCY) == FLASH_Latency_2) || \ + ((LATENCY) == FLASH_Latency_3) || \ + ((LATENCY) == FLASH_Latency_4) || \ + ((LATENCY) == FLASH_Latency_5) || \ + ((LATENCY) == FLASH_Latency_6) || \ + ((LATENCY) == FLASH_Latency_7)) +/** + * @} + */ + +/** @defgroup FLASH_Voltage_Range + * @{ + */ +#define VoltageRange_1 ((uint8_t)0x00) /*!< Device operating range: 1.8V to 2.1V */ +#define VoltageRange_2 ((uint8_t)0x01) /*!= 0x08000000) && ((ADDRESS) < 0x080FFFFF)) ||\ + (((ADDRESS) >= 0x1FFF7800) && ((ADDRESS) < 0x1FFF7A0F))) +/** + * @} + */ + +/** @defgroup Option_Bytes_Write_Protection + * @{ + */ +#define OB_WRP_Sector_0 ((uint32_t)0x00000001) /*!< Write protection of Sector0 */ +#define OB_WRP_Sector_1 ((uint32_t)0x00000002) /*!< Write protection of Sector1 */ +#define OB_WRP_Sector_2 ((uint32_t)0x00000004) /*!< Write protection of Sector2 */ +#define OB_WRP_Sector_3 ((uint32_t)0x00000008) /*!< Write protection of Sector3 */ +#define OB_WRP_Sector_4 ((uint32_t)0x00000010) /*!< Write protection of Sector4 */ +#define OB_WRP_Sector_5 ((uint32_t)0x00000020) /*!< Write protection of Sector5 */ +#define OB_WRP_Sector_6 ((uint32_t)0x00000040) /*!< Write protection of Sector6 */ +#define OB_WRP_Sector_7 ((uint32_t)0x00000080) /*!< Write protection of Sector7 */ +#define OB_WRP_Sector_8 ((uint32_t)0x00000100) /*!< Write protection of Sector8 */ +#define OB_WRP_Sector_9 ((uint32_t)0x00000200) /*!< Write protection of Sector9 */ +#define OB_WRP_Sector_10 ((uint32_t)0x00000400) /*!< Write protection of Sector10 */ +#define OB_WRP_Sector_11 ((uint32_t)0x00000800) /*!< Write protection of Sector11 */ +#define OB_WRP_Sector_All ((uint32_t)0x00000FFF) /*!< Write protection of all Sectors */ + +#define IS_OB_WRP(SECTOR)((((SECTOR) & (uint32_t)0xFFFFF000) == 0x00000000) && ((SECTOR) != 0x00000000)) +/** + * @} + */ + +/** @defgroup FLASH_Option_Bytes_Read_Protection + * @{ + */ +#define OB_RDP_Level_0 ((uint8_t)0xAA) +#define OB_RDP_Level_1 ((uint8_t)0x55) +/*#define OB_RDP_Level_2 ((uint8_t)0xCC)*/ /*!< Warning: When enabling read protection level 2 + it's no more possible to go back to level 1 or 0 */ +#define IS_OB_RDP(LEVEL) (((LEVEL) == OB_RDP_Level_0)||\ + ((LEVEL) == OB_RDP_Level_1))/*||\ + ((LEVEL) == OB_RDP_Level_2))*/ +/** + * @} + */ + +/** @defgroup FLASH_Option_Bytes_IWatchdog + * @{ + */ +#define OB_IWDG_SW ((uint8_t)0x20) /*!< Software IWDG selected */ +#define OB_IWDG_HW ((uint8_t)0x00) /*!< Hardware IWDG selected */ +#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW)) +/** + * @} + */ + +/** @defgroup FLASH_Option_Bytes_nRST_STOP + * @{ + */ +#define OB_STOP_NoRST ((uint8_t)0x40) /*!< No reset generated when entering in STOP */ +#define OB_STOP_RST ((uint8_t)0x00) /*!< Reset generated when entering in STOP */ +#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NoRST) || ((SOURCE) == OB_STOP_RST)) +/** + * @} + */ + + +/** @defgroup FLASH_Option_Bytes_nRST_STDBY + * @{ + */ +#define OB_STDBY_NoRST ((uint8_t)0x80) /*!< No reset generated when entering in STANDBY */ +#define OB_STDBY_RST ((uint8_t)0x00) /*!< Reset generated when entering in STANDBY */ +#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NoRST) || ((SOURCE) == OB_STDBY_RST)) +/** + * @} + */ + +/** @defgroup FLASH_BOR_Reset_Level + * @{ + */ +#define OB_BOR_LEVEL3 ((uint8_t)0x00) /*!< Supply voltage ranges from 2.70 to 3.60 V */ +#define OB_BOR_LEVEL2 ((uint8_t)0x04) /*!< Supply voltage ranges from 2.40 to 2.70 V */ +#define OB_BOR_LEVEL1 ((uint8_t)0x08) /*!< Supply voltage ranges from 2.10 to 2.40 V */ +#define OB_BOR_OFF ((uint8_t)0x0C) /*!< Supply voltage ranges from 1.62 to 2.10 V */ +#define IS_OB_BOR(LEVEL) (((LEVEL) == OB_BOR_LEVEL1) || ((LEVEL) == OB_BOR_LEVEL2) ||\ + ((LEVEL) == OB_BOR_LEVEL3) || ((LEVEL) == OB_BOR_OFF)) +/** + * @} + */ + +/** @defgroup FLASH_Interrupts + * @{ + */ +#define FLASH_IT_EOP ((uint32_t)0x01000000) /*!< End of FLASH Operation Interrupt source */ +#define FLASH_IT_ERR ((uint32_t)0x02000000) /*!< Error Interrupt source */ +#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFCFFFFFF) == 0x00000000) && ((IT) != 0x00000000)) +/** + * @} + */ + +/** @defgroup FLASH_Flags + * @{ + */ +#define FLASH_FLAG_EOP ((uint32_t)0x00000001) /*!< FLASH End of Operation flag */ +#define FLASH_FLAG_OPERR ((uint32_t)0x00000002) /*!< FLASH operation Error flag */ +#define FLASH_FLAG_WRPERR ((uint32_t)0x00000010) /*!< FLASH Write protected error flag */ +#define FLASH_FLAG_PGAERR ((uint32_t)0x00000020) /*!< FLASH Programming Alignment error flag */ +#define FLASH_FLAG_PGPERR ((uint32_t)0x00000040) /*!< FLASH Programming Parallelism error flag */ +#define FLASH_FLAG_PGSERR ((uint32_t)0x00000080) /*!< FLASH Programming Sequence error flag */ +#define FLASH_FLAG_BSY ((uint32_t)0x00010000) /*!< FLASH Busy flag */ +#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFF0C) == 0x00000000) && ((FLAG) != 0x00000000)) +#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_EOP) || ((FLAG) == FLASH_FLAG_OPERR) || \ + ((FLAG) == FLASH_FLAG_WRPERR) || ((FLAG) == FLASH_FLAG_PGAERR) || \ + ((FLAG) == FLASH_FLAG_PGPERR) || ((FLAG) == FLASH_FLAG_PGSERR) || \ + ((FLAG) == FLASH_FLAG_BSY)) +/** + * @} + */ + +/** @defgroup FLASH_Program_Parallelism + * @{ + */ +#define FLASH_PSIZE_BYTE ((uint32_t)0x00000000) +#define FLASH_PSIZE_HALF_WORD ((uint32_t)0x00000100) +#define FLASH_PSIZE_WORD ((uint32_t)0x00000200) +#define FLASH_PSIZE_DOUBLE_WORD ((uint32_t)0x00000300) +#define CR_PSIZE_MASK ((uint32_t)0xFFFFFCFF) +/** + * @} + */ + +/** @defgroup FLASH_Keys + * @{ + */ +#define RDP_KEY ((uint16_t)0x00A5) +#define FLASH_KEY1 ((uint32_t)0x45670123) +#define FLASH_KEY2 ((uint32_t)0xCDEF89AB) +#define FLASH_OPT_KEY1 ((uint32_t)0x08192A3B) +#define FLASH_OPT_KEY2 ((uint32_t)0x4C5D6E7F) +/** + * @} + */ + +/** + * @brief ACR register byte 0 (Bits[8:0]) base address + */ +#define ACR_BYTE0_ADDRESS ((uint32_t)0x40023C00) +/** + * @brief OPTCR register byte 3 (Bits[24:16]) base address + */ +#define OPTCR_BYTE0_ADDRESS ((uint32_t)0x40023C14) +#define OPTCR_BYTE1_ADDRESS ((uint32_t)0x40023C15) +#define OPTCR_BYTE2_ADDRESS ((uint32_t)0x40023C16) + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* FLASH Interface configuration functions ************************************/ +void FLASH_SetLatency(uint32_t FLASH_Latency); +void FLASH_PrefetchBufferCmd(FunctionalState NewState); +void FLASH_InstructionCacheCmd(FunctionalState NewState); +void FLASH_DataCacheCmd(FunctionalState NewState); +void FLASH_InstructionCacheReset(void); +void FLASH_DataCacheReset(void); + +/* FLASH Memory Programming functions *****************************************/ +void FLASH_Unlock(void); +void FLASH_Lock(void); +FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange); +FLASH_Status FLASH_EraseAllSectors(uint8_t VoltageRange); +FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data); +FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data); +FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data); +FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data); + +/* Option Bytes Programming functions *****************************************/ +void FLASH_OB_Unlock(void); +void FLASH_OB_Lock(void); +void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState); +void FLASH_OB_RDPConfig(uint8_t OB_RDP); +void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY); +void FLASH_OB_BORConfig(uint8_t OB_BOR); +FLASH_Status FLASH_OB_Launch(void); +uint8_t FLASH_OB_GetUser(void); +uint16_t FLASH_OB_GetWRP(void); +FlagStatus FLASH_OB_GetRDP(void); +uint8_t FLASH_OB_GetBOR(void); + +/* Interrupts and flags management functions **********************************/ +void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState); +FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG); +void FLASH_ClearFlag(uint32_t FLASH_FLAG); +FLASH_Status FLASH_GetStatus(void); +FLASH_Status FLASH_WaitForLastOperation(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_FLASH_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_fsmc.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_fsmc.h new file mode 100644 index 0000000..29baf50 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_fsmc.h @@ -0,0 +1,669 @@ +/** + ****************************************************************************** + * @file stm32f4xx_fsmc.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the FSMC firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_FSMC_H +#define __STM32F4xx_FSMC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup FSMC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief Timing parameters For NOR/SRAM Banks + */ +typedef struct +{ + uint32_t FSMC_AddressSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address setup time. + This parameter can be a value between 0 and 0xF. + @note This parameter is not used with synchronous NOR Flash memories. */ + + uint32_t FSMC_AddressHoldTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address hold time. + This parameter can be a value between 0 and 0xF. + @note This parameter is not used with synchronous NOR Flash memories.*/ + + uint32_t FSMC_DataSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the data setup time. + This parameter can be a value between 0 and 0xFF. + @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed NOR Flash memories. */ + + uint32_t FSMC_BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure + the duration of the bus turnaround. + This parameter can be a value between 0 and 0xF. + @note This parameter is only used for multiplexed NOR Flash memories. */ + + uint32_t FSMC_CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of HCLK cycles. + This parameter can be a value between 1 and 0xF. + @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM accesses. */ + + uint32_t FSMC_DataLatency; /*!< Defines the number of memory clock cycles to issue + to the memory before getting the first data. + The parameter value depends on the memory type as shown below: + - It must be set to 0 in case of a CRAM + - It is don't care in asynchronous NOR, SRAM or ROM accesses + - It may assume a value between 0 and 0xF in NOR Flash memories + with synchronous burst mode enable */ + + uint32_t FSMC_AccessMode; /*!< Specifies the asynchronous access mode. + This parameter can be a value of @ref FSMC_Access_Mode */ +}FSMC_NORSRAMTimingInitTypeDef; + +/** + * @brief FSMC NOR/SRAM Init structure definition + */ +typedef struct +{ + uint32_t FSMC_Bank; /*!< Specifies the NOR/SRAM memory bank that will be used. + This parameter can be a value of @ref FSMC_NORSRAM_Bank */ + + uint32_t FSMC_DataAddressMux; /*!< Specifies whether the address and data values are + multiplexed on the databus or not. + This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */ + + uint32_t FSMC_MemoryType; /*!< Specifies the type of external memory attached to + the corresponding memory bank. + This parameter can be a value of @ref FSMC_Memory_Type */ + + uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be a value of @ref FSMC_Data_Width */ + + uint32_t FSMC_BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory, + valid only with synchronous burst Flash memories. + This parameter can be a value of @ref FSMC_Burst_Access_Mode */ + + uint32_t FSMC_AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers, + valid only with asynchronous Flash memories. + This parameter can be a value of @ref FSMC_AsynchronousWait */ + + uint32_t FSMC_WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing + the Flash memory in burst mode. + This parameter can be a value of @ref FSMC_Wait_Signal_Polarity */ + + uint32_t FSMC_WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash + memory, valid only when accessing Flash memories in burst mode. + This parameter can be a value of @ref FSMC_Wrap_Mode */ + + uint32_t FSMC_WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one + clock cycle before the wait state or during the wait state, + valid only when accessing memories in burst mode. + This parameter can be a value of @ref FSMC_Wait_Timing */ + + uint32_t FSMC_WriteOperation; /*!< Enables or disables the write operation in the selected bank by the FSMC. + This parameter can be a value of @ref FSMC_Write_Operation */ + + uint32_t FSMC_WaitSignal; /*!< Enables or disables the wait-state insertion via wait + signal, valid for Flash memory access in burst mode. + This parameter can be a value of @ref FSMC_Wait_Signal */ + + uint32_t FSMC_ExtendedMode; /*!< Enables or disables the extended mode. + This parameter can be a value of @ref FSMC_Extended_Mode */ + + uint32_t FSMC_WriteBurst; /*!< Enables or disables the write burst operation. + This parameter can be a value of @ref FSMC_Write_Burst */ + + FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct; /*!< Timing Parameters for write and read access if the ExtendedMode is not used*/ + + FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct; /*!< Timing Parameters for write access if the ExtendedMode is used*/ +}FSMC_NORSRAMInitTypeDef; + +/** + * @brief Timing parameters For FSMC NAND and PCCARD Banks + */ +typedef struct +{ + uint32_t FSMC_SetupTime; /*!< Defines the number of HCLK cycles to setup address before + the command assertion for NAND-Flash read or write access + to common/Attribute or I/O memory space (depending on + the memory space timing to be configured). + This parameter can be a value between 0 and 0xFF.*/ + + uint32_t FSMC_WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the + command for NAND-Flash read or write access to + common/Attribute or I/O memory space (depending on the + memory space timing to be configured). + This parameter can be a number between 0x00 and 0xFF */ + + uint32_t FSMC_HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address + (and data for write access) after the command deassertion + for NAND-Flash read or write access to common/Attribute + or I/O memory space (depending on the memory space timing + to be configured). + This parameter can be a number between 0x00 and 0xFF */ + + uint32_t FSMC_HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the + databus is kept in HiZ after the start of a NAND-Flash + write access to common/Attribute or I/O memory space (depending + on the memory space timing to be configured). + This parameter can be a number between 0x00 and 0xFF */ +}FSMC_NAND_PCCARDTimingInitTypeDef; + +/** + * @brief FSMC NAND Init structure definition + */ +typedef struct +{ + uint32_t FSMC_Bank; /*!< Specifies the NAND memory bank that will be used. + This parameter can be a value of @ref FSMC_NAND_Bank */ + + uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory Bank. + This parameter can be any value of @ref FSMC_Wait_feature */ + + uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be any value of @ref FSMC_Data_Width */ + + uint32_t FSMC_ECC; /*!< Enables or disables the ECC computation. + This parameter can be any value of @ref FSMC_ECC */ + + uint32_t FSMC_ECCPageSize; /*!< Defines the page size for the extended ECC. + This parameter can be any value of @ref FSMC_ECC_Page_Size */ + + uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between CLE low and RE low. + This parameter can be a value between 0 and 0xFF. */ + + uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between ALE low and RE low. + This parameter can be a number between 0x0 and 0xFF */ + + FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */ + + FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */ +}FSMC_NANDInitTypeDef; + +/** + * @brief FSMC PCCARD Init structure definition + */ + +typedef struct +{ + uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the Memory Bank. + This parameter can be any value of @ref FSMC_Wait_feature */ + + uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between CLE low and RE low. + This parameter can be a value between 0 and 0xFF. */ + + uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between ALE low and RE low. + This parameter can be a number between 0x0 and 0xFF */ + + + FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */ + + FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */ + + FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_IOSpaceTimingStruct; /*!< FSMC IO Space Timing */ +}FSMC_PCCARDInitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup FSMC_Exported_Constants + * @{ + */ + +/** @defgroup FSMC_NORSRAM_Bank + * @{ + */ +#define FSMC_Bank1_NORSRAM1 ((uint32_t)0x00000000) +#define FSMC_Bank1_NORSRAM2 ((uint32_t)0x00000002) +#define FSMC_Bank1_NORSRAM3 ((uint32_t)0x00000004) +#define FSMC_Bank1_NORSRAM4 ((uint32_t)0x00000006) +/** + * @} + */ + +/** @defgroup FSMC_NAND_Bank + * @{ + */ +#define FSMC_Bank2_NAND ((uint32_t)0x00000010) +#define FSMC_Bank3_NAND ((uint32_t)0x00000100) +/** + * @} + */ + +/** @defgroup FSMC_PCCARD_Bank + * @{ + */ +#define FSMC_Bank4_PCCARD ((uint32_t)0x00001000) +/** + * @} + */ + +#define IS_FSMC_NORSRAM_BANK(BANK) (((BANK) == FSMC_Bank1_NORSRAM1) || \ + ((BANK) == FSMC_Bank1_NORSRAM2) || \ + ((BANK) == FSMC_Bank1_NORSRAM3) || \ + ((BANK) == FSMC_Bank1_NORSRAM4)) + +#define IS_FSMC_NAND_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ + ((BANK) == FSMC_Bank3_NAND)) + +#define IS_FSMC_GETFLAG_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ + ((BANK) == FSMC_Bank3_NAND) || \ + ((BANK) == FSMC_Bank4_PCCARD)) + +#define IS_FSMC_IT_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ + ((BANK) == FSMC_Bank3_NAND) || \ + ((BANK) == FSMC_Bank4_PCCARD)) + +/** @defgroup FSMC_NOR_SRAM_Controller + * @{ + */ + +/** @defgroup FSMC_Data_Address_Bus_Multiplexing + * @{ + */ + +#define FSMC_DataAddressMux_Disable ((uint32_t)0x00000000) +#define FSMC_DataAddressMux_Enable ((uint32_t)0x00000002) +#define IS_FSMC_MUX(MUX) (((MUX) == FSMC_DataAddressMux_Disable) || \ + ((MUX) == FSMC_DataAddressMux_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Memory_Type + * @{ + */ + +#define FSMC_MemoryType_SRAM ((uint32_t)0x00000000) +#define FSMC_MemoryType_PSRAM ((uint32_t)0x00000004) +#define FSMC_MemoryType_NOR ((uint32_t)0x00000008) +#define IS_FSMC_MEMORY(MEMORY) (((MEMORY) == FSMC_MemoryType_SRAM) || \ + ((MEMORY) == FSMC_MemoryType_PSRAM)|| \ + ((MEMORY) == FSMC_MemoryType_NOR)) +/** + * @} + */ + +/** @defgroup FSMC_Data_Width + * @{ + */ + +#define FSMC_MemoryDataWidth_8b ((uint32_t)0x00000000) +#define FSMC_MemoryDataWidth_16b ((uint32_t)0x00000010) +#define IS_FSMC_MEMORY_WIDTH(WIDTH) (((WIDTH) == FSMC_MemoryDataWidth_8b) || \ + ((WIDTH) == FSMC_MemoryDataWidth_16b)) +/** + * @} + */ + +/** @defgroup FSMC_Burst_Access_Mode + * @{ + */ + +#define FSMC_BurstAccessMode_Disable ((uint32_t)0x00000000) +#define FSMC_BurstAccessMode_Enable ((uint32_t)0x00000100) +#define IS_FSMC_BURSTMODE(STATE) (((STATE) == FSMC_BurstAccessMode_Disable) || \ + ((STATE) == FSMC_BurstAccessMode_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_AsynchronousWait + * @{ + */ +#define FSMC_AsynchronousWait_Disable ((uint32_t)0x00000000) +#define FSMC_AsynchronousWait_Enable ((uint32_t)0x00008000) +#define IS_FSMC_ASYNWAIT(STATE) (((STATE) == FSMC_AsynchronousWait_Disable) || \ + ((STATE) == FSMC_AsynchronousWait_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Wait_Signal_Polarity + * @{ + */ +#define FSMC_WaitSignalPolarity_Low ((uint32_t)0x00000000) +#define FSMC_WaitSignalPolarity_High ((uint32_t)0x00000200) +#define IS_FSMC_WAIT_POLARITY(POLARITY) (((POLARITY) == FSMC_WaitSignalPolarity_Low) || \ + ((POLARITY) == FSMC_WaitSignalPolarity_High)) +/** + * @} + */ + +/** @defgroup FSMC_Wrap_Mode + * @{ + */ +#define FSMC_WrapMode_Disable ((uint32_t)0x00000000) +#define FSMC_WrapMode_Enable ((uint32_t)0x00000400) +#define IS_FSMC_WRAP_MODE(MODE) (((MODE) == FSMC_WrapMode_Disable) || \ + ((MODE) == FSMC_WrapMode_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Wait_Timing + * @{ + */ +#define FSMC_WaitSignalActive_BeforeWaitState ((uint32_t)0x00000000) +#define FSMC_WaitSignalActive_DuringWaitState ((uint32_t)0x00000800) +#define IS_FSMC_WAIT_SIGNAL_ACTIVE(ACTIVE) (((ACTIVE) == FSMC_WaitSignalActive_BeforeWaitState) || \ + ((ACTIVE) == FSMC_WaitSignalActive_DuringWaitState)) +/** + * @} + */ + +/** @defgroup FSMC_Write_Operation + * @{ + */ +#define FSMC_WriteOperation_Disable ((uint32_t)0x00000000) +#define FSMC_WriteOperation_Enable ((uint32_t)0x00001000) +#define IS_FSMC_WRITE_OPERATION(OPERATION) (((OPERATION) == FSMC_WriteOperation_Disable) || \ + ((OPERATION) == FSMC_WriteOperation_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Wait_Signal + * @{ + */ +#define FSMC_WaitSignal_Disable ((uint32_t)0x00000000) +#define FSMC_WaitSignal_Enable ((uint32_t)0x00002000) +#define IS_FSMC_WAITE_SIGNAL(SIGNAL) (((SIGNAL) == FSMC_WaitSignal_Disable) || \ + ((SIGNAL) == FSMC_WaitSignal_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Extended_Mode + * @{ + */ +#define FSMC_ExtendedMode_Disable ((uint32_t)0x00000000) +#define FSMC_ExtendedMode_Enable ((uint32_t)0x00004000) + +#define IS_FSMC_EXTENDED_MODE(MODE) (((MODE) == FSMC_ExtendedMode_Disable) || \ + ((MODE) == FSMC_ExtendedMode_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Write_Burst + * @{ + */ + +#define FSMC_WriteBurst_Disable ((uint32_t)0x00000000) +#define FSMC_WriteBurst_Enable ((uint32_t)0x00080000) +#define IS_FSMC_WRITE_BURST(BURST) (((BURST) == FSMC_WriteBurst_Disable) || \ + ((BURST) == FSMC_WriteBurst_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Address_Setup_Time + * @{ + */ +#define IS_FSMC_ADDRESS_SETUP_TIME(TIME) ((TIME) <= 0xF) +/** + * @} + */ + +/** @defgroup FSMC_Address_Hold_Time + * @{ + */ +#define IS_FSMC_ADDRESS_HOLD_TIME(TIME) ((TIME) <= 0xF) +/** + * @} + */ + +/** @defgroup FSMC_Data_Setup_Time + * @{ + */ +#define IS_FSMC_DATASETUP_TIME(TIME) (((TIME) > 0) && ((TIME) <= 0xFF)) +/** + * @} + */ + +/** @defgroup FSMC_Bus_Turn_around_Duration + * @{ + */ +#define IS_FSMC_TURNAROUND_TIME(TIME) ((TIME) <= 0xF) +/** + * @} + */ + +/** @defgroup FSMC_CLK_Division + * @{ + */ +#define IS_FSMC_CLK_DIV(DIV) ((DIV) <= 0xF) +/** + * @} + */ + +/** @defgroup FSMC_Data_Latency + * @{ + */ +#define IS_FSMC_DATA_LATENCY(LATENCY) ((LATENCY) <= 0xF) +/** + * @} + */ + +/** @defgroup FSMC_Access_Mode + * @{ + */ +#define FSMC_AccessMode_A ((uint32_t)0x00000000) +#define FSMC_AccessMode_B ((uint32_t)0x10000000) +#define FSMC_AccessMode_C ((uint32_t)0x20000000) +#define FSMC_AccessMode_D ((uint32_t)0x30000000) +#define IS_FSMC_ACCESS_MODE(MODE) (((MODE) == FSMC_AccessMode_A) || \ + ((MODE) == FSMC_AccessMode_B) || \ + ((MODE) == FSMC_AccessMode_C) || \ + ((MODE) == FSMC_AccessMode_D)) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FSMC_NAND_PCCARD_Controller + * @{ + */ + +/** @defgroup FSMC_Wait_feature + * @{ + */ +#define FSMC_Waitfeature_Disable ((uint32_t)0x00000000) +#define FSMC_Waitfeature_Enable ((uint32_t)0x00000002) +#define IS_FSMC_WAIT_FEATURE(FEATURE) (((FEATURE) == FSMC_Waitfeature_Disable) || \ + ((FEATURE) == FSMC_Waitfeature_Enable)) +/** + * @} + */ + + +/** @defgroup FSMC_ECC + * @{ + */ +#define FSMC_ECC_Disable ((uint32_t)0x00000000) +#define FSMC_ECC_Enable ((uint32_t)0x00000040) +#define IS_FSMC_ECC_STATE(STATE) (((STATE) == FSMC_ECC_Disable) || \ + ((STATE) == FSMC_ECC_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_ECC_Page_Size + * @{ + */ +#define FSMC_ECCPageSize_256Bytes ((uint32_t)0x00000000) +#define FSMC_ECCPageSize_512Bytes ((uint32_t)0x00020000) +#define FSMC_ECCPageSize_1024Bytes ((uint32_t)0x00040000) +#define FSMC_ECCPageSize_2048Bytes ((uint32_t)0x00060000) +#define FSMC_ECCPageSize_4096Bytes ((uint32_t)0x00080000) +#define FSMC_ECCPageSize_8192Bytes ((uint32_t)0x000A0000) +#define IS_FSMC_ECCPAGE_SIZE(SIZE) (((SIZE) == FSMC_ECCPageSize_256Bytes) || \ + ((SIZE) == FSMC_ECCPageSize_512Bytes) || \ + ((SIZE) == FSMC_ECCPageSize_1024Bytes) || \ + ((SIZE) == FSMC_ECCPageSize_2048Bytes) || \ + ((SIZE) == FSMC_ECCPageSize_4096Bytes) || \ + ((SIZE) == FSMC_ECCPageSize_8192Bytes)) +/** + * @} + */ + +/** @defgroup FSMC_TCLR_Setup_Time + * @{ + */ +#define IS_FSMC_TCLR_TIME(TIME) ((TIME) <= 0xFF) +/** + * @} + */ + +/** @defgroup FSMC_TAR_Setup_Time + * @{ + */ +#define IS_FSMC_TAR_TIME(TIME) ((TIME) <= 0xFF) +/** + * @} + */ + +/** @defgroup FSMC_Setup_Time + * @{ + */ +#define IS_FSMC_SETUP_TIME(TIME) ((TIME) <= 0xFF) +/** + * @} + */ + +/** @defgroup FSMC_Wait_Setup_Time + * @{ + */ +#define IS_FSMC_WAIT_TIME(TIME) ((TIME) <= 0xFF) +/** + * @} + */ + +/** @defgroup FSMC_Hold_Setup_Time + * @{ + */ +#define IS_FSMC_HOLD_TIME(TIME) ((TIME) <= 0xFF) +/** + * @} + */ + +/** @defgroup FSMC_HiZ_Setup_Time + * @{ + */ +#define IS_FSMC_HIZ_TIME(TIME) ((TIME) <= 0xFF) +/** + * @} + */ + +/** @defgroup FSMC_Interrupt_sources + * @{ + */ +#define FSMC_IT_RisingEdge ((uint32_t)0x00000008) +#define FSMC_IT_Level ((uint32_t)0x00000010) +#define FSMC_IT_FallingEdge ((uint32_t)0x00000020) +#define IS_FSMC_IT(IT) ((((IT) & (uint32_t)0xFFFFFFC7) == 0x00000000) && ((IT) != 0x00000000)) +#define IS_FSMC_GET_IT(IT) (((IT) == FSMC_IT_RisingEdge) || \ + ((IT) == FSMC_IT_Level) || \ + ((IT) == FSMC_IT_FallingEdge)) +/** + * @} + */ + +/** @defgroup FSMC_Flags + * @{ + */ +#define FSMC_FLAG_RisingEdge ((uint32_t)0x00000001) +#define FSMC_FLAG_Level ((uint32_t)0x00000002) +#define FSMC_FLAG_FallingEdge ((uint32_t)0x00000004) +#define FSMC_FLAG_FEMPT ((uint32_t)0x00000040) +#define IS_FSMC_GET_FLAG(FLAG) (((FLAG) == FSMC_FLAG_RisingEdge) || \ + ((FLAG) == FSMC_FLAG_Level) || \ + ((FLAG) == FSMC_FLAG_FallingEdge) || \ + ((FLAG) == FSMC_FLAG_FEMPT)) + +#define IS_FSMC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFF8) == 0x00000000) && ((FLAG) != 0x00000000)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* NOR/SRAM Controller functions **********************************************/ +void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank); +void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct); +void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct); +void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState); + +/* NAND Controller functions **************************************************/ +void FSMC_NANDDeInit(uint32_t FSMC_Bank); +void FSMC_NANDInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct); +void FSMC_NANDStructInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct); +void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState); +void FSMC_NANDECCCmd(uint32_t FSMC_Bank, FunctionalState NewState); +uint32_t FSMC_GetECC(uint32_t FSMC_Bank); + +/* PCCARD Controller functions ************************************************/ +void FSMC_PCCARDDeInit(void); +void FSMC_PCCARDInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct); +void FSMC_PCCARDStructInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct); +void FSMC_PCCARDCmd(FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void FSMC_ITConfig(uint32_t FSMC_Bank, uint32_t FSMC_IT, FunctionalState NewState); +FlagStatus FSMC_GetFlagStatus(uint32_t FSMC_Bank, uint32_t FSMC_FLAG); +void FSMC_ClearFlag(uint32_t FSMC_Bank, uint32_t FSMC_FLAG); +ITStatus FSMC_GetITStatus(uint32_t FSMC_Bank, uint32_t FSMC_IT); +void FSMC_ClearITPendingBit(uint32_t FSMC_Bank, uint32_t FSMC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_FSMC_H */ +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h new file mode 100644 index 0000000..5cbc201 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h @@ -0,0 +1,406 @@ +/** + ****************************************************************************** + * @file stm32f4xx_gpio.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the GPIO firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_GPIO_H +#define __STM32F4xx_GPIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup GPIO + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ + ((PERIPH) == GPIOB) || \ + ((PERIPH) == GPIOC) || \ + ((PERIPH) == GPIOD) || \ + ((PERIPH) == GPIOE) || \ + ((PERIPH) == GPIOF) || \ + ((PERIPH) == GPIOG) || \ + ((PERIPH) == GPIOH) || \ + ((PERIPH) == GPIOI)) + +/** + * @brief GPIO Configuration Mode enumeration + */ +typedef enum +{ + GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ + GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ + GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ + GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ +}GPIOMode_TypeDef; +#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) || \ + ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN)) + +/** + * @brief GPIO Output type enumeration + */ +typedef enum +{ + GPIO_OType_PP = 0x00, + GPIO_OType_OD = 0x01 +}GPIOOType_TypeDef; +#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD)) + + +/** + * @brief GPIO Output Maximum frequency enumeration + */ +typedef enum +{ + GPIO_Speed_2MHz = 0x00, /*!< Low speed */ + GPIO_Speed_25MHz = 0x01, /*!< Medium speed */ + GPIO_Speed_50MHz = 0x02, /*!< Fast speed */ + GPIO_Speed_100MHz = 0x03 /*!< High speed on 30 pF (80 MHz Output max speed on 15 pF) */ +}GPIOSpeed_TypeDef; +#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_2MHz) || ((SPEED) == GPIO_Speed_25MHz) || \ + ((SPEED) == GPIO_Speed_50MHz)|| ((SPEED) == GPIO_Speed_100MHz)) + +/** + * @brief GPIO Configuration PullUp PullDown enumeration + */ +typedef enum +{ + GPIO_PuPd_NOPULL = 0x00, + GPIO_PuPd_UP = 0x01, + GPIO_PuPd_DOWN = 0x02 +}GPIOPuPd_TypeDef; +#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \ + ((PUPD) == GPIO_PuPd_DOWN)) + +/** + * @brief GPIO Bit SET and Bit RESET enumeration + */ +typedef enum +{ + Bit_RESET = 0, + Bit_SET +}BitAction; +#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) + + +/** + * @brief GPIO Init structure definition + */ +typedef struct +{ + uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_pins_define */ + + GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIOMode_TypeDef */ + + GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIOSpeed_TypeDef */ + + GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. + This parameter can be a value of @ref GPIOOType_TypeDef */ + + GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. + This parameter can be a value of @ref GPIOPuPd_TypeDef */ +}GPIO_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup GPIO_Exported_Constants + * @{ + */ + +/** @defgroup GPIO_pins_define + * @{ + */ +#define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */ +#define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */ +#define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */ +#define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */ +#define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */ +#define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */ +#define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */ +#define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */ +#define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */ +#define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */ +#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */ +#define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */ +#define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */ +#define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */ +#define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */ +#define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */ +#define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */ + +#define IS_GPIO_PIN(PIN) ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00)) +#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ + ((PIN) == GPIO_Pin_1) || \ + ((PIN) == GPIO_Pin_2) || \ + ((PIN) == GPIO_Pin_3) || \ + ((PIN) == GPIO_Pin_4) || \ + ((PIN) == GPIO_Pin_5) || \ + ((PIN) == GPIO_Pin_6) || \ + ((PIN) == GPIO_Pin_7) || \ + ((PIN) == GPIO_Pin_8) || \ + ((PIN) == GPIO_Pin_9) || \ + ((PIN) == GPIO_Pin_10) || \ + ((PIN) == GPIO_Pin_11) || \ + ((PIN) == GPIO_Pin_12) || \ + ((PIN) == GPIO_Pin_13) || \ + ((PIN) == GPIO_Pin_14) || \ + ((PIN) == GPIO_Pin_15)) +/** + * @} + */ + + +/** @defgroup GPIO_Pin_sources + * @{ + */ +#define GPIO_PinSource0 ((uint8_t)0x00) +#define GPIO_PinSource1 ((uint8_t)0x01) +#define GPIO_PinSource2 ((uint8_t)0x02) +#define GPIO_PinSource3 ((uint8_t)0x03) +#define GPIO_PinSource4 ((uint8_t)0x04) +#define GPIO_PinSource5 ((uint8_t)0x05) +#define GPIO_PinSource6 ((uint8_t)0x06) +#define GPIO_PinSource7 ((uint8_t)0x07) +#define GPIO_PinSource8 ((uint8_t)0x08) +#define GPIO_PinSource9 ((uint8_t)0x09) +#define GPIO_PinSource10 ((uint8_t)0x0A) +#define GPIO_PinSource11 ((uint8_t)0x0B) +#define GPIO_PinSource12 ((uint8_t)0x0C) +#define GPIO_PinSource13 ((uint8_t)0x0D) +#define GPIO_PinSource14 ((uint8_t)0x0E) +#define GPIO_PinSource15 ((uint8_t)0x0F) + +#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ + ((PINSOURCE) == GPIO_PinSource1) || \ + ((PINSOURCE) == GPIO_PinSource2) || \ + ((PINSOURCE) == GPIO_PinSource3) || \ + ((PINSOURCE) == GPIO_PinSource4) || \ + ((PINSOURCE) == GPIO_PinSource5) || \ + ((PINSOURCE) == GPIO_PinSource6) || \ + ((PINSOURCE) == GPIO_PinSource7) || \ + ((PINSOURCE) == GPIO_PinSource8) || \ + ((PINSOURCE) == GPIO_PinSource9) || \ + ((PINSOURCE) == GPIO_PinSource10) || \ + ((PINSOURCE) == GPIO_PinSource11) || \ + ((PINSOURCE) == GPIO_PinSource12) || \ + ((PINSOURCE) == GPIO_PinSource13) || \ + ((PINSOURCE) == GPIO_PinSource14) || \ + ((PINSOURCE) == GPIO_PinSource15)) +/** + * @} + */ + +/** @defgroup GPIO_Alternat_function_selection_define + * @{ + */ +/** + * @brief AF 0 selection + */ +#define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ +#define GPIO_AF_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ +#define GPIO_AF_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ + +/** + * @brief AF 2 selection + */ +#define GPIO_AF_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ +#define GPIO_AF_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ +#define GPIO_AF_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ +#define GPIO_AF_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ +#define GPIO_AF_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ +#define GPIO_AF_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ + +/** + * @brief AF 4 selection + */ +#define GPIO_AF_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ +#define GPIO_AF_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ +#define GPIO_AF_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */ +#define GPIO_AF_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ + +/** + * @brief AF 7 selection + */ +#define GPIO_AF_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ +#define GPIO_AF_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ +#define GPIO_AF_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ +#define GPIO_AF_I2S3ext ((uint8_t)0x07) /* I2S3ext Alternate Function mapping */ + +/** + * @brief AF 8 selection + */ +#define GPIO_AF_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ +#define GPIO_AF_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ +#define GPIO_AF_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ +#define GPIO_AF_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ +#define GPIO_AF_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ +#define GPIO_AF_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ +#define GPIO_AF_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ + +/** + * @brief AF 10 selection + */ +#define GPIO_AF_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ +#define GPIO_AF_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ + +/** + * @brief AF 11 selection + */ +#define GPIO_AF_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */ + +/** + * @brief AF 12 selection + */ +#define GPIO_AF_FSMC ((uint8_t)0xC) /* FSMC Alternate Function mapping */ +#define GPIO_AF_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ +#define GPIO_AF_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ + +/** + * @brief AF 13 selection + */ +#define GPIO_AF_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ + ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ + ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ + ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ + ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ + ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ + ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ + ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ + ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ + ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ + ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ + ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ + ((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ + ((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ + ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ + ((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_FSMC) || \ + ((AF) == GPIO_AF_OTG_HS_FS) || ((AF) == GPIO_AF_SDIO) || \ + ((AF) == GPIO_AF_DCMI) || ((AF) == GPIO_AF_EVENTOUT)) +/** + * @} + */ + +/** @defgroup GPIO_Legacy + * @{ + */ + +#define GPIO_Mode_AIN GPIO_Mode_AN + +#define GPIO_AF_OTG1_FS GPIO_AF_OTG_FS +#define GPIO_AF_OTG2_HS GPIO_AF_OTG_HS +#define GPIO_AF_OTG2_FS GPIO_AF_OTG_HS_FS + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the GPIO configuration to the default reset state ****/ +void GPIO_DeInit(GPIO_TypeDef* GPIOx); + +/* Initialization and Configuration functions *********************************/ +void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); +void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); +void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); + +/* GPIO Read and Write functions **********************************************/ +uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); +uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); +void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); +void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); +void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); + +/* GPIO Alternate functions configuration function ****************************/ +void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_GPIO_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_hash.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_hash.h new file mode 100644 index 0000000..f303c88 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_hash.h @@ -0,0 +1,244 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hash.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the HASH + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HASH_H +#define __STM32F4xx_HASH_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup HASH + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief HASH Init structure definition + */ +typedef struct +{ + uint32_t HASH_AlgoSelection; /*!< SHA-1 or MD5. This parameter can be a value + of @ref HASH_Algo_Selection */ + uint32_t HASH_AlgoMode; /*!< HASH or HMAC. This parameter can be a value + of @ref HASH_processor_Algorithm_Mode */ + uint32_t HASH_DataType; /*!< 32-bit data, 16-bit data, 8-bit data or + bit-string. This parameter can be a value of + @ref HASH_Data_Type */ + uint32_t HASH_HMACKeyType; /*!< HMAC Short key or HMAC Long Key. This parameter + can be a value of @ref HASH_HMAC_Long_key_only_for_HMAC_mode */ +}HASH_InitTypeDef; + +/** + * @brief HASH message digest result structure definition + */ +typedef struct +{ + uint32_t Data[5]; /*!< Message digest result : 5x 32bit words for SHA1 or + 4x 32bit words for MD5 */ +} HASH_MsgDigest; + +/** + * @brief HASH context swapping structure definition + */ +typedef struct +{ + uint32_t HASH_IMR; + uint32_t HASH_STR; + uint32_t HASH_CR; + uint32_t HASH_CSR[51]; +}HASH_Context; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup HASH_Exported_Constants + * @{ + */ + +/** @defgroup HASH_Algo_Selection + * @{ + */ +#define HASH_AlgoSelection_SHA1 ((uint16_t)0x0000) /*!< HASH function is SHA1 */ +#define HASH_AlgoSelection_MD5 ((uint16_t)0x0080) /*!< HASH function is MD5 */ + +#define IS_HASH_ALGOSELECTION(ALGOSELECTION) (((ALGOSELECTION) == HASH_AlgoSelection_SHA1) || \ + ((ALGOSELECTION) == HASH_AlgoSelection_MD5)) +/** + * @} + */ + +/** @defgroup HASH_processor_Algorithm_Mode + * @{ + */ +#define HASH_AlgoMode_HASH ((uint16_t)0x0000) /*!< Algorithm is HASH */ +#define HASH_AlgoMode_HMAC ((uint16_t)0x0040) /*!< Algorithm is HMAC */ + +#define IS_HASH_ALGOMODE(ALGOMODE) (((ALGOMODE) == HASH_AlgoMode_HASH) || \ + ((ALGOMODE) == HASH_AlgoMode_HMAC)) +/** + * @} + */ + +/** @defgroup HASH_Data_Type + * @{ + */ +#define HASH_DataType_32b ((uint16_t)0x0000) +#define HASH_DataType_16b ((uint16_t)0x0010) +#define HASH_DataType_8b ((uint16_t)0x0020) +#define HASH_DataType_1b ((uint16_t)0x0030) + +#define IS_HASH_DATATYPE(DATATYPE) (((DATATYPE) == HASH_DataType_32b)|| \ + ((DATATYPE) == HASH_DataType_16b)|| \ + ((DATATYPE) == HASH_DataType_8b)|| \ + ((DATATYPE) == HASH_DataType_1b)) +/** + * @} + */ + +/** @defgroup HASH_HMAC_Long_key_only_for_HMAC_mode + * @{ + */ +#define HASH_HMACKeyType_ShortKey ((uint32_t)0x00000000) /*!< HMAC Key is <= 64 bytes */ +#define HASH_HMACKeyType_LongKey ((uint32_t)0x00010000) /*!< HMAC Key is > 64 bytes */ + +#define IS_HASH_HMAC_KEYTYPE(KEYTYPE) (((KEYTYPE) == HASH_HMACKeyType_ShortKey) || \ + ((KEYTYPE) == HASH_HMACKeyType_LongKey)) +/** + * @} + */ + +/** @defgroup Number_of_valid_bits_in_last_word_of_the_message + * @{ + */ +#define IS_HASH_VALIDBITSNUMBER(VALIDBITS) ((VALIDBITS) <= 0x1F) + +/** + * @} + */ + +/** @defgroup HASH_interrupts_definition + * @{ + */ +#define HASH_IT_DINI ((uint8_t)0x01) /*!< A new block can be entered into the input buffer (DIN)*/ +#define HASH_IT_DCI ((uint8_t)0x02) /*!< Digest calculation complete */ + +#define IS_HASH_IT(IT) ((((IT) & (uint8_t)0xFC) == 0x00) && ((IT) != 0x00)) +#define IS_HASH_GET_IT(IT) (((IT) == HASH_IT_DINI) || ((IT) == HASH_IT_DCI)) + +/** + * @} + */ + +/** @defgroup HASH_flags_definition + * @{ + */ +#define HASH_FLAG_DINIS ((uint16_t)0x0001) /*!< 16 locations are free in the DIN : A new block can be entered into the input buffer.*/ +#define HASH_FLAG_DCIS ((uint16_t)0x0002) /*!< Digest calculation complete */ +#define HASH_FLAG_DMAS ((uint16_t)0x0004) /*!< DMA interface is enabled (DMAE=1) or a transfer is ongoing */ +#define HASH_FLAG_BUSY ((uint16_t)0x0008) /*!< The hash core is Busy : processing a block of data */ +#define HASH_FLAG_DINNE ((uint16_t)0x1000) /*!< DIN not empty : The input buffer contains at least one word of data */ + +#define IS_HASH_GET_FLAG(FLAG) (((FLAG) == HASH_FLAG_DINIS) || \ + ((FLAG) == HASH_FLAG_DCIS) || \ + ((FLAG) == HASH_FLAG_DMAS) || \ + ((FLAG) == HASH_FLAG_BUSY) || \ + ((FLAG) == HASH_FLAG_DINNE)) + +#define IS_HASH_CLEAR_FLAG(FLAG)(((FLAG) == HASH_FLAG_DINIS) || \ + ((FLAG) == HASH_FLAG_DCIS)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the HASH configuration to the default reset state ****/ +void HASH_DeInit(void); + +/* HASH Configuration function ************************************************/ +void HASH_Init(HASH_InitTypeDef* HASH_InitStruct); +void HASH_StructInit(HASH_InitTypeDef* HASH_InitStruct); +void HASH_Reset(void); + +/* HASH Message Digest generation functions ***********************************/ +void HASH_DataIn(uint32_t Data); +uint8_t HASH_GetInFIFOWordsNbr(void); +void HASH_SetLastWordValidBitsNbr(uint16_t ValidNumber); +void HASH_StartDigest(void); +void HASH_GetDigest(HASH_MsgDigest* HASH_MessageDigest); + +/* HASH Context swapping functions ********************************************/ +void HASH_SaveContext(HASH_Context* HASH_ContextSave); +void HASH_RestoreContext(HASH_Context* HASH_ContextRestore); + +/* HASH's DMA interface function **********************************************/ +void HASH_DMACmd(FunctionalState NewState); + +/* HASH Interrupts and flags management functions *****************************/ +void HASH_ITConfig(uint8_t HASH_IT, FunctionalState NewState); +FlagStatus HASH_GetFlagStatus(uint16_t HASH_FLAG); +void HASH_ClearFlag(uint16_t HASH_FLAG); +ITStatus HASH_GetITStatus(uint8_t HASH_IT); +void HASH_ClearITPendingBit(uint8_t HASH_IT); + +/* High Level SHA1 functions **************************************************/ +ErrorStatus HASH_SHA1(uint8_t *Input, uint32_t Ilen, uint8_t Output[20]); +ErrorStatus HMAC_SHA1(uint8_t *Key, uint32_t Keylen, + uint8_t *Input, uint32_t Ilen, + uint8_t Output[20]); + +/* High Level MD5 functions ***************************************************/ +ErrorStatus HASH_MD5(uint8_t *Input, uint32_t Ilen, uint8_t Output[16]); +ErrorStatus HMAC_MD5(uint8_t *Key, uint32_t Keylen, + uint8_t *Input, uint32_t Ilen, + uint8_t Output[16]); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_HASH_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h new file mode 100644 index 0000000..ea5e36d --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h @@ -0,0 +1,692 @@ +/** + ****************************************************************************** + * @file stm32f4xx_i2c.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the I2C firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_I2C_H +#define __STM32F4xx_I2C_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup I2C + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief I2C Init structure definition + */ + +typedef struct +{ + uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency. + This parameter must be set to a value lower than 400kHz */ + + uint16_t I2C_Mode; /*!< Specifies the I2C mode. + This parameter can be a value of @ref I2C_mode */ + + uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle. + This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ + + uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address. + This parameter can be a 7-bit or 10-bit address. */ + + uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement. + This parameter can be a value of @ref I2C_acknowledgement */ + + uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged. + This parameter can be a value of @ref I2C_acknowledged_address */ +}I2C_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + + +/** @defgroup I2C_Exported_Constants + * @{ + */ + +#define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C1) || \ + ((PERIPH) == I2C2) || \ + ((PERIPH) == I2C3)) +/** @defgroup I2C_mode + * @{ + */ + +#define I2C_Mode_I2C ((uint16_t)0x0000) +#define I2C_Mode_SMBusDevice ((uint16_t)0x0002) +#define I2C_Mode_SMBusHost ((uint16_t)0x000A) +#define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \ + ((MODE) == I2C_Mode_SMBusDevice) || \ + ((MODE) == I2C_Mode_SMBusHost)) +/** + * @} + */ + +/** @defgroup I2C_duty_cycle_in_fast_mode + * @{ + */ + +#define I2C_DutyCycle_16_9 ((uint16_t)0x4000) /*!< I2C fast mode Tlow/Thigh = 16/9 */ +#define I2C_DutyCycle_2 ((uint16_t)0xBFFF) /*!< I2C fast mode Tlow/Thigh = 2 */ +#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DutyCycle_16_9) || \ + ((CYCLE) == I2C_DutyCycle_2)) +/** + * @} + */ + +/** @defgroup I2C_acknowledgement + * @{ + */ + +#define I2C_Ack_Enable ((uint16_t)0x0400) +#define I2C_Ack_Disable ((uint16_t)0x0000) +#define IS_I2C_ACK_STATE(STATE) (((STATE) == I2C_Ack_Enable) || \ + ((STATE) == I2C_Ack_Disable)) +/** + * @} + */ + +/** @defgroup I2C_transfer_direction + * @{ + */ + +#define I2C_Direction_Transmitter ((uint8_t)0x00) +#define I2C_Direction_Receiver ((uint8_t)0x01) +#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \ + ((DIRECTION) == I2C_Direction_Receiver)) +/** + * @} + */ + +/** @defgroup I2C_acknowledged_address + * @{ + */ + +#define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000) +#define I2C_AcknowledgedAddress_10bit ((uint16_t)0xC000) +#define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \ + ((ADDRESS) == I2C_AcknowledgedAddress_10bit)) +/** + * @} + */ + +/** @defgroup I2C_registers + * @{ + */ + +#define I2C_Register_CR1 ((uint8_t)0x00) +#define I2C_Register_CR2 ((uint8_t)0x04) +#define I2C_Register_OAR1 ((uint8_t)0x08) +#define I2C_Register_OAR2 ((uint8_t)0x0C) +#define I2C_Register_DR ((uint8_t)0x10) +#define I2C_Register_SR1 ((uint8_t)0x14) +#define I2C_Register_SR2 ((uint8_t)0x18) +#define I2C_Register_CCR ((uint8_t)0x1C) +#define I2C_Register_TRISE ((uint8_t)0x20) +#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \ + ((REGISTER) == I2C_Register_CR2) || \ + ((REGISTER) == I2C_Register_OAR1) || \ + ((REGISTER) == I2C_Register_OAR2) || \ + ((REGISTER) == I2C_Register_DR) || \ + ((REGISTER) == I2C_Register_SR1) || \ + ((REGISTER) == I2C_Register_SR2) || \ + ((REGISTER) == I2C_Register_CCR) || \ + ((REGISTER) == I2C_Register_TRISE)) +/** + * @} + */ + +/** @defgroup I2C_NACK_position + * @{ + */ + +#define I2C_NACKPosition_Next ((uint16_t)0x0800) +#define I2C_NACKPosition_Current ((uint16_t)0xF7FF) +#define IS_I2C_NACK_POSITION(POSITION) (((POSITION) == I2C_NACKPosition_Next) || \ + ((POSITION) == I2C_NACKPosition_Current)) +/** + * @} + */ + +/** @defgroup I2C_SMBus_alert_pin_level + * @{ + */ + +#define I2C_SMBusAlert_Low ((uint16_t)0x2000) +#define I2C_SMBusAlert_High ((uint16_t)0xDFFF) +#define IS_I2C_SMBUS_ALERT(ALERT) (((ALERT) == I2C_SMBusAlert_Low) || \ + ((ALERT) == I2C_SMBusAlert_High)) +/** + * @} + */ + +/** @defgroup I2C_PEC_position + * @{ + */ + +#define I2C_PECPosition_Next ((uint16_t)0x0800) +#define I2C_PECPosition_Current ((uint16_t)0xF7FF) +#define IS_I2C_PEC_POSITION(POSITION) (((POSITION) == I2C_PECPosition_Next) || \ + ((POSITION) == I2C_PECPosition_Current)) +/** + * @} + */ + +/** @defgroup I2C_interrupts_definition + * @{ + */ + +#define I2C_IT_BUF ((uint16_t)0x0400) +#define I2C_IT_EVT ((uint16_t)0x0200) +#define I2C_IT_ERR ((uint16_t)0x0100) +#define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint16_t)0xF8FF) == 0x00) && ((IT) != 0x00)) +/** + * @} + */ + +/** @defgroup I2C_interrupts_definition + * @{ + */ + +#define I2C_IT_SMBALERT ((uint32_t)0x01008000) +#define I2C_IT_TIMEOUT ((uint32_t)0x01004000) +#define I2C_IT_PECERR ((uint32_t)0x01001000) +#define I2C_IT_OVR ((uint32_t)0x01000800) +#define I2C_IT_AF ((uint32_t)0x01000400) +#define I2C_IT_ARLO ((uint32_t)0x01000200) +#define I2C_IT_BERR ((uint32_t)0x01000100) +#define I2C_IT_TXE ((uint32_t)0x06000080) +#define I2C_IT_RXNE ((uint32_t)0x06000040) +#define I2C_IT_STOPF ((uint32_t)0x02000010) +#define I2C_IT_ADD10 ((uint32_t)0x02000008) +#define I2C_IT_BTF ((uint32_t)0x02000004) +#define I2C_IT_ADDR ((uint32_t)0x02000002) +#define I2C_IT_SB ((uint32_t)0x02000001) + +#define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint16_t)0x20FF) == 0x00) && ((IT) != (uint16_t)0x00)) + +#define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \ + ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \ + ((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \ + ((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_TXE) || \ + ((IT) == I2C_IT_RXNE) || ((IT) == I2C_IT_STOPF) || \ + ((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \ + ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB)) +/** + * @} + */ + +/** @defgroup I2C_flags_definition + * @{ + */ + +/** + * @brief SR2 register flags + */ + +#define I2C_FLAG_DUALF ((uint32_t)0x00800000) +#define I2C_FLAG_SMBHOST ((uint32_t)0x00400000) +#define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000) +#define I2C_FLAG_GENCALL ((uint32_t)0x00100000) +#define I2C_FLAG_TRA ((uint32_t)0x00040000) +#define I2C_FLAG_BUSY ((uint32_t)0x00020000) +#define I2C_FLAG_MSL ((uint32_t)0x00010000) + +/** + * @brief SR1 register flags + */ + +#define I2C_FLAG_SMBALERT ((uint32_t)0x10008000) +#define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000) +#define I2C_FLAG_PECERR ((uint32_t)0x10001000) +#define I2C_FLAG_OVR ((uint32_t)0x10000800) +#define I2C_FLAG_AF ((uint32_t)0x10000400) +#define I2C_FLAG_ARLO ((uint32_t)0x10000200) +#define I2C_FLAG_BERR ((uint32_t)0x10000100) +#define I2C_FLAG_TXE ((uint32_t)0x10000080) +#define I2C_FLAG_RXNE ((uint32_t)0x10000040) +#define I2C_FLAG_STOPF ((uint32_t)0x10000010) +#define I2C_FLAG_ADD10 ((uint32_t)0x10000008) +#define I2C_FLAG_BTF ((uint32_t)0x10000004) +#define I2C_FLAG_ADDR ((uint32_t)0x10000002) +#define I2C_FLAG_SB ((uint32_t)0x10000001) + +#define IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0x20FF) == 0x00) && ((FLAG) != (uint16_t)0x00)) + +#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_DUALF) || ((FLAG) == I2C_FLAG_SMBHOST) || \ + ((FLAG) == I2C_FLAG_SMBDEFAULT) || ((FLAG) == I2C_FLAG_GENCALL) || \ + ((FLAG) == I2C_FLAG_TRA) || ((FLAG) == I2C_FLAG_BUSY) || \ + ((FLAG) == I2C_FLAG_MSL) || ((FLAG) == I2C_FLAG_SMBALERT) || \ + ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_PECERR) || \ + ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_AF) || \ + ((FLAG) == I2C_FLAG_ARLO) || ((FLAG) == I2C_FLAG_BERR) || \ + ((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_RXNE) || \ + ((FLAG) == I2C_FLAG_STOPF) || ((FLAG) == I2C_FLAG_ADD10) || \ + ((FLAG) == I2C_FLAG_BTF) || ((FLAG) == I2C_FLAG_ADDR) || \ + ((FLAG) == I2C_FLAG_SB)) +/** + * @} + */ + +/** @defgroup I2C_Events + * @{ + */ + +/** + =============================================================================== + I2C Master Events (Events grouped in order of communication) + =============================================================================== + */ + +/** + * @brief Communication start + * + * After sending the START condition (I2C_GenerateSTART() function) the master + * has to wait for this event. It means that the Start condition has been correctly + * released on the I2C bus (the bus is free, no other devices is communicating). + * + */ +/* --EV5 */ +#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */ + +/** + * @brief Address Acknowledge + * + * After checking on EV5 (start condition correctly released on the bus), the + * master sends the address of the slave(s) with which it will communicate + * (I2C_Send7bitAddress() function, it also determines the direction of the communication: + * Master transmitter or Receiver). Then the master has to wait that a slave acknowledges + * his address. If an acknowledge is sent on the bus, one of the following events will + * be set: + * + * 1) In case of Master Receiver (7-bit addressing): the I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED + * event is set. + * + * 2) In case of Master Transmitter (7-bit addressing): the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED + * is set + * + * 3) In case of 10-Bit addressing mode, the master (just after generating the START + * and checking on EV5) has to send the header of 10-bit addressing mode (I2C_SendData() + * function). Then master should wait on EV9. It means that the 10-bit addressing + * header has been correctly sent on the bus. Then master should send the second part of + * the 10-bit address (LSB) using the function I2C_Send7bitAddress(). Then master + * should wait for event EV6. + * + */ + +/* --EV6 */ +#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */ +#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */ +/* --EV9 */ +#define I2C_EVENT_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */ + +/** + * @brief Communication events + * + * If a communication is established (START condition generated and slave address + * acknowledged) then the master has to check on one of the following events for + * communication procedures: + * + * 1) Master Receiver mode: The master has to wait on the event EV7 then to read + * the data received from the slave (I2C_ReceiveData() function). + * + * 2) Master Transmitter mode: The master has to send data (I2C_SendData() + * function) then to wait on event EV8 or EV8_2. + * These two events are similar: + * - EV8 means that the data has been written in the data register and is + * being shifted out. + * - EV8_2 means that the data has been physically shifted out and output + * on the bus. + * In most cases, using EV8 is sufficient for the application. + * Using EV8_2 leads to a slower communication but ensure more reliable test. + * EV8_2 is also more suitable than EV8 for testing on the last data transmission + * (before Stop condition generation). + * + * @note In case the user software does not guarantee that this event EV7 is + * managed before the current byte end of transfer, then user may check on EV7 + * and BTF flag at the same time (ie. (I2C_EVENT_MASTER_BYTE_RECEIVED | I2C_FLAG_BTF)). + * In this case the communication may be slower. + * + */ + +/* Master RECEIVER mode -----------------------------*/ +/* --EV7 */ +#define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */ + +/* Master TRANSMITTER mode --------------------------*/ +/* --EV8 */ +#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */ +/* --EV8_2 */ +#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */ + + +/** + =============================================================================== + I2C Slave Events (Events grouped in order of communication) + =============================================================================== + */ + + +/** + * @brief Communication start events + * + * Wait on one of these events at the start of the communication. It means that + * the I2C peripheral detected a Start condition on the bus (generated by master + * device) followed by the peripheral address. The peripheral generates an ACK + * condition on the bus (if the acknowledge feature is enabled through function + * I2C_AcknowledgeConfig()) and the events listed above are set : + * + * 1) In normal case (only one address managed by the slave), when the address + * sent by the master matches the own address of the peripheral (configured by + * I2C_OwnAddress1 field) the I2C_EVENT_SLAVE_XXX_ADDRESS_MATCHED event is set + * (where XXX could be TRANSMITTER or RECEIVER). + * + * 2) In case the address sent by the master matches the second address of the + * peripheral (configured by the function I2C_OwnAddress2Config() and enabled + * by the function I2C_DualAddressCmd()) the events I2C_EVENT_SLAVE_XXX_SECONDADDRESS_MATCHED + * (where XXX could be TRANSMITTER or RECEIVER) are set. + * + * 3) In case the address sent by the master is General Call (address 0x00) and + * if the General Call is enabled for the peripheral (using function I2C_GeneralCallCmd()) + * the following event is set I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED. + * + */ + +/* --EV1 (all the events below are variants of EV1) */ +/* 1) Case of One Single Address managed by the slave */ +#define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY and ADDR flags */ +#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE and ADDR flags */ + +/* 2) Case of Dual address managed by the slave */ +#define I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED ((uint32_t)0x00820000) /* DUALF and BUSY flags */ +#define I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED ((uint32_t)0x00860080) /* DUALF, TRA, BUSY and TXE flags */ + +/* 3) Case of General Call enabled for the slave */ +#define I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED ((uint32_t)0x00120000) /* GENCALL and BUSY flags */ + +/** + * @brief Communication events + * + * Wait on one of these events when EV1 has already been checked and: + * + * - Slave RECEIVER mode: + * - EV2: When the application is expecting a data byte to be received. + * - EV4: When the application is expecting the end of the communication: master + * sends a stop condition and data transmission is stopped. + * + * - Slave Transmitter mode: + * - EV3: When a byte has been transmitted by the slave and the application is expecting + * the end of the byte transmission. The two events I2C_EVENT_SLAVE_BYTE_TRANSMITTED and + * I2C_EVENT_SLAVE_BYTE_TRANSMITTING are similar. The second one can optionally be + * used when the user software doesn't guarantee the EV3 is managed before the + * current byte end of transfer. + * - EV3_2: When the master sends a NACK in order to tell slave that data transmission + * shall end (before sending the STOP condition). In this case slave has to stop sending + * data bytes and expect a Stop condition on the bus. + * + * @note In case the user software does not guarantee that the event EV2 is + * managed before the current byte end of transfer, then user may check on EV2 + * and BTF flag at the same time (ie. (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_BTF)). + * In this case the communication may be slower. + * + */ + +/* Slave RECEIVER mode --------------------------*/ +/* --EV2 */ +#define I2C_EVENT_SLAVE_BYTE_RECEIVED ((uint32_t)0x00020040) /* BUSY and RXNE flags */ +/* --EV4 */ +#define I2C_EVENT_SLAVE_STOP_DETECTED ((uint32_t)0x00000010) /* STOPF flag */ + +/* Slave TRANSMITTER mode -----------------------*/ +/* --EV3 */ +#define I2C_EVENT_SLAVE_BYTE_TRANSMITTED ((uint32_t)0x00060084) /* TRA, BUSY, TXE and BTF flags */ +#define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY and TXE flags */ +/* --EV3_2 */ +#define I2C_EVENT_SLAVE_ACK_FAILURE ((uint32_t)0x00000400) /* AF flag */ + +/* + =============================================================================== + End of Events Description + =============================================================================== + */ + +#define IS_I2C_EVENT(EVENT) (((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_BYTE_RECEIVED) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF)) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL)) || \ + ((EVENT) == I2C_EVENT_SLAVE_BYTE_TRANSMITTED) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL)) || \ + ((EVENT) == I2C_EVENT_SLAVE_STOP_DETECTED) || \ + ((EVENT) == I2C_EVENT_MASTER_MODE_SELECT) || \ + ((EVENT) == I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) || \ + ((EVENT) == I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) || \ + ((EVENT) == I2C_EVENT_MASTER_BYTE_RECEIVED) || \ + ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTED) || \ + ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTING) || \ + ((EVENT) == I2C_EVENT_MASTER_MODE_ADDRESS10) || \ + ((EVENT) == I2C_EVENT_SLAVE_ACK_FAILURE)) +/** + * @} + */ + +/** @defgroup I2C_own_address1 + * @{ + */ + +#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x3FF) +/** + * @} + */ + +/** @defgroup I2C_clock_speed + * @{ + */ + +#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) >= 0x1) && ((SPEED) <= 400000)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the I2C configuration to the default reset state *****/ +void I2C_DeInit(I2C_TypeDef* I2Cx); + +/* Initialization and Configuration functions *********************************/ +void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct); +void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct); +void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction); +void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address); +void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle); +void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition); +void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert); +void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); + +/* Data transfers functions ***************************************************/ +void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data); +uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx); + +/* PEC management functions ***************************************************/ +void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition); +void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState); +uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx); + +/* DMA transfers management functions *****************************************/ +void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); + +/* Interrupts, events and flags management functions **************************/ +uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register); +void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState); + +/* + =============================================================================== + I2C State Monitoring Functions + =============================================================================== + This I2C driver provides three different ways for I2C state monitoring + depending on the application requirements and constraints: + + + 1. Basic state monitoring (Using I2C_CheckEvent() function) + ----------------------------------------------------------- + It compares the status registers (SR1 and SR2) content to a given event + (can be the combination of one or more flags). + It returns SUCCESS if the current status includes the given flags + and returns ERROR if one or more flags are missing in the current status. + + - When to use + - This function is suitable for most applications as well as for startup + activity since the events are fully described in the product reference + manual (RM0090). + - It is also suitable for users who need to define their own events. + + - Limitations + - If an error occurs (ie. error flags are set besides to the monitored + flags), the I2C_CheckEvent() function may return SUCCESS despite + the communication hold or corrupted real state. + In this case, it is advised to use error interrupts to monitor + the error events and handle them in the interrupt IRQ handler. + + Note + For error management, it is advised to use the following functions: + - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). + - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs. + Where x is the peripheral instance (I2C1, I2C2 ...) + - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the + I2Cx_ER_IRQHandler() function in order to determine which error occurred. + - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() + and/or I2C_GenerateStop() in order to clear the error flag and source + and return to correct communication status. + + + 2. Advanced state monitoring (Using the function I2C_GetLastEvent()) + -------------------------------------------------------------------- + Using the function I2C_GetLastEvent() which returns the image of both status + registers in a single word (uint32_t) (Status Register 2 value is shifted left + by 16 bits and concatenated to Status Register 1). + + - When to use + - This function is suitable for the same applications above but it + allows to overcome the mentioned limitation of I2C_GetFlagStatus() + function. + - The returned value could be compared to events already defined in + this file or to custom values defined by user. + This function is suitable when multiple flags are monitored at the + same time. + - At the opposite of I2C_CheckEvent() function, this function allows + user to choose when an event is accepted (when all events flags are + set and no other flags are set or just when the needed flags are set + like I2C_CheckEvent() function. + + - Limitations + - User may need to define his own events. + - Same remark concerning the error management is applicable for this + function if user decides to check only regular communication flags + (and ignores error flags). + + + 3. Flag-based state monitoring (Using the function I2C_GetFlagStatus()) + ----------------------------------------------------------------------- + + Using the function I2C_GetFlagStatus() which simply returns the status of + one single flag (ie. I2C_FLAG_RXNE ...). + + - When to use + - This function could be used for specific applications or in debug + phase. + - It is suitable when only one flag checking is needed (most I2C + events are monitored through multiple flags). + - Limitations: + - When calling this function, the Status register is accessed. + Some flags are cleared when the status register is accessed. + So checking the status of one Flag, may clear other ones. + - Function may need to be called twice or more in order to monitor + one single event. + */ + +/* + =============================================================================== + 1. Basic state monitoring + =============================================================================== + */ +ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT); +/* + =============================================================================== + 2. Advanced state monitoring + =============================================================================== + */ +uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx); +/* + =============================================================================== + 3. Flag-based state monitoring + =============================================================================== + */ +FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); + + +void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); +ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT); +void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_I2C_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_iwdg.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_iwdg.h new file mode 100644 index 0000000..fd5deb5 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_iwdg.h @@ -0,0 +1,125 @@ +/** + ****************************************************************************** + * @file stm32f4xx_iwdg.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the IWDG + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_IWDG_H +#define __STM32F4xx_IWDG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup IWDG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup IWDG_Exported_Constants + * @{ + */ + +/** @defgroup IWDG_WriteAccess + * @{ + */ +#define IWDG_WriteAccess_Enable ((uint16_t)0x5555) +#define IWDG_WriteAccess_Disable ((uint16_t)0x0000) +#define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \ + ((ACCESS) == IWDG_WriteAccess_Disable)) +/** + * @} + */ + +/** @defgroup IWDG_prescaler + * @{ + */ +#define IWDG_Prescaler_4 ((uint8_t)0x00) +#define IWDG_Prescaler_8 ((uint8_t)0x01) +#define IWDG_Prescaler_16 ((uint8_t)0x02) +#define IWDG_Prescaler_32 ((uint8_t)0x03) +#define IWDG_Prescaler_64 ((uint8_t)0x04) +#define IWDG_Prescaler_128 ((uint8_t)0x05) +#define IWDG_Prescaler_256 ((uint8_t)0x06) +#define IS_IWDG_PRESCALER(PRESCALER) (((PRESCALER) == IWDG_Prescaler_4) || \ + ((PRESCALER) == IWDG_Prescaler_8) || \ + ((PRESCALER) == IWDG_Prescaler_16) || \ + ((PRESCALER) == IWDG_Prescaler_32) || \ + ((PRESCALER) == IWDG_Prescaler_64) || \ + ((PRESCALER) == IWDG_Prescaler_128)|| \ + ((PRESCALER) == IWDG_Prescaler_256)) +/** + * @} + */ + +/** @defgroup IWDG_Flag + * @{ + */ +#define IWDG_FLAG_PVU ((uint16_t)0x0001) +#define IWDG_FLAG_RVU ((uint16_t)0x0002) +#define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU)) +#define IS_IWDG_RELOAD(RELOAD) ((RELOAD) <= 0xFFF) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Prescaler and Counter configuration functions ******************************/ +void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); +void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); +void IWDG_SetReload(uint16_t Reload); +void IWDG_ReloadCounter(void); + +/* IWDG activation function ***************************************************/ +void IWDG_Enable(void); + +/* Flag management function ***************************************************/ +FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_IWDG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h new file mode 100644 index 0000000..8f47984 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h @@ -0,0 +1,179 @@ +/** + ****************************************************************************** + * @file stm32f4xx_pwr.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the PWR firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_PWR_H +#define __STM32F4xx_PWR_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup PWR + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Constants + * @{ + */ + +/** @defgroup PWR_PVD_detection_level + * @{ + */ + +#define PWR_PVDLevel_0 PWR_CR_PLS_LEV0 +#define PWR_PVDLevel_1 PWR_CR_PLS_LEV1 +#define PWR_PVDLevel_2 PWR_CR_PLS_LEV2 +#define PWR_PVDLevel_3 PWR_CR_PLS_LEV3 +#define PWR_PVDLevel_4 PWR_CR_PLS_LEV4 +#define PWR_PVDLevel_5 PWR_CR_PLS_LEV5 +#define PWR_PVDLevel_6 PWR_CR_PLS_LEV6 +#define PWR_PVDLevel_7 PWR_CR_PLS_LEV7 + +#define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLevel_0) || ((LEVEL) == PWR_PVDLevel_1)|| \ + ((LEVEL) == PWR_PVDLevel_2) || ((LEVEL) == PWR_PVDLevel_3)|| \ + ((LEVEL) == PWR_PVDLevel_4) || ((LEVEL) == PWR_PVDLevel_5)|| \ + ((LEVEL) == PWR_PVDLevel_6) || ((LEVEL) == PWR_PVDLevel_7)) +/** + * @} + */ + + +/** @defgroup PWR_Regulator_state_in_STOP_mode + * @{ + */ + +#define PWR_Regulator_ON ((uint32_t)0x00000000) +#define PWR_Regulator_LowPower PWR_CR_LPDS +#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_Regulator_ON) || \ + ((REGULATOR) == PWR_Regulator_LowPower)) +/** + * @} + */ + +/** @defgroup PWR_STOP_mode_entry + * @{ + */ + +#define PWR_STOPEntry_WFI ((uint8_t)0x01) +#define PWR_STOPEntry_WFE ((uint8_t)0x02) +#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPEntry_WFI) || ((ENTRY) == PWR_STOPEntry_WFE)) + +/** @defgroup PWR_Regulator_Voltage_Scale + * @{ + */ + +#define PWR_Regulator_Voltage_Scale1 ((uint32_t)0x00004000) +#define PWR_Regulator_Voltage_Scale2 ((uint32_t)0x00000000) +#define IS_PWR_REGULATOR_VOLTAGE(VOLTAGE) (((VOLTAGE) == PWR_Regulator_Voltage_Scale1) || ((VOLTAGE) == PWR_Regulator_Voltage_Scale2)) + +/** + * @} + */ + +/** @defgroup PWR_Flag + * @{ + */ + +#define PWR_FLAG_WU PWR_CSR_WUF +#define PWR_FLAG_SB PWR_CSR_SBF +#define PWR_FLAG_PVDO PWR_CSR_PVDO +#define PWR_FLAG_BRR PWR_CSR_BRR +#define PWR_FLAG_VOSRDY PWR_CSR_VOSRDY + +/** @defgroup PWR_Flag_Legacy + * @{ + */ +#define PWR_FLAG_REGRDY PWR_FLAG_VOSRDY +/** + * @} + */ + +#define IS_PWR_GET_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB) || \ + ((FLAG) == PWR_FLAG_PVDO) || ((FLAG) == PWR_FLAG_BRR) || \ + ((FLAG) == PWR_FLAG_VOSRDY)) + +#define IS_PWR_CLEAR_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the PWR configuration to the default reset state ******/ +void PWR_DeInit(void); + +/* Backup Domain Access function **********************************************/ +void PWR_BackupAccessCmd(FunctionalState NewState); + +/* PVD configuration functions ************************************************/ +void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel); +void PWR_PVDCmd(FunctionalState NewState); + +/* WakeUp pins configuration functions ****************************************/ +void PWR_WakeUpPinCmd(FunctionalState NewState); + +/* Main and Backup Regulators configuration functions *************************/ +void PWR_BackupRegulatorCmd(FunctionalState NewState); +void PWR_MainRegulatorModeConfig(uint32_t PWR_Regulator_Voltage); + +/* FLASH Power Down configuration functions ***********************************/ +void PWR_FlashPowerDownCmd(FunctionalState NewState); + +/* Low Power modes configuration functions ************************************/ +void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry); +void PWR_EnterSTANDBYMode(void); + +/* Flags management functions *************************************************/ +FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG); +void PWR_ClearFlag(uint32_t PWR_FLAG); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_PWR_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h new file mode 100644 index 0000000..f06b643 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h @@ -0,0 +1,510 @@ +/** + ****************************************************************************** + * @file stm32f4xx_rcc.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the RCC firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_RCC_H +#define __STM32F4xx_RCC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup RCC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +typedef struct +{ + uint32_t SYSCLK_Frequency; /*!< SYSCLK clock frequency expressed in Hz */ + uint32_t HCLK_Frequency; /*!< HCLK clock frequency expressed in Hz */ + uint32_t PCLK1_Frequency; /*!< PCLK1 clock frequency expressed in Hz */ + uint32_t PCLK2_Frequency; /*!< PCLK2 clock frequency expressed in Hz */ +}RCC_ClocksTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Constants + * @{ + */ + +/** @defgroup RCC_HSE_configuration + * @{ + */ +#define RCC_HSE_OFF ((uint8_t)0x00) +#define RCC_HSE_ON ((uint8_t)0x01) +#define RCC_HSE_Bypass ((uint8_t)0x05) +#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || ((HSE) == RCC_HSE_ON) || \ + ((HSE) == RCC_HSE_Bypass)) +/** + * @} + */ + +/** @defgroup RCC_PLL_Clock_Source + * @{ + */ +#define RCC_PLLSource_HSI ((uint32_t)0x00000000) +#define RCC_PLLSource_HSE ((uint32_t)0x00400000) +#define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI) || \ + ((SOURCE) == RCC_PLLSource_HSE)) +#define IS_RCC_PLLM_VALUE(VALUE) ((VALUE) <= 63) +#define IS_RCC_PLLN_VALUE(VALUE) ((192 <= (VALUE)) && ((VALUE) <= 432)) +#define IS_RCC_PLLP_VALUE(VALUE) (((VALUE) == 2) || ((VALUE) == 4) || ((VALUE) == 6) || ((VALUE) == 8)) +#define IS_RCC_PLLQ_VALUE(VALUE) ((4 <= (VALUE)) && ((VALUE) <= 15)) + +#define IS_RCC_PLLI2SN_VALUE(VALUE) ((192 <= (VALUE)) && ((VALUE) <= 432)) +#define IS_RCC_PLLI2SR_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 7)) +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source + * @{ + */ +#define RCC_SYSCLKSource_HSI ((uint32_t)0x00000000) +#define RCC_SYSCLKSource_HSE ((uint32_t)0x00000001) +#define RCC_SYSCLKSource_PLLCLK ((uint32_t)0x00000002) +#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_HSI) || \ + ((SOURCE) == RCC_SYSCLKSource_HSE) || \ + ((SOURCE) == RCC_SYSCLKSource_PLLCLK)) +/** + * @} + */ + +/** @defgroup RCC_AHB_Clock_Source + * @{ + */ +#define RCC_SYSCLK_Div1 ((uint32_t)0x00000000) +#define RCC_SYSCLK_Div2 ((uint32_t)0x00000080) +#define RCC_SYSCLK_Div4 ((uint32_t)0x00000090) +#define RCC_SYSCLK_Div8 ((uint32_t)0x000000A0) +#define RCC_SYSCLK_Div16 ((uint32_t)0x000000B0) +#define RCC_SYSCLK_Div64 ((uint32_t)0x000000C0) +#define RCC_SYSCLK_Div128 ((uint32_t)0x000000D0) +#define RCC_SYSCLK_Div256 ((uint32_t)0x000000E0) +#define RCC_SYSCLK_Div512 ((uint32_t)0x000000F0) +#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_Div1) || ((HCLK) == RCC_SYSCLK_Div2) || \ + ((HCLK) == RCC_SYSCLK_Div4) || ((HCLK) == RCC_SYSCLK_Div8) || \ + ((HCLK) == RCC_SYSCLK_Div16) || ((HCLK) == RCC_SYSCLK_Div64) || \ + ((HCLK) == RCC_SYSCLK_Div128) || ((HCLK) == RCC_SYSCLK_Div256) || \ + ((HCLK) == RCC_SYSCLK_Div512)) +/** + * @} + */ + +/** @defgroup RCC_APB1_APB2_Clock_Source + * @{ + */ +#define RCC_HCLK_Div1 ((uint32_t)0x00000000) +#define RCC_HCLK_Div2 ((uint32_t)0x00001000) +#define RCC_HCLK_Div4 ((uint32_t)0x00001400) +#define RCC_HCLK_Div8 ((uint32_t)0x00001800) +#define RCC_HCLK_Div16 ((uint32_t)0x00001C00) +#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_Div1) || ((PCLK) == RCC_HCLK_Div2) || \ + ((PCLK) == RCC_HCLK_Div4) || ((PCLK) == RCC_HCLK_Div8) || \ + ((PCLK) == RCC_HCLK_Div16)) +/** + * @} + */ + +/** @defgroup RCC_Interrupt_Source + * @{ + */ +#define RCC_IT_LSIRDY ((uint8_t)0x01) +#define RCC_IT_LSERDY ((uint8_t)0x02) +#define RCC_IT_HSIRDY ((uint8_t)0x04) +#define RCC_IT_HSERDY ((uint8_t)0x08) +#define RCC_IT_PLLRDY ((uint8_t)0x10) +#define RCC_IT_PLLI2SRDY ((uint8_t)0x20) +#define RCC_IT_CSS ((uint8_t)0x80) +#define IS_RCC_IT(IT) ((((IT) & (uint8_t)0xC0) == 0x00) && ((IT) != 0x00)) +#define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \ + ((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \ + ((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_CSS) || \ + ((IT) == RCC_IT_PLLI2SRDY)) +#define IS_RCC_CLEAR_IT(IT) ((((IT) & (uint8_t)0x40) == 0x00) && ((IT) != 0x00)) +/** + * @} + */ + +/** @defgroup RCC_LSE_Configuration + * @{ + */ +#define RCC_LSE_OFF ((uint8_t)0x00) +#define RCC_LSE_ON ((uint8_t)0x01) +#define RCC_LSE_Bypass ((uint8_t)0x04) +#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \ + ((LSE) == RCC_LSE_Bypass)) +/** + * @} + */ + +/** @defgroup RCC_RTC_Clock_Source + * @{ + */ +#define RCC_RTCCLKSource_LSE ((uint32_t)0x00000100) +#define RCC_RTCCLKSource_LSI ((uint32_t)0x00000200) +#define RCC_RTCCLKSource_HSE_Div2 ((uint32_t)0x00020300) +#define RCC_RTCCLKSource_HSE_Div3 ((uint32_t)0x00030300) +#define RCC_RTCCLKSource_HSE_Div4 ((uint32_t)0x00040300) +#define RCC_RTCCLKSource_HSE_Div5 ((uint32_t)0x00050300) +#define RCC_RTCCLKSource_HSE_Div6 ((uint32_t)0x00060300) +#define RCC_RTCCLKSource_HSE_Div7 ((uint32_t)0x00070300) +#define RCC_RTCCLKSource_HSE_Div8 ((uint32_t)0x00080300) +#define RCC_RTCCLKSource_HSE_Div9 ((uint32_t)0x00090300) +#define RCC_RTCCLKSource_HSE_Div10 ((uint32_t)0x000A0300) +#define RCC_RTCCLKSource_HSE_Div11 ((uint32_t)0x000B0300) +#define RCC_RTCCLKSource_HSE_Div12 ((uint32_t)0x000C0300) +#define RCC_RTCCLKSource_HSE_Div13 ((uint32_t)0x000D0300) +#define RCC_RTCCLKSource_HSE_Div14 ((uint32_t)0x000E0300) +#define RCC_RTCCLKSource_HSE_Div15 ((uint32_t)0x000F0300) +#define RCC_RTCCLKSource_HSE_Div16 ((uint32_t)0x00100300) +#define RCC_RTCCLKSource_HSE_Div17 ((uint32_t)0x00110300) +#define RCC_RTCCLKSource_HSE_Div18 ((uint32_t)0x00120300) +#define RCC_RTCCLKSource_HSE_Div19 ((uint32_t)0x00130300) +#define RCC_RTCCLKSource_HSE_Div20 ((uint32_t)0x00140300) +#define RCC_RTCCLKSource_HSE_Div21 ((uint32_t)0x00150300) +#define RCC_RTCCLKSource_HSE_Div22 ((uint32_t)0x00160300) +#define RCC_RTCCLKSource_HSE_Div23 ((uint32_t)0x00170300) +#define RCC_RTCCLKSource_HSE_Div24 ((uint32_t)0x00180300) +#define RCC_RTCCLKSource_HSE_Div25 ((uint32_t)0x00190300) +#define RCC_RTCCLKSource_HSE_Div26 ((uint32_t)0x001A0300) +#define RCC_RTCCLKSource_HSE_Div27 ((uint32_t)0x001B0300) +#define RCC_RTCCLKSource_HSE_Div28 ((uint32_t)0x001C0300) +#define RCC_RTCCLKSource_HSE_Div29 ((uint32_t)0x001D0300) +#define RCC_RTCCLKSource_HSE_Div30 ((uint32_t)0x001E0300) +#define RCC_RTCCLKSource_HSE_Div31 ((uint32_t)0x001F0300) +#define IS_RCC_RTCCLK_SOURCE(SOURCE) (((SOURCE) == RCC_RTCCLKSource_LSE) || \ + ((SOURCE) == RCC_RTCCLKSource_LSI) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div2) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div3) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div4) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div5) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div6) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div7) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div8) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div9) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div10) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div11) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div12) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div13) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div14) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div15) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div16) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div17) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div18) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div19) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div20) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div21) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div22) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div23) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div24) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div25) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div26) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div27) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div28) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div29) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div30) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div31)) +/** + * @} + */ + +/** @defgroup RCC_I2S_Clock_Source + * @{ + */ +#define RCC_I2S2CLKSource_PLLI2S ((uint8_t)0x00) +#define RCC_I2S2CLKSource_Ext ((uint8_t)0x01) + +#define IS_RCC_I2SCLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2S2CLKSource_PLLI2S) || ((SOURCE) == RCC_I2S2CLKSource_Ext)) +/** + * @} + */ + +/** @defgroup RCC_AHB1_Peripherals + * @{ + */ +#define RCC_AHB1Periph_GPIOA ((uint32_t)0x00000001) +#define RCC_AHB1Periph_GPIOB ((uint32_t)0x00000002) +#define RCC_AHB1Periph_GPIOC ((uint32_t)0x00000004) +#define RCC_AHB1Periph_GPIOD ((uint32_t)0x00000008) +#define RCC_AHB1Periph_GPIOE ((uint32_t)0x00000010) +#define RCC_AHB1Periph_GPIOF ((uint32_t)0x00000020) +#define RCC_AHB1Periph_GPIOG ((uint32_t)0x00000040) +#define RCC_AHB1Periph_GPIOH ((uint32_t)0x00000080) +#define RCC_AHB1Periph_GPIOI ((uint32_t)0x00000100) +#define RCC_AHB1Periph_CRC ((uint32_t)0x00001000) +#define RCC_AHB1Periph_FLITF ((uint32_t)0x00008000) +#define RCC_AHB1Periph_SRAM1 ((uint32_t)0x00010000) +#define RCC_AHB1Periph_SRAM2 ((uint32_t)0x00020000) +#define RCC_AHB1Periph_BKPSRAM ((uint32_t)0x00040000) +#define RCC_AHB1Periph_CCMDATARAMEN ((uint32_t)0x00100000) +#define RCC_AHB1Periph_DMA1 ((uint32_t)0x00200000) +#define RCC_AHB1Periph_DMA2 ((uint32_t)0x00400000) +#define RCC_AHB1Periph_ETH_MAC ((uint32_t)0x02000000) +#define RCC_AHB1Periph_ETH_MAC_Tx ((uint32_t)0x04000000) +#define RCC_AHB1Periph_ETH_MAC_Rx ((uint32_t)0x08000000) +#define RCC_AHB1Periph_ETH_MAC_PTP ((uint32_t)0x10000000) +#define RCC_AHB1Periph_OTG_HS ((uint32_t)0x20000000) +#define RCC_AHB1Periph_OTG_HS_ULPI ((uint32_t)0x40000000) +#define IS_RCC_AHB1_CLOCK_PERIPH(PERIPH) ((((PERIPH) & 0x818BEE00) == 0x00) && ((PERIPH) != 0x00)) +#define IS_RCC_AHB1_RESET_PERIPH(PERIPH) ((((PERIPH) & 0xDD9FEE00) == 0x00) && ((PERIPH) != 0x00)) +#define IS_RCC_AHB1_LPMODE_PERIPH(PERIPH) ((((PERIPH) & 0x81986E00) == 0x00) && ((PERIPH) != 0x00)) +/** + * @} + */ + +/** @defgroup RCC_AHB2_Peripherals + * @{ + */ +#define RCC_AHB2Periph_DCMI ((uint32_t)0x00000001) +#define RCC_AHB2Periph_CRYP ((uint32_t)0x00000010) +#define RCC_AHB2Periph_HASH ((uint32_t)0x00000020) +#define RCC_AHB2Periph_RNG ((uint32_t)0x00000040) +#define RCC_AHB2Periph_OTG_FS ((uint32_t)0x00000080) +#define IS_RCC_AHB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFF0E) == 0x00) && ((PERIPH) != 0x00)) +/** + * @} + */ + +/** @defgroup RCC_AHB3_Peripherals + * @{ + */ +#define RCC_AHB3Periph_FSMC ((uint32_t)0x00000001) +#define IS_RCC_AHB3_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFFE) == 0x00) && ((PERIPH) != 0x00)) +/** + * @} + */ + +/** @defgroup RCC_APB1_Peripherals + * @{ + */ +#define RCC_APB1Periph_TIM2 ((uint32_t)0x00000001) +#define RCC_APB1Periph_TIM3 ((uint32_t)0x00000002) +#define RCC_APB1Periph_TIM4 ((uint32_t)0x00000004) +#define RCC_APB1Periph_TIM5 ((uint32_t)0x00000008) +#define RCC_APB1Periph_TIM6 ((uint32_t)0x00000010) +#define RCC_APB1Periph_TIM7 ((uint32_t)0x00000020) +#define RCC_APB1Periph_TIM12 ((uint32_t)0x00000040) +#define RCC_APB1Periph_TIM13 ((uint32_t)0x00000080) +#define RCC_APB1Periph_TIM14 ((uint32_t)0x00000100) +#define RCC_APB1Periph_WWDG ((uint32_t)0x00000800) +#define RCC_APB1Periph_SPI2 ((uint32_t)0x00004000) +#define RCC_APB1Periph_SPI3 ((uint32_t)0x00008000) +#define RCC_APB1Periph_USART2 ((uint32_t)0x00020000) +#define RCC_APB1Periph_USART3 ((uint32_t)0x00040000) +#define RCC_APB1Periph_UART4 ((uint32_t)0x00080000) +#define RCC_APB1Periph_UART5 ((uint32_t)0x00100000) +#define RCC_APB1Periph_I2C1 ((uint32_t)0x00200000) +#define RCC_APB1Periph_I2C2 ((uint32_t)0x00400000) +#define RCC_APB1Periph_I2C3 ((uint32_t)0x00800000) +#define RCC_APB1Periph_CAN1 ((uint32_t)0x02000000) +#define RCC_APB1Periph_CAN2 ((uint32_t)0x04000000) +#define RCC_APB1Periph_PWR ((uint32_t)0x10000000) +#define RCC_APB1Periph_DAC ((uint32_t)0x20000000) +#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0xC9013600) == 0x00) && ((PERIPH) != 0x00)) +/** + * @} + */ + +/** @defgroup RCC_APB2_Peripherals + * @{ + */ +#define RCC_APB2Periph_TIM1 ((uint32_t)0x00000001) +#define RCC_APB2Periph_TIM8 ((uint32_t)0x00000002) +#define RCC_APB2Periph_USART1 ((uint32_t)0x00000010) +#define RCC_APB2Periph_USART6 ((uint32_t)0x00000020) +#define RCC_APB2Periph_ADC ((uint32_t)0x00000100) +#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000100) +#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000200) +#define RCC_APB2Periph_ADC3 ((uint32_t)0x00000400) +#define RCC_APB2Periph_SDIO ((uint32_t)0x00000800) +#define RCC_APB2Periph_SPI1 ((uint32_t)0x00001000) +#define RCC_APB2Periph_SYSCFG ((uint32_t)0x00004000) +#define RCC_APB2Periph_TIM9 ((uint32_t)0x00010000) +#define RCC_APB2Periph_TIM10 ((uint32_t)0x00020000) +#define RCC_APB2Periph_TIM11 ((uint32_t)0x00040000) +#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFF8A0CC) == 0x00) && ((PERIPH) != 0x00)) +#define IS_RCC_APB2_RESET_PERIPH(PERIPH) ((((PERIPH) & 0xFFF8A6CC) == 0x00) && ((PERIPH) != 0x00)) +/** + * @} + */ + +/** @defgroup RCC_MCO1_Clock_Source_Prescaler + * @{ + */ +#define RCC_MCO1Source_HSI ((uint32_t)0x00000000) +#define RCC_MCO1Source_LSE ((uint32_t)0x00200000) +#define RCC_MCO1Source_HSE ((uint32_t)0x00400000) +#define RCC_MCO1Source_PLLCLK ((uint32_t)0x00600000) +#define RCC_MCO1Div_1 ((uint32_t)0x00000000) +#define RCC_MCO1Div_2 ((uint32_t)0x04000000) +#define RCC_MCO1Div_3 ((uint32_t)0x05000000) +#define RCC_MCO1Div_4 ((uint32_t)0x06000000) +#define RCC_MCO1Div_5 ((uint32_t)0x07000000) +#define IS_RCC_MCO1SOURCE(SOURCE) (((SOURCE) == RCC_MCO1Source_HSI) || ((SOURCE) == RCC_MCO1Source_LSE) || \ + ((SOURCE) == RCC_MCO1Source_HSE) || ((SOURCE) == RCC_MCO1Source_PLLCLK)) + +#define IS_RCC_MCO1DIV(DIV) (((DIV) == RCC_MCO1Div_1) || ((DIV) == RCC_MCO1Div_2) || \ + ((DIV) == RCC_MCO1Div_3) || ((DIV) == RCC_MCO1Div_4) || \ + ((DIV) == RCC_MCO1Div_5)) +/** + * @} + */ + +/** @defgroup RCC_MCO2_Clock_Source_Prescaler + * @{ + */ +#define RCC_MCO2Source_SYSCLK ((uint32_t)0x00000000) +#define RCC_MCO2Source_PLLI2SCLK ((uint32_t)0x40000000) +#define RCC_MCO2Source_HSE ((uint32_t)0x80000000) +#define RCC_MCO2Source_PLLCLK ((uint32_t)0xC0000000) +#define RCC_MCO2Div_1 ((uint32_t)0x00000000) +#define RCC_MCO2Div_2 ((uint32_t)0x20000000) +#define RCC_MCO2Div_3 ((uint32_t)0x28000000) +#define RCC_MCO2Div_4 ((uint32_t)0x30000000) +#define RCC_MCO2Div_5 ((uint32_t)0x38000000) +#define IS_RCC_MCO2SOURCE(SOURCE) (((SOURCE) == RCC_MCO2Source_SYSCLK) || ((SOURCE) == RCC_MCO2Source_PLLI2SCLK)|| \ + ((SOURCE) == RCC_MCO2Source_HSE) || ((SOURCE) == RCC_MCO2Source_PLLCLK)) + +#define IS_RCC_MCO2DIV(DIV) (((DIV) == RCC_MCO2Div_1) || ((DIV) == RCC_MCO2Div_2) || \ + ((DIV) == RCC_MCO2Div_3) || ((DIV) == RCC_MCO2Div_4) || \ + ((DIV) == RCC_MCO2Div_5)) +/** + * @} + */ + +/** @defgroup RCC_Flag + * @{ + */ +#define RCC_FLAG_HSIRDY ((uint8_t)0x21) +#define RCC_FLAG_HSERDY ((uint8_t)0x31) +#define RCC_FLAG_PLLRDY ((uint8_t)0x39) +#define RCC_FLAG_PLLI2SRDY ((uint8_t)0x3B) +#define RCC_FLAG_LSERDY ((uint8_t)0x41) +#define RCC_FLAG_LSIRDY ((uint8_t)0x61) +#define RCC_FLAG_BORRST ((uint8_t)0x79) +#define RCC_FLAG_PINRST ((uint8_t)0x7A) +#define RCC_FLAG_PORRST ((uint8_t)0x7B) +#define RCC_FLAG_SFTRST ((uint8_t)0x7C) +#define RCC_FLAG_IWDGRST ((uint8_t)0x7D) +#define RCC_FLAG_WWDGRST ((uint8_t)0x7E) +#define RCC_FLAG_LPWRRST ((uint8_t)0x7F) +#define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \ + ((FLAG) == RCC_FLAG_PLLRDY) || ((FLAG) == RCC_FLAG_LSERDY) || \ + ((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_BORRST) || \ + ((FLAG) == RCC_FLAG_PINRST) || ((FLAG) == RCC_FLAG_PORRST) || \ + ((FLAG) == RCC_FLAG_SFTRST) || ((FLAG) == RCC_FLAG_IWDGRST)|| \ + ((FLAG) == RCC_FLAG_WWDGRST)|| ((FLAG) == RCC_FLAG_LPWRRST)|| \ + ((FLAG) == RCC_FLAG_PLLI2SRDY)) +#define IS_RCC_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the RCC clock configuration to the default reset state */ +void RCC_DeInit(void); + +/* Internal/external clocks, PLL, CSS and MCO configuration functions *********/ +void RCC_HSEConfig(uint8_t RCC_HSE); +ErrorStatus RCC_WaitForHSEStartUp(void); +void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue); +void RCC_HSICmd(FunctionalState NewState); +void RCC_LSEConfig(uint8_t RCC_LSE); +void RCC_LSICmd(FunctionalState NewState); + +void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ); +void RCC_PLLCmd(FunctionalState NewState); +void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR); +void RCC_PLLI2SCmd(FunctionalState NewState); + +void RCC_ClockSecuritySystemCmd(FunctionalState NewState); +void RCC_MCO1Config(uint32_t RCC_MCO1Source, uint32_t RCC_MCO1Div); +void RCC_MCO2Config(uint32_t RCC_MCO2Source, uint32_t RCC_MCO2Div); + +/* System, AHB and APB busses clocks configuration functions ******************/ +void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource); +uint8_t RCC_GetSYSCLKSource(void); +void RCC_HCLKConfig(uint32_t RCC_SYSCLK); +void RCC_PCLK1Config(uint32_t RCC_HCLK); +void RCC_PCLK2Config(uint32_t RCC_HCLK); +void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks); + +/* Peripheral clocks configuration functions **********************************/ +void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); +void RCC_RTCCLKCmd(FunctionalState NewState); +void RCC_BackupResetCmd(FunctionalState NewState); +void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource); + +void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); +void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); +void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); +void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); +void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); + +void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); +void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); +void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); +void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); +void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); + +void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); +void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); +void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); +void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); +void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState); +FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG); +void RCC_ClearFlag(void); +ITStatus RCC_GetITStatus(uint8_t RCC_IT); +void RCC_ClearITPendingBit(uint8_t RCC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_RCC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rng.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rng.h new file mode 100644 index 0000000..5a080a3 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rng.h @@ -0,0 +1,114 @@ +/** + ****************************************************************************** + * @file stm32f4xx_rng.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the Random + * Number Generator(RNG) firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_RNG_H +#define __STM32F4xx_RNG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup RNG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RNG_Exported_Constants + * @{ + */ + +/** @defgroup RNG_flags_definition + * @{ + */ +#define RNG_FLAG_DRDY ((uint8_t)0x0001) /*!< Data ready */ +#define RNG_FLAG_CECS ((uint8_t)0x0002) /*!< Clock error current status */ +#define RNG_FLAG_SECS ((uint8_t)0x0004) /*!< Seed error current status */ + +#define IS_RNG_GET_FLAG(RNG_FLAG) (((RNG_FLAG) == RNG_FLAG_DRDY) || \ + ((RNG_FLAG) == RNG_FLAG_CECS) || \ + ((RNG_FLAG) == RNG_FLAG_SECS)) +#define IS_RNG_CLEAR_FLAG(RNG_FLAG) (((RNG_FLAG) == RNG_FLAG_CECS) || \ + ((RNG_FLAG) == RNG_FLAG_SECS)) +/** + * @} + */ + +/** @defgroup RNG_interrupts_definition + * @{ + */ +#define RNG_IT_CEI ((uint8_t)0x20) /*!< Clock error interrupt */ +#define RNG_IT_SEI ((uint8_t)0x40) /*!< Seed error interrupt */ + +#define IS_RNG_IT(IT) ((((IT) & (uint8_t)0x9F) == 0x00) && ((IT) != 0x00)) +#define IS_RNG_GET_IT(RNG_IT) (((RNG_IT) == RNG_IT_CEI) || ((RNG_IT) == RNG_IT_SEI)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the RNG configuration to the default reset state *****/ +void RNG_DeInit(void); + +/* Configuration function *****************************************************/ +void RNG_Cmd(FunctionalState NewState); + +/* Get 32 bit Random number function ******************************************/ +uint32_t RNG_GetRandomNumber(void); + +/* Interrupts and flags management functions **********************************/ +void RNG_ITConfig(FunctionalState NewState); +FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG); +void RNG_ClearFlag(uint8_t RNG_FLAG); +ITStatus RNG_GetITStatus(uint8_t RNG_IT); +void RNG_ClearITPendingBit(uint8_t RNG_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_RNG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rtc.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rtc.h new file mode 100644 index 0000000..d5e5794 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rtc.h @@ -0,0 +1,875 @@ +/** + ****************************************************************************** + * @file stm32f4xx_rtc.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the RTC firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_RTC_H +#define __STM32F4xx_RTC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup RTC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief RTC Init structures definition + */ +typedef struct +{ + uint32_t RTC_HourFormat; /*!< Specifies the RTC Hour Format. + This parameter can be a value of @ref RTC_Hour_Formats */ + + uint32_t RTC_AsynchPrediv; /*!< Specifies the RTC Asynchronous Predivider value. + This parameter must be set to a value lower than 0x7F */ + + uint32_t RTC_SynchPrediv; /*!< Specifies the RTC Synchronous Predivider value. + This parameter must be set to a value lower than 0x7FFF */ +}RTC_InitTypeDef; + +/** + * @brief RTC Time structure definition + */ +typedef struct +{ + uint8_t RTC_Hours; /*!< Specifies the RTC Time Hour. + This parameter must be set to a value in the 0-12 range + if the RTC_HourFormat_12 is selected or 0-23 range if + the RTC_HourFormat_24 is selected. */ + + uint8_t RTC_Minutes; /*!< Specifies the RTC Time Minutes. + This parameter must be set to a value in the 0-59 range. */ + + uint8_t RTC_Seconds; /*!< Specifies the RTC Time Seconds. + This parameter must be set to a value in the 0-59 range. */ + + uint8_t RTC_H12; /*!< Specifies the RTC AM/PM Time. + This parameter can be a value of @ref RTC_AM_PM_Definitions */ +}RTC_TimeTypeDef; + +/** + * @brief RTC Date structure definition + */ +typedef struct +{ + uint8_t RTC_WeekDay; /*!< Specifies the RTC Date WeekDay. + This parameter can be a value of @ref RTC_WeekDay_Definitions */ + + uint8_t RTC_Month; /*!< Specifies the RTC Date Month (in BCD format). + This parameter can be a value of @ref RTC_Month_Date_Definitions */ + + uint8_t RTC_Date; /*!< Specifies the RTC Date. + This parameter must be set to a value in the 1-31 range. */ + + uint8_t RTC_Year; /*!< Specifies the RTC Date Year. + This parameter must be set to a value in the 0-99 range. */ +}RTC_DateTypeDef; + +/** + * @brief RTC Alarm structure definition + */ +typedef struct +{ + RTC_TimeTypeDef RTC_AlarmTime; /*!< Specifies the RTC Alarm Time members. */ + + uint32_t RTC_AlarmMask; /*!< Specifies the RTC Alarm Masks. + This parameter can be a value of @ref RTC_AlarmMask_Definitions */ + + uint32_t RTC_AlarmDateWeekDaySel; /*!< Specifies the RTC Alarm is on Date or WeekDay. + This parameter can be a value of @ref RTC_AlarmDateWeekDay_Definitions */ + + uint8_t RTC_AlarmDateWeekDay; /*!< Specifies the RTC Alarm Date/WeekDay. + If the Alarm Date is selected, this parameter + must be set to a value in the 1-31 range. + If the Alarm WeekDay is selected, this + parameter can be a value of @ref RTC_WeekDay_Definitions */ +}RTC_AlarmTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RTC_Exported_Constants + * @{ + */ + + +/** @defgroup RTC_Hour_Formats + * @{ + */ +#define RTC_HourFormat_24 ((uint32_t)0x00000000) +#define RTC_HourFormat_12 ((uint32_t)0x00000040) +#define IS_RTC_HOUR_FORMAT(FORMAT) (((FORMAT) == RTC_HourFormat_12) || \ + ((FORMAT) == RTC_HourFormat_24)) +/** + * @} + */ + +/** @defgroup RTC_Asynchronous_Predivider + * @{ + */ +#define IS_RTC_ASYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7F) + +/** + * @} + */ + + +/** @defgroup RTC_Synchronous_Predivider + * @{ + */ +#define IS_RTC_SYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7FFF) + +/** + * @} + */ + +/** @defgroup RTC_Time_Definitions + * @{ + */ +#define IS_RTC_HOUR12(HOUR) (((HOUR) > 0) && ((HOUR) <= 12)) +#define IS_RTC_HOUR24(HOUR) ((HOUR) <= 23) +#define IS_RTC_MINUTES(MINUTES) ((MINUTES) <= 59) +#define IS_RTC_SECONDS(SECONDS) ((SECONDS) <= 59) + +/** + * @} + */ + +/** @defgroup RTC_AM_PM_Definitions + * @{ + */ +#define RTC_H12_AM ((uint8_t)0x00) +#define RTC_H12_PM ((uint8_t)0x40) +#define IS_RTC_H12(PM) (((PM) == RTC_H12_AM) || ((PM) == RTC_H12_PM)) + +/** + * @} + */ + +/** @defgroup RTC_Year_Date_Definitions + * @{ + */ +#define IS_RTC_YEAR(YEAR) ((YEAR) <= 99) + +/** + * @} + */ + +/** @defgroup RTC_Month_Date_Definitions + * @{ + */ + +/* Coded in BCD format */ +#define RTC_Month_January ((uint8_t)0x01) +#define RTC_Month_February ((uint8_t)0x02) +#define RTC_Month_March ((uint8_t)0x03) +#define RTC_Month_April ((uint8_t)0x04) +#define RTC_Month_May ((uint8_t)0x05) +#define RTC_Month_June ((uint8_t)0x06) +#define RTC_Month_July ((uint8_t)0x07) +#define RTC_Month_August ((uint8_t)0x08) +#define RTC_Month_September ((uint8_t)0x09) +#define RTC_Month_October ((uint8_t)0x10) +#define RTC_Month_November ((uint8_t)0x11) +#define RTC_Month_December ((uint8_t)0x12) +#define IS_RTC_MONTH(MONTH) (((MONTH) >= 1) && ((MONTH) <= 12)) +#define IS_RTC_DATE(DATE) (((DATE) >= 1) && ((DATE) <= 31)) + +/** + * @} + */ + +/** @defgroup RTC_WeekDay_Definitions + * @{ + */ + +#define RTC_Weekday_Monday ((uint8_t)0x01) +#define RTC_Weekday_Tuesday ((uint8_t)0x02) +#define RTC_Weekday_Wednesday ((uint8_t)0x03) +#define RTC_Weekday_Thursday ((uint8_t)0x04) +#define RTC_Weekday_Friday ((uint8_t)0x05) +#define RTC_Weekday_Saturday ((uint8_t)0x06) +#define RTC_Weekday_Sunday ((uint8_t)0x07) +#define IS_RTC_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \ + ((WEEKDAY) == RTC_Weekday_Tuesday) || \ + ((WEEKDAY) == RTC_Weekday_Wednesday) || \ + ((WEEKDAY) == RTC_Weekday_Thursday) || \ + ((WEEKDAY) == RTC_Weekday_Friday) || \ + ((WEEKDAY) == RTC_Weekday_Saturday) || \ + ((WEEKDAY) == RTC_Weekday_Sunday)) +/** + * @} + */ + + +/** @defgroup RTC_Alarm_Definitions + * @{ + */ +#define IS_RTC_ALARM_DATE_WEEKDAY_DATE(DATE) (((DATE) > 0) && ((DATE) <= 31)) +#define IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \ + ((WEEKDAY) == RTC_Weekday_Tuesday) || \ + ((WEEKDAY) == RTC_Weekday_Wednesday) || \ + ((WEEKDAY) == RTC_Weekday_Thursday) || \ + ((WEEKDAY) == RTC_Weekday_Friday) || \ + ((WEEKDAY) == RTC_Weekday_Saturday) || \ + ((WEEKDAY) == RTC_Weekday_Sunday)) + +/** + * @} + */ + + +/** @defgroup RTC_AlarmDateWeekDay_Definitions + * @{ + */ +#define RTC_AlarmDateWeekDaySel_Date ((uint32_t)0x00000000) +#define RTC_AlarmDateWeekDaySel_WeekDay ((uint32_t)0x40000000) + +#define IS_RTC_ALARM_DATE_WEEKDAY_SEL(SEL) (((SEL) == RTC_AlarmDateWeekDaySel_Date) || \ + ((SEL) == RTC_AlarmDateWeekDaySel_WeekDay)) + +/** + * @} + */ + + +/** @defgroup RTC_AlarmMask_Definitions + * @{ + */ +#define RTC_AlarmMask_None ((uint32_t)0x00000000) +#define RTC_AlarmMask_DateWeekDay ((uint32_t)0x80000000) +#define RTC_AlarmMask_Hours ((uint32_t)0x00800000) +#define RTC_AlarmMask_Minutes ((uint32_t)0x00008000) +#define RTC_AlarmMask_Seconds ((uint32_t)0x00000080) +#define RTC_AlarmMask_All ((uint32_t)0x80808080) +#define IS_ALARM_MASK(MASK) (((MASK) & 0x7F7F7F7F) == (uint32_t)RESET) + +/** + * @} + */ + +/** @defgroup RTC_Alarms_Definitions + * @{ + */ +#define RTC_Alarm_A ((uint32_t)0x00000100) +#define RTC_Alarm_B ((uint32_t)0x00000200) +#define IS_RTC_ALARM(ALARM) (((ALARM) == RTC_Alarm_A) || ((ALARM) == RTC_Alarm_B)) +#define IS_RTC_CMD_ALARM(ALARM) (((ALARM) & (RTC_Alarm_A | RTC_Alarm_B)) != (uint32_t)RESET) + +/** + * @} + */ + + /** @defgroup RTC_Alarm_Sub_Seconds_Masks_Definitions + * @{ + */ +#define RTC_AlarmSubSecondMask_All ((uint32_t)0x00000000) /*!< All Alarm SS fields are masked. + There is no comparison on sub seconds + for Alarm */ +#define RTC_AlarmSubSecondMask_SS14_1 ((uint32_t)0x01000000) /*!< SS[14:1] are don't care in Alarm + comparison. Only SS[0] is compared. */ +#define RTC_AlarmSubSecondMask_SS14_2 ((uint32_t)0x02000000) /*!< SS[14:2] are don't care in Alarm + comparison. Only SS[1:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_3 ((uint32_t)0x03000000) /*!< SS[14:3] are don't care in Alarm + comparison. Only SS[2:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_4 ((uint32_t)0x04000000) /*!< SS[14:4] are don't care in Alarm + comparison. Only SS[3:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_5 ((uint32_t)0x05000000) /*!< SS[14:5] are don't care in Alarm + comparison. Only SS[4:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_6 ((uint32_t)0x06000000) /*!< SS[14:6] are don't care in Alarm + comparison. Only SS[5:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_7 ((uint32_t)0x07000000) /*!< SS[14:7] are don't care in Alarm + comparison. Only SS[6:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_8 ((uint32_t)0x08000000) /*!< SS[14:8] are don't care in Alarm + comparison. Only SS[7:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_9 ((uint32_t)0x09000000) /*!< SS[14:9] are don't care in Alarm + comparison. Only SS[8:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_10 ((uint32_t)0x0A000000) /*!< SS[14:10] are don't care in Alarm + comparison. Only SS[9:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_11 ((uint32_t)0x0B000000) /*!< SS[14:11] are don't care in Alarm + comparison. Only SS[10:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_12 ((uint32_t)0x0C000000) /*!< SS[14:12] are don't care in Alarm + comparison.Only SS[11:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_13 ((uint32_t)0x0D000000) /*!< SS[14:13] are don't care in Alarm + comparison. Only SS[12:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14 ((uint32_t)0x0E000000) /*!< SS[14] is don't care in Alarm + comparison.Only SS[13:0] are compared */ +#define RTC_AlarmSubSecondMask_None ((uint32_t)0x0F000000) /*!< SS[14:0] are compared and must match + to activate alarm. */ +#define IS_RTC_ALARM_SUB_SECOND_MASK(MASK) (((MASK) == RTC_AlarmSubSecondMask_All) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_1) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_2) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_3) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_4) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_5) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_6) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_7) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_8) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_9) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_10) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_11) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_12) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_13) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14) || \ + ((MASK) == RTC_AlarmSubSecondMask_None)) +/** + * @} + */ + +/** @defgroup RTC_Alarm_Sub_Seconds_Value + * @{ + */ + +#define IS_RTC_ALARM_SUB_SECOND_VALUE(VALUE) ((VALUE) <= 0x00007FFF) + +/** + * @} + */ + +/** @defgroup RTC_Wakeup_Timer_Definitions + * @{ + */ +#define RTC_WakeUpClock_RTCCLK_Div16 ((uint32_t)0x00000000) +#define RTC_WakeUpClock_RTCCLK_Div8 ((uint32_t)0x00000001) +#define RTC_WakeUpClock_RTCCLK_Div4 ((uint32_t)0x00000002) +#define RTC_WakeUpClock_RTCCLK_Div2 ((uint32_t)0x00000003) +#define RTC_WakeUpClock_CK_SPRE_16bits ((uint32_t)0x00000004) +#define RTC_WakeUpClock_CK_SPRE_17bits ((uint32_t)0x00000006) +#define IS_RTC_WAKEUP_CLOCK(CLOCK) (((CLOCK) == RTC_WakeUpClock_RTCCLK_Div16) || \ + ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div8) || \ + ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div4) || \ + ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div2) || \ + ((CLOCK) == RTC_WakeUpClock_CK_SPRE_16bits) || \ + ((CLOCK) == RTC_WakeUpClock_CK_SPRE_17bits)) +#define IS_RTC_WAKEUP_COUNTER(COUNTER) ((COUNTER) <= 0xFFFF) +/** + * @} + */ + +/** @defgroup RTC_Time_Stamp_Edges_definitions + * @{ + */ +#define RTC_TimeStampEdge_Rising ((uint32_t)0x00000000) +#define RTC_TimeStampEdge_Falling ((uint32_t)0x00000008) +#define IS_RTC_TIMESTAMP_EDGE(EDGE) (((EDGE) == RTC_TimeStampEdge_Rising) || \ + ((EDGE) == RTC_TimeStampEdge_Falling)) +/** + * @} + */ + +/** @defgroup RTC_Output_selection_Definitions + * @{ + */ +#define RTC_Output_Disable ((uint32_t)0x00000000) +#define RTC_Output_AlarmA ((uint32_t)0x00200000) +#define RTC_Output_AlarmB ((uint32_t)0x00400000) +#define RTC_Output_WakeUp ((uint32_t)0x00600000) + +#define IS_RTC_OUTPUT(OUTPUT) (((OUTPUT) == RTC_Output_Disable) || \ + ((OUTPUT) == RTC_Output_AlarmA) || \ + ((OUTPUT) == RTC_Output_AlarmB) || \ + ((OUTPUT) == RTC_Output_WakeUp)) + +/** + * @} + */ + +/** @defgroup RTC_Output_Polarity_Definitions + * @{ + */ +#define RTC_OutputPolarity_High ((uint32_t)0x00000000) +#define RTC_OutputPolarity_Low ((uint32_t)0x00100000) +#define IS_RTC_OUTPUT_POL(POL) (((POL) == RTC_OutputPolarity_High) || \ + ((POL) == RTC_OutputPolarity_Low)) +/** + * @} + */ + + +/** @defgroup RTC_Digital_Calibration_Definitions + * @{ + */ +#define RTC_CalibSign_Positive ((uint32_t)0x00000000) +#define RTC_CalibSign_Negative ((uint32_t)0x00000080) +#define IS_RTC_CALIB_SIGN(SIGN) (((SIGN) == RTC_CalibSign_Positive) || \ + ((SIGN) == RTC_CalibSign_Negative)) +#define IS_RTC_CALIB_VALUE(VALUE) ((VALUE) < 0x20) + +/** + * @} + */ + + /** @defgroup RTC_Calib_Output_selection_Definitions + * @{ + */ +#define RTC_CalibOutput_512Hz ((uint32_t)0x00000000) +#define RTC_CalibOutput_1Hz ((uint32_t)0x00080000) +#define IS_RTC_CALIB_OUTPUT(OUTPUT) (((OUTPUT) == RTC_CalibOutput_512Hz) || \ + ((OUTPUT) == RTC_CalibOutput_1Hz)) +/** + * @} + */ + +/** @defgroup RTC_Smooth_calib_period_Definitions + * @{ + */ +#define RTC_SmoothCalibPeriod_32sec ((uint32_t)0x00000000) /*!< if RTCCLK = 32768 Hz, Smooth calibation + period is 32s, else 2exp20 RTCCLK seconds */ +#define RTC_SmoothCalibPeriod_16sec ((uint32_t)0x00002000) /*!< if RTCCLK = 32768 Hz, Smooth calibation + period is 16s, else 2exp19 RTCCLK seconds */ +#define RTC_SmoothCalibPeriod_8sec ((uint32_t)0x00004000) /*!< if RTCCLK = 32768 Hz, Smooth calibation + period is 8s, else 2exp18 RTCCLK seconds */ +#define IS_RTC_SMOOTH_CALIB_PERIOD(PERIOD) (((PERIOD) == RTC_SmoothCalibPeriod_32sec) || \ + ((PERIOD) == RTC_SmoothCalibPeriod_16sec) || \ + ((PERIOD) == RTC_SmoothCalibPeriod_8sec)) + +/** + * @} + */ + +/** @defgroup RTC_Smooth_calib_Plus_pulses_Definitions + * @{ + */ +#define RTC_SmoothCalibPlusPulses_Set ((uint32_t)0x00008000) /*!< The number of RTCCLK pulses added + during a X -second window = Y - CALM[8:0]. + with Y = 512, 256, 128 when X = 32, 16, 8 */ +#define RTC_SmoothCalibPlusPulses_Reset ((uint32_t)0x00000000) /*!< The number of RTCCLK pulses subbstited + during a 32-second window = CALM[8:0]. */ +#define IS_RTC_SMOOTH_CALIB_PLUS(PLUS) (((PLUS) == RTC_SmoothCalibPlusPulses_Set) || \ + ((PLUS) == RTC_SmoothCalibPlusPulses_Reset)) + +/** + * @} + */ + +/** @defgroup RTC_Smooth_calib_Minus_pulses_Definitions + * @{ + */ +#define IS_RTC_SMOOTH_CALIB_MINUS(VALUE) ((VALUE) <= 0x000001FF) + +/** + * @} + */ + +/** @defgroup RTC_DayLightSaving_Definitions + * @{ + */ +#define RTC_DayLightSaving_SUB1H ((uint32_t)0x00020000) +#define RTC_DayLightSaving_ADD1H ((uint32_t)0x00010000) +#define IS_RTC_DAYLIGHT_SAVING(SAVE) (((SAVE) == RTC_DayLightSaving_SUB1H) || \ + ((SAVE) == RTC_DayLightSaving_ADD1H)) + +#define RTC_StoreOperation_Reset ((uint32_t)0x00000000) +#define RTC_StoreOperation_Set ((uint32_t)0x00040000) +#define IS_RTC_STORE_OPERATION(OPERATION) (((OPERATION) == RTC_StoreOperation_Reset) || \ + ((OPERATION) == RTC_StoreOperation_Set)) +/** + * @} + */ + +/** @defgroup RTC_Tamper_Trigger_Definitions + * @{ + */ +#define RTC_TamperTrigger_RisingEdge ((uint32_t)0x00000000) +#define RTC_TamperTrigger_FallingEdge ((uint32_t)0x00000001) +#define RTC_TamperTrigger_LowLevel ((uint32_t)0x00000000) +#define RTC_TamperTrigger_HighLevel ((uint32_t)0x00000001) +#define IS_RTC_TAMPER_TRIGGER(TRIGGER) (((TRIGGER) == RTC_TamperTrigger_RisingEdge) || \ + ((TRIGGER) == RTC_TamperTrigger_FallingEdge) || \ + ((TRIGGER) == RTC_TamperTrigger_LowLevel) || \ + ((TRIGGER) == RTC_TamperTrigger_HighLevel)) + +/** + * @} + */ + +/** @defgroup RTC_Tamper_Filter_Definitions + * @{ + */ +#define RTC_TamperFilter_Disable ((uint32_t)0x00000000) /*!< Tamper filter is disabled */ + +#define RTC_TamperFilter_2Sample ((uint32_t)0x00000800) /*!< Tamper is activated after 2 + consecutive samples at the active level */ +#define RTC_TamperFilter_4Sample ((uint32_t)0x00001000) /*!< Tamper is activated after 4 + consecutive samples at the active level */ +#define RTC_TamperFilter_8Sample ((uint32_t)0x00001800) /*!< Tamper is activated after 8 + consecutive samples at the active leve. */ +#define IS_RTC_TAMPER_FILTER(FILTER) (((FILTER) == RTC_TamperFilter_Disable) || \ + ((FILTER) == RTC_TamperFilter_2Sample) || \ + ((FILTER) == RTC_TamperFilter_4Sample) || \ + ((FILTER) == RTC_TamperFilter_8Sample)) +/** + * @} + */ + +/** @defgroup RTC_Tamper_Sampling_Frequencies_Definitions + * @{ + */ +#define RTC_TamperSamplingFreq_RTCCLK_Div32768 ((uint32_t)0x00000000) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 32768 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div16384 ((uint32_t)0x000000100) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 16384 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div8192 ((uint32_t)0x00000200) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 8192 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div4096 ((uint32_t)0x00000300) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 4096 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div2048 ((uint32_t)0x00000400) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 2048 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div1024 ((uint32_t)0x00000500) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 1024 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div512 ((uint32_t)0x00000600) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 512 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div256 ((uint32_t)0x00000700) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 256 */ +#define IS_RTC_TAMPER_SAMPLING_FREQ(FREQ) (((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div32768) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div16384) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div8192) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div4096) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div2048) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div1024) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div512) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div256)) + +/** + * @} + */ + + /** @defgroup RTC_Tamper_Pin_Precharge_Duration_Definitions + * @{ + */ +#define RTC_TamperPrechargeDuration_1RTCCLK ((uint32_t)0x00000000) /*!< Tamper pins are pre-charged before + sampling during 1 RTCCLK cycle */ +#define RTC_TamperPrechargeDuration_2RTCCLK ((uint32_t)0x00002000) /*!< Tamper pins are pre-charged before + sampling during 2 RTCCLK cycles */ +#define RTC_TamperPrechargeDuration_4RTCCLK ((uint32_t)0x00004000) /*!< Tamper pins are pre-charged before + sampling during 4 RTCCLK cycles */ +#define RTC_TamperPrechargeDuration_8RTCCLK ((uint32_t)0x00006000) /*!< Tamper pins are pre-charged before + sampling during 8 RTCCLK cycles */ + +#define IS_RTC_TAMPER_PRECHARGE_DURATION(DURATION) (((DURATION) == RTC_TamperPrechargeDuration_1RTCCLK) || \ + ((DURATION) == RTC_TamperPrechargeDuration_2RTCCLK) || \ + ((DURATION) == RTC_TamperPrechargeDuration_4RTCCLK) || \ + ((DURATION) == RTC_TamperPrechargeDuration_8RTCCLK)) +/** + * @} + */ + +/** @defgroup RTC_Tamper_Pins_Definitions + * @{ + */ +#define RTC_Tamper_1 RTC_TAFCR_TAMP1E +#define IS_RTC_TAMPER(TAMPER) (((TAMPER) == RTC_Tamper_1)) + +/** + * @} + */ + +/** @defgroup RTC_Tamper_Pin_Selection + * @{ + */ +#define RTC_TamperPin_PC13 ((uint32_t)0x00000000) +#define RTC_TamperPin_PI8 ((uint32_t)0x00010000) +#define IS_RTC_TAMPER_PIN(PIN) (((PIN) == RTC_TamperPin_PC13) || \ + ((PIN) == RTC_TamperPin_PI8)) +/** + * @} + */ + +/** @defgroup RTC_TimeStamp_Pin_Selection + * @{ + */ +#define RTC_TimeStampPin_PC13 ((uint32_t)0x00000000) +#define RTC_TimeStampPin_PI8 ((uint32_t)0x00020000) +#define IS_RTC_TIMESTAMP_PIN(PIN) (((PIN) == RTC_TimeStampPin_PC13) || \ + ((PIN) == RTC_TimeStampPin_PI8)) +/** + * @} + */ + +/** @defgroup RTC_Output_Type_ALARM_OUT + * @{ + */ +#define RTC_OutputType_OpenDrain ((uint32_t)0x00000000) +#define RTC_OutputType_PushPull ((uint32_t)0x00040000) +#define IS_RTC_OUTPUT_TYPE(TYPE) (((TYPE) == RTC_OutputType_OpenDrain) || \ + ((TYPE) == RTC_OutputType_PushPull)) + +/** + * @} + */ + +/** @defgroup RTC_Add_1_Second_Parameter_Definitions + * @{ + */ +#define RTC_ShiftAdd1S_Reset ((uint32_t)0x00000000) +#define RTC_ShiftAdd1S_Set ((uint32_t)0x80000000) +#define IS_RTC_SHIFT_ADD1S(SEL) (((SEL) == RTC_ShiftAdd1S_Reset) || \ + ((SEL) == RTC_ShiftAdd1S_Set)) +/** + * @} + */ + +/** @defgroup RTC_Substract_Fraction_Of_Second_Value + * @{ + */ +#define IS_RTC_SHIFT_SUBFS(FS) ((FS) <= 0x00007FFF) + +/** + * @} + */ + +/** @defgroup RTC_Backup_Registers_Definitions + * @{ + */ + +#define RTC_BKP_DR0 ((uint32_t)0x00000000) +#define RTC_BKP_DR1 ((uint32_t)0x00000001) +#define RTC_BKP_DR2 ((uint32_t)0x00000002) +#define RTC_BKP_DR3 ((uint32_t)0x00000003) +#define RTC_BKP_DR4 ((uint32_t)0x00000004) +#define RTC_BKP_DR5 ((uint32_t)0x00000005) +#define RTC_BKP_DR6 ((uint32_t)0x00000006) +#define RTC_BKP_DR7 ((uint32_t)0x00000007) +#define RTC_BKP_DR8 ((uint32_t)0x00000008) +#define RTC_BKP_DR9 ((uint32_t)0x00000009) +#define RTC_BKP_DR10 ((uint32_t)0x0000000A) +#define RTC_BKP_DR11 ((uint32_t)0x0000000B) +#define RTC_BKP_DR12 ((uint32_t)0x0000000C) +#define RTC_BKP_DR13 ((uint32_t)0x0000000D) +#define RTC_BKP_DR14 ((uint32_t)0x0000000E) +#define RTC_BKP_DR15 ((uint32_t)0x0000000F) +#define RTC_BKP_DR16 ((uint32_t)0x00000010) +#define RTC_BKP_DR17 ((uint32_t)0x00000011) +#define RTC_BKP_DR18 ((uint32_t)0x00000012) +#define RTC_BKP_DR19 ((uint32_t)0x00000013) +#define IS_RTC_BKP(BKP) (((BKP) == RTC_BKP_DR0) || \ + ((BKP) == RTC_BKP_DR1) || \ + ((BKP) == RTC_BKP_DR2) || \ + ((BKP) == RTC_BKP_DR3) || \ + ((BKP) == RTC_BKP_DR4) || \ + ((BKP) == RTC_BKP_DR5) || \ + ((BKP) == RTC_BKP_DR6) || \ + ((BKP) == RTC_BKP_DR7) || \ + ((BKP) == RTC_BKP_DR8) || \ + ((BKP) == RTC_BKP_DR9) || \ + ((BKP) == RTC_BKP_DR10) || \ + ((BKP) == RTC_BKP_DR11) || \ + ((BKP) == RTC_BKP_DR12) || \ + ((BKP) == RTC_BKP_DR13) || \ + ((BKP) == RTC_BKP_DR14) || \ + ((BKP) == RTC_BKP_DR15) || \ + ((BKP) == RTC_BKP_DR16) || \ + ((BKP) == RTC_BKP_DR17) || \ + ((BKP) == RTC_BKP_DR18) || \ + ((BKP) == RTC_BKP_DR19)) +/** + * @} + */ + +/** @defgroup RTC_Input_parameter_format_definitions + * @{ + */ +#define RTC_Format_BIN ((uint32_t)0x000000000) +#define RTC_Format_BCD ((uint32_t)0x000000001) +#define IS_RTC_FORMAT(FORMAT) (((FORMAT) == RTC_Format_BIN) || ((FORMAT) == RTC_Format_BCD)) + +/** + * @} + */ + +/** @defgroup RTC_Flags_Definitions + * @{ + */ +#define RTC_FLAG_RECALPF ((uint32_t)0x00010000) +#define RTC_FLAG_TAMP1F ((uint32_t)0x00002000) +#define RTC_FLAG_TSOVF ((uint32_t)0x00001000) +#define RTC_FLAG_TSF ((uint32_t)0x00000800) +#define RTC_FLAG_WUTF ((uint32_t)0x00000400) +#define RTC_FLAG_ALRBF ((uint32_t)0x00000200) +#define RTC_FLAG_ALRAF ((uint32_t)0x00000100) +#define RTC_FLAG_INITF ((uint32_t)0x00000040) +#define RTC_FLAG_RSF ((uint32_t)0x00000020) +#define RTC_FLAG_INITS ((uint32_t)0x00000010) +#define RTC_FLAG_SHPF ((uint32_t)0x00000008) +#define RTC_FLAG_WUTWF ((uint32_t)0x00000004) +#define RTC_FLAG_ALRBWF ((uint32_t)0x00000002) +#define RTC_FLAG_ALRAWF ((uint32_t)0x00000001) +#define IS_RTC_GET_FLAG(FLAG) (((FLAG) == RTC_FLAG_TSOVF) || ((FLAG) == RTC_FLAG_TSF) || \ + ((FLAG) == RTC_FLAG_WUTF) || ((FLAG) == RTC_FLAG_ALRBF) || \ + ((FLAG) == RTC_FLAG_ALRAF) || ((FLAG) == RTC_FLAG_INITF) || \ + ((FLAG) == RTC_FLAG_RSF) || ((FLAG) == RTC_FLAG_WUTWF) || \ + ((FLAG) == RTC_FLAG_ALRBWF) || ((FLAG) == RTC_FLAG_ALRAWF) || \ + ((FLAG) == RTC_FLAG_TAMP1F) || ((FLAG) == RTC_FLAG_RECALPF) || \ + ((FLAG) == RTC_FLAG_SHPF)) +#define IS_RTC_CLEAR_FLAG(FLAG) (((FLAG) != (uint32_t)RESET) && (((FLAG) & 0xFFFF00DF) == (uint32_t)RESET)) +/** + * @} + */ + +/** @defgroup RTC_Interrupts_Definitions + * @{ + */ +#define RTC_IT_TS ((uint32_t)0x00008000) +#define RTC_IT_WUT ((uint32_t)0x00004000) +#define RTC_IT_ALRB ((uint32_t)0x00002000) +#define RTC_IT_ALRA ((uint32_t)0x00001000) +#define RTC_IT_TAMP ((uint32_t)0x00000004) /* Used only to Enable the Tamper Interrupt */ +#define RTC_IT_TAMP1 ((uint32_t)0x00020000) + +#define IS_RTC_CONFIG_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFF0FFB) == (uint32_t)RESET)) +#define IS_RTC_GET_IT(IT) (((IT) == RTC_IT_TS) || ((IT) == RTC_IT_WUT) || \ + ((IT) == RTC_IT_ALRB) || ((IT) == RTC_IT_ALRA) || \ + ((IT) == RTC_IT_TAMP1)) +#define IS_RTC_CLEAR_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFD0FFF) == (uint32_t)RESET)) + +/** + * @} + */ + +/** @defgroup RTC_Legacy + * @{ + */ +#define RTC_DigitalCalibConfig RTC_CoarseCalibConfig +#define RTC_DigitalCalibCmd RTC_CoarseCalibCmd + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the RTC configuration to the default reset state *****/ +ErrorStatus RTC_DeInit(void); + +/* Initialization and Configuration functions *********************************/ +ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct); +void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct); +void RTC_WriteProtectionCmd(FunctionalState NewState); +ErrorStatus RTC_EnterInitMode(void); +void RTC_ExitInitMode(void); +ErrorStatus RTC_WaitForSynchro(void); +ErrorStatus RTC_RefClockCmd(FunctionalState NewState); +void RTC_BypassShadowCmd(FunctionalState NewState); + +/* Time and Date configuration functions **************************************/ +ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct); +void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct); +void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct); +uint32_t RTC_GetSubSecond(void); +ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct); +void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct); +void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct); + +/* Alarms (Alarm A and Alarm B) configuration functions **********************/ +void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct); +void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct); +void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct); +ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState); +void RTC_AlarmSubSecondConfig(uint32_t RTC_Alarm, uint32_t RTC_AlarmSubSecondValue, uint32_t RTC_AlarmSubSecondMask); +uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm); + +/* WakeUp Timer configuration functions ***************************************/ +void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock); +void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter); +uint32_t RTC_GetWakeUpCounter(void); +ErrorStatus RTC_WakeUpCmd(FunctionalState NewState); + +/* Daylight Saving configuration functions ************************************/ +void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation); +uint32_t RTC_GetStoreOperation(void); + +/* Output pin Configuration function ******************************************/ +void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity); + +/* Digital Calibration configuration functions *********************************/ +ErrorStatus RTC_CoarseCalibConfig(uint32_t RTC_CalibSign, uint32_t Value); +ErrorStatus RTC_CoarseCalibCmd(FunctionalState NewState); +void RTC_CalibOutputCmd(FunctionalState NewState); +void RTC_CalibOutputConfig(uint32_t RTC_CalibOutput); +ErrorStatus RTC_SmoothCalibConfig(uint32_t RTC_SmoothCalibPeriod, + uint32_t RTC_SmoothCalibPlusPulses, + uint32_t RTC_SmouthCalibMinusPulsesValue); + +/* TimeStamp configuration functions ******************************************/ +void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState); +void RTC_GetTimeStamp(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_StampTimeStruct, + RTC_DateTypeDef* RTC_StampDateStruct); +uint32_t RTC_GetTimeStampSubSecond(void); + +/* Tampers configuration functions ********************************************/ +void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger); +void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState); +void RTC_TamperFilterConfig(uint32_t RTC_TamperFilter); +void RTC_TamperSamplingFreqConfig(uint32_t RTC_TamperSamplingFreq); +void RTC_TamperPinsPrechargeDuration(uint32_t RTC_TamperPrechargeDuration); +void RTC_TimeStampOnTamperDetectionCmd(FunctionalState NewState); +void RTC_TamperPullUpCmd(FunctionalState NewState); + +/* Backup Data Registers configuration functions ******************************/ +void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data); +uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR); + +/* RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration + functions ******************************************************************/ +void RTC_TamperPinSelection(uint32_t RTC_TamperPin); +void RTC_TimeStampPinSelection(uint32_t RTC_TimeStampPin); +void RTC_OutputTypeConfig(uint32_t RTC_OutputType); + +/* RTC_Shift_control_synchonisation_functions *********************************/ +ErrorStatus RTC_SynchroShiftConfig(uint32_t RTC_ShiftAdd1S, uint32_t RTC_ShiftSubFS); + +/* Interrupts and flags management functions **********************************/ +void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState); +FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG); +void RTC_ClearFlag(uint32_t RTC_FLAG); +ITStatus RTC_GetITStatus(uint32_t RTC_IT); +void RTC_ClearITPendingBit(uint32_t RTC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_RTC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h new file mode 100644 index 0000000..315703d --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h @@ -0,0 +1,530 @@ +/** + ****************************************************************************** + * @file stm32f4xx_sdio.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the SDIO firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_SDIO_H +#define __STM32F4xx_SDIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup SDIO + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +typedef struct +{ + uint32_t SDIO_ClockEdge; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref SDIO_Clock_Edge */ + + uint32_t SDIO_ClockBypass; /*!< Specifies whether the SDIO Clock divider bypass is + enabled or disabled. + This parameter can be a value of @ref SDIO_Clock_Bypass */ + + uint32_t SDIO_ClockPowerSave; /*!< Specifies whether SDIO Clock output is enabled or + disabled when the bus is idle. + This parameter can be a value of @ref SDIO_Clock_Power_Save */ + + uint32_t SDIO_BusWide; /*!< Specifies the SDIO bus width. + This parameter can be a value of @ref SDIO_Bus_Wide */ + + uint32_t SDIO_HardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled. + This parameter can be a value of @ref SDIO_Hardware_Flow_Control */ + + uint8_t SDIO_ClockDiv; /*!< Specifies the clock frequency of the SDIO controller. + This parameter can be a value between 0x00 and 0xFF. */ + +} SDIO_InitTypeDef; + +typedef struct +{ + uint32_t SDIO_Argument; /*!< Specifies the SDIO command argument which is sent + to a card as part of a command message. If a command + contains an argument, it must be loaded into this register + before writing the command to the command register */ + + uint32_t SDIO_CmdIndex; /*!< Specifies the SDIO command index. It must be lower than 0x40. */ + + uint32_t SDIO_Response; /*!< Specifies the SDIO response type. + This parameter can be a value of @ref SDIO_Response_Type */ + + uint32_t SDIO_Wait; /*!< Specifies whether SDIO wait-for-interrupt request is enabled or disabled. + This parameter can be a value of @ref SDIO_Wait_Interrupt_State */ + + uint32_t SDIO_CPSM; /*!< Specifies whether SDIO Command path state machine (CPSM) + is enabled or disabled. + This parameter can be a value of @ref SDIO_CPSM_State */ +} SDIO_CmdInitTypeDef; + +typedef struct +{ + uint32_t SDIO_DataTimeOut; /*!< Specifies the data timeout period in card bus clock periods. */ + + uint32_t SDIO_DataLength; /*!< Specifies the number of data bytes to be transferred. */ + + uint32_t SDIO_DataBlockSize; /*!< Specifies the data block size for block transfer. + This parameter can be a value of @ref SDIO_Data_Block_Size */ + + uint32_t SDIO_TransferDir; /*!< Specifies the data transfer direction, whether the transfer + is a read or write. + This parameter can be a value of @ref SDIO_Transfer_Direction */ + + uint32_t SDIO_TransferMode; /*!< Specifies whether data transfer is in stream or block mode. + This parameter can be a value of @ref SDIO_Transfer_Type */ + + uint32_t SDIO_DPSM; /*!< Specifies whether SDIO Data path state machine (DPSM) + is enabled or disabled. + This parameter can be a value of @ref SDIO_DPSM_State */ +} SDIO_DataInitTypeDef; + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup SDIO_Exported_Constants + * @{ + */ + +/** @defgroup SDIO_Clock_Edge + * @{ + */ + +#define SDIO_ClockEdge_Rising ((uint32_t)0x00000000) +#define SDIO_ClockEdge_Falling ((uint32_t)0x00002000) +#define IS_SDIO_CLOCK_EDGE(EDGE) (((EDGE) == SDIO_ClockEdge_Rising) || \ + ((EDGE) == SDIO_ClockEdge_Falling)) +/** + * @} + */ + +/** @defgroup SDIO_Clock_Bypass + * @{ + */ + +#define SDIO_ClockBypass_Disable ((uint32_t)0x00000000) +#define SDIO_ClockBypass_Enable ((uint32_t)0x00000400) +#define IS_SDIO_CLOCK_BYPASS(BYPASS) (((BYPASS) == SDIO_ClockBypass_Disable) || \ + ((BYPASS) == SDIO_ClockBypass_Enable)) +/** + * @} + */ + +/** @defgroup SDIO_Clock_Power_Save + * @{ + */ + +#define SDIO_ClockPowerSave_Disable ((uint32_t)0x00000000) +#define SDIO_ClockPowerSave_Enable ((uint32_t)0x00000200) +#define IS_SDIO_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDIO_ClockPowerSave_Disable) || \ + ((SAVE) == SDIO_ClockPowerSave_Enable)) +/** + * @} + */ + +/** @defgroup SDIO_Bus_Wide + * @{ + */ + +#define SDIO_BusWide_1b ((uint32_t)0x00000000) +#define SDIO_BusWide_4b ((uint32_t)0x00000800) +#define SDIO_BusWide_8b ((uint32_t)0x00001000) +#define IS_SDIO_BUS_WIDE(WIDE) (((WIDE) == SDIO_BusWide_1b) || ((WIDE) == SDIO_BusWide_4b) || \ + ((WIDE) == SDIO_BusWide_8b)) + +/** + * @} + */ + +/** @defgroup SDIO_Hardware_Flow_Control + * @{ + */ + +#define SDIO_HardwareFlowControl_Disable ((uint32_t)0x00000000) +#define SDIO_HardwareFlowControl_Enable ((uint32_t)0x00004000) +#define IS_SDIO_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDIO_HardwareFlowControl_Disable) || \ + ((CONTROL) == SDIO_HardwareFlowControl_Enable)) +/** + * @} + */ + +/** @defgroup SDIO_Power_State + * @{ + */ + +#define SDIO_PowerState_OFF ((uint32_t)0x00000000) +#define SDIO_PowerState_ON ((uint32_t)0x00000003) +#define IS_SDIO_POWER_STATE(STATE) (((STATE) == SDIO_PowerState_OFF) || ((STATE) == SDIO_PowerState_ON)) +/** + * @} + */ + + +/** @defgroup SDIO_Interrupt_sources + * @{ + */ + +#define SDIO_IT_CCRCFAIL ((uint32_t)0x00000001) +#define SDIO_IT_DCRCFAIL ((uint32_t)0x00000002) +#define SDIO_IT_CTIMEOUT ((uint32_t)0x00000004) +#define SDIO_IT_DTIMEOUT ((uint32_t)0x00000008) +#define SDIO_IT_TXUNDERR ((uint32_t)0x00000010) +#define SDIO_IT_RXOVERR ((uint32_t)0x00000020) +#define SDIO_IT_CMDREND ((uint32_t)0x00000040) +#define SDIO_IT_CMDSENT ((uint32_t)0x00000080) +#define SDIO_IT_DATAEND ((uint32_t)0x00000100) +#define SDIO_IT_STBITERR ((uint32_t)0x00000200) +#define SDIO_IT_DBCKEND ((uint32_t)0x00000400) +#define SDIO_IT_CMDACT ((uint32_t)0x00000800) +#define SDIO_IT_TXACT ((uint32_t)0x00001000) +#define SDIO_IT_RXACT ((uint32_t)0x00002000) +#define SDIO_IT_TXFIFOHE ((uint32_t)0x00004000) +#define SDIO_IT_RXFIFOHF ((uint32_t)0x00008000) +#define SDIO_IT_TXFIFOF ((uint32_t)0x00010000) +#define SDIO_IT_RXFIFOF ((uint32_t)0x00020000) +#define SDIO_IT_TXFIFOE ((uint32_t)0x00040000) +#define SDIO_IT_RXFIFOE ((uint32_t)0x00080000) +#define SDIO_IT_TXDAVL ((uint32_t)0x00100000) +#define SDIO_IT_RXDAVL ((uint32_t)0x00200000) +#define SDIO_IT_SDIOIT ((uint32_t)0x00400000) +#define SDIO_IT_CEATAEND ((uint32_t)0x00800000) +#define IS_SDIO_IT(IT) ((((IT) & (uint32_t)0xFF000000) == 0x00) && ((IT) != (uint32_t)0x00)) +/** + * @} + */ + +/** @defgroup SDIO_Command_Index + * @{ + */ + +#define IS_SDIO_CMD_INDEX(INDEX) ((INDEX) < 0x40) +/** + * @} + */ + +/** @defgroup SDIO_Response_Type + * @{ + */ + +#define SDIO_Response_No ((uint32_t)0x00000000) +#define SDIO_Response_Short ((uint32_t)0x00000040) +#define SDIO_Response_Long ((uint32_t)0x000000C0) +#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_Response_No) || \ + ((RESPONSE) == SDIO_Response_Short) || \ + ((RESPONSE) == SDIO_Response_Long)) +/** + * @} + */ + +/** @defgroup SDIO_Wait_Interrupt_State + * @{ + */ + +#define SDIO_Wait_No ((uint32_t)0x00000000) /*!< SDIO No Wait, TimeOut is enabled */ +#define SDIO_Wait_IT ((uint32_t)0x00000100) /*!< SDIO Wait Interrupt Request */ +#define SDIO_Wait_Pend ((uint32_t)0x00000200) /*!< SDIO Wait End of transfer */ +#define IS_SDIO_WAIT(WAIT) (((WAIT) == SDIO_Wait_No) || ((WAIT) == SDIO_Wait_IT) || \ + ((WAIT) == SDIO_Wait_Pend)) +/** + * @} + */ + +/** @defgroup SDIO_CPSM_State + * @{ + */ + +#define SDIO_CPSM_Disable ((uint32_t)0x00000000) +#define SDIO_CPSM_Enable ((uint32_t)0x00000400) +#define IS_SDIO_CPSM(CPSM) (((CPSM) == SDIO_CPSM_Enable) || ((CPSM) == SDIO_CPSM_Disable)) +/** + * @} + */ + +/** @defgroup SDIO_Response_Registers + * @{ + */ + +#define SDIO_RESP1 ((uint32_t)0x00000000) +#define SDIO_RESP2 ((uint32_t)0x00000004) +#define SDIO_RESP3 ((uint32_t)0x00000008) +#define SDIO_RESP4 ((uint32_t)0x0000000C) +#define IS_SDIO_RESP(RESP) (((RESP) == SDIO_RESP1) || ((RESP) == SDIO_RESP2) || \ + ((RESP) == SDIO_RESP3) || ((RESP) == SDIO_RESP4)) +/** + * @} + */ + +/** @defgroup SDIO_Data_Length + * @{ + */ + +#define IS_SDIO_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFF) +/** + * @} + */ + +/** @defgroup SDIO_Data_Block_Size + * @{ + */ + +#define SDIO_DataBlockSize_1b ((uint32_t)0x00000000) +#define SDIO_DataBlockSize_2b ((uint32_t)0x00000010) +#define SDIO_DataBlockSize_4b ((uint32_t)0x00000020) +#define SDIO_DataBlockSize_8b ((uint32_t)0x00000030) +#define SDIO_DataBlockSize_16b ((uint32_t)0x00000040) +#define SDIO_DataBlockSize_32b ((uint32_t)0x00000050) +#define SDIO_DataBlockSize_64b ((uint32_t)0x00000060) +#define SDIO_DataBlockSize_128b ((uint32_t)0x00000070) +#define SDIO_DataBlockSize_256b ((uint32_t)0x00000080) +#define SDIO_DataBlockSize_512b ((uint32_t)0x00000090) +#define SDIO_DataBlockSize_1024b ((uint32_t)0x000000A0) +#define SDIO_DataBlockSize_2048b ((uint32_t)0x000000B0) +#define SDIO_DataBlockSize_4096b ((uint32_t)0x000000C0) +#define SDIO_DataBlockSize_8192b ((uint32_t)0x000000D0) +#define SDIO_DataBlockSize_16384b ((uint32_t)0x000000E0) +#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DataBlockSize_1b) || \ + ((SIZE) == SDIO_DataBlockSize_2b) || \ + ((SIZE) == SDIO_DataBlockSize_4b) || \ + ((SIZE) == SDIO_DataBlockSize_8b) || \ + ((SIZE) == SDIO_DataBlockSize_16b) || \ + ((SIZE) == SDIO_DataBlockSize_32b) || \ + ((SIZE) == SDIO_DataBlockSize_64b) || \ + ((SIZE) == SDIO_DataBlockSize_128b) || \ + ((SIZE) == SDIO_DataBlockSize_256b) || \ + ((SIZE) == SDIO_DataBlockSize_512b) || \ + ((SIZE) == SDIO_DataBlockSize_1024b) || \ + ((SIZE) == SDIO_DataBlockSize_2048b) || \ + ((SIZE) == SDIO_DataBlockSize_4096b) || \ + ((SIZE) == SDIO_DataBlockSize_8192b) || \ + ((SIZE) == SDIO_DataBlockSize_16384b)) +/** + * @} + */ + +/** @defgroup SDIO_Transfer_Direction + * @{ + */ + +#define SDIO_TransferDir_ToCard ((uint32_t)0x00000000) +#define SDIO_TransferDir_ToSDIO ((uint32_t)0x00000002) +#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TransferDir_ToCard) || \ + ((DIR) == SDIO_TransferDir_ToSDIO)) +/** + * @} + */ + +/** @defgroup SDIO_Transfer_Type + * @{ + */ + +#define SDIO_TransferMode_Block ((uint32_t)0x00000000) +#define SDIO_TransferMode_Stream ((uint32_t)0x00000004) +#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TransferMode_Stream) || \ + ((MODE) == SDIO_TransferMode_Block)) +/** + * @} + */ + +/** @defgroup SDIO_DPSM_State + * @{ + */ + +#define SDIO_DPSM_Disable ((uint32_t)0x00000000) +#define SDIO_DPSM_Enable ((uint32_t)0x00000001) +#define IS_SDIO_DPSM(DPSM) (((DPSM) == SDIO_DPSM_Enable) || ((DPSM) == SDIO_DPSM_Disable)) +/** + * @} + */ + +/** @defgroup SDIO_Flags + * @{ + */ + +#define SDIO_FLAG_CCRCFAIL ((uint32_t)0x00000001) +#define SDIO_FLAG_DCRCFAIL ((uint32_t)0x00000002) +#define SDIO_FLAG_CTIMEOUT ((uint32_t)0x00000004) +#define SDIO_FLAG_DTIMEOUT ((uint32_t)0x00000008) +#define SDIO_FLAG_TXUNDERR ((uint32_t)0x00000010) +#define SDIO_FLAG_RXOVERR ((uint32_t)0x00000020) +#define SDIO_FLAG_CMDREND ((uint32_t)0x00000040) +#define SDIO_FLAG_CMDSENT ((uint32_t)0x00000080) +#define SDIO_FLAG_DATAEND ((uint32_t)0x00000100) +#define SDIO_FLAG_STBITERR ((uint32_t)0x00000200) +#define SDIO_FLAG_DBCKEND ((uint32_t)0x00000400) +#define SDIO_FLAG_CMDACT ((uint32_t)0x00000800) +#define SDIO_FLAG_TXACT ((uint32_t)0x00001000) +#define SDIO_FLAG_RXACT ((uint32_t)0x00002000) +#define SDIO_FLAG_TXFIFOHE ((uint32_t)0x00004000) +#define SDIO_FLAG_RXFIFOHF ((uint32_t)0x00008000) +#define SDIO_FLAG_TXFIFOF ((uint32_t)0x00010000) +#define SDIO_FLAG_RXFIFOF ((uint32_t)0x00020000) +#define SDIO_FLAG_TXFIFOE ((uint32_t)0x00040000) +#define SDIO_FLAG_RXFIFOE ((uint32_t)0x00080000) +#define SDIO_FLAG_TXDAVL ((uint32_t)0x00100000) +#define SDIO_FLAG_RXDAVL ((uint32_t)0x00200000) +#define SDIO_FLAG_SDIOIT ((uint32_t)0x00400000) +#define SDIO_FLAG_CEATAEND ((uint32_t)0x00800000) +#define IS_SDIO_FLAG(FLAG) (((FLAG) == SDIO_FLAG_CCRCFAIL) || \ + ((FLAG) == SDIO_FLAG_DCRCFAIL) || \ + ((FLAG) == SDIO_FLAG_CTIMEOUT) || \ + ((FLAG) == SDIO_FLAG_DTIMEOUT) || \ + ((FLAG) == SDIO_FLAG_TXUNDERR) || \ + ((FLAG) == SDIO_FLAG_RXOVERR) || \ + ((FLAG) == SDIO_FLAG_CMDREND) || \ + ((FLAG) == SDIO_FLAG_CMDSENT) || \ + ((FLAG) == SDIO_FLAG_DATAEND) || \ + ((FLAG) == SDIO_FLAG_STBITERR) || \ + ((FLAG) == SDIO_FLAG_DBCKEND) || \ + ((FLAG) == SDIO_FLAG_CMDACT) || \ + ((FLAG) == SDIO_FLAG_TXACT) || \ + ((FLAG) == SDIO_FLAG_RXACT) || \ + ((FLAG) == SDIO_FLAG_TXFIFOHE) || \ + ((FLAG) == SDIO_FLAG_RXFIFOHF) || \ + ((FLAG) == SDIO_FLAG_TXFIFOF) || \ + ((FLAG) == SDIO_FLAG_RXFIFOF) || \ + ((FLAG) == SDIO_FLAG_TXFIFOE) || \ + ((FLAG) == SDIO_FLAG_RXFIFOE) || \ + ((FLAG) == SDIO_FLAG_TXDAVL) || \ + ((FLAG) == SDIO_FLAG_RXDAVL) || \ + ((FLAG) == SDIO_FLAG_SDIOIT) || \ + ((FLAG) == SDIO_FLAG_CEATAEND)) + +#define IS_SDIO_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFF3FF800) == 0x00) && ((FLAG) != (uint32_t)0x00)) + +#define IS_SDIO_GET_IT(IT) (((IT) == SDIO_IT_CCRCFAIL) || \ + ((IT) == SDIO_IT_DCRCFAIL) || \ + ((IT) == SDIO_IT_CTIMEOUT) || \ + ((IT) == SDIO_IT_DTIMEOUT) || \ + ((IT) == SDIO_IT_TXUNDERR) || \ + ((IT) == SDIO_IT_RXOVERR) || \ + ((IT) == SDIO_IT_CMDREND) || \ + ((IT) == SDIO_IT_CMDSENT) || \ + ((IT) == SDIO_IT_DATAEND) || \ + ((IT) == SDIO_IT_STBITERR) || \ + ((IT) == SDIO_IT_DBCKEND) || \ + ((IT) == SDIO_IT_CMDACT) || \ + ((IT) == SDIO_IT_TXACT) || \ + ((IT) == SDIO_IT_RXACT) || \ + ((IT) == SDIO_IT_TXFIFOHE) || \ + ((IT) == SDIO_IT_RXFIFOHF) || \ + ((IT) == SDIO_IT_TXFIFOF) || \ + ((IT) == SDIO_IT_RXFIFOF) || \ + ((IT) == SDIO_IT_TXFIFOE) || \ + ((IT) == SDIO_IT_RXFIFOE) || \ + ((IT) == SDIO_IT_TXDAVL) || \ + ((IT) == SDIO_IT_RXDAVL) || \ + ((IT) == SDIO_IT_SDIOIT) || \ + ((IT) == SDIO_IT_CEATAEND)) + +#define IS_SDIO_CLEAR_IT(IT) ((((IT) & (uint32_t)0xFF3FF800) == 0x00) && ((IT) != (uint32_t)0x00)) + +/** + * @} + */ + +/** @defgroup SDIO_Read_Wait_Mode + * @{ + */ + +#define SDIO_ReadWaitMode_CLK ((uint32_t)0x00000000) +#define SDIO_ReadWaitMode_DATA2 ((uint32_t)0x00000001) +#define IS_SDIO_READWAIT_MODE(MODE) (((MODE) == SDIO_ReadWaitMode_CLK) || \ + ((MODE) == SDIO_ReadWaitMode_DATA2)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/* Function used to set the SDIO configuration to the default reset state ****/ +void SDIO_DeInit(void); + +/* Initialization and Configuration functions *********************************/ +void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct); +void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct); +void SDIO_ClockCmd(FunctionalState NewState); +void SDIO_SetPowerState(uint32_t SDIO_PowerState); +uint32_t SDIO_GetPowerState(void); + +/* Command path state machine (CPSM) management functions *********************/ +void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct); +void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct); +uint8_t SDIO_GetCommandResponse(void); +uint32_t SDIO_GetResponse(uint32_t SDIO_RESP); + +/* Data path state machine (DPSM) management functions ************************/ +void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct); +void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct); +uint32_t SDIO_GetDataCounter(void); +uint32_t SDIO_ReadData(void); +void SDIO_WriteData(uint32_t Data); +uint32_t SDIO_GetFIFOCount(void); + +/* SDIO IO Cards mode management functions ************************************/ +void SDIO_StartSDIOReadWait(FunctionalState NewState); +void SDIO_StopSDIOReadWait(FunctionalState NewState); +void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode); +void SDIO_SetSDIOOperation(FunctionalState NewState); +void SDIO_SendSDIOSuspendCmd(FunctionalState NewState); + +/* CE-ATA mode management functions *******************************************/ +void SDIO_CommandCompletionCmd(FunctionalState NewState); +void SDIO_CEATAITCmd(FunctionalState NewState); +void SDIO_SendCEATACmd(FunctionalState NewState); + +/* DMA transfers management functions *****************************************/ +void SDIO_DMACmd(FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState); +FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG); +void SDIO_ClearFlag(uint32_t SDIO_FLAG); +ITStatus SDIO_GetITStatus(uint32_t SDIO_IT); +void SDIO_ClearITPendingBit(uint32_t SDIO_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_SDIO_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h new file mode 100644 index 0000000..3e0d79e --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h @@ -0,0 +1,537 @@ +/** + ****************************************************************************** + * @file stm32f4xx_spi.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the SPI + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_SPI_H +#define __STM32F4xx_SPI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup SPI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief SPI Init structure definition + */ + +typedef struct +{ + uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode. + This parameter can be a value of @ref SPI_data_direction */ + + uint16_t SPI_Mode; /*!< Specifies the SPI operating mode. + This parameter can be a value of @ref SPI_mode */ + + uint16_t SPI_DataSize; /*!< Specifies the SPI data size. + This parameter can be a value of @ref SPI_data_size */ + + uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_Clock_Polarity */ + + uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_Clock_Phase */ + + uint16_t SPI_NSS; /*!< Specifies whether the NSS signal is managed by + hardware (NSS pin) or by software using the SSI bit. + This parameter can be a value of @ref SPI_Slave_Select_management */ + + uint16_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be + used to configure the transmit and receive SCK clock. + This parameter can be a value of @ref SPI_BaudRate_Prescaler + @note The communication clock is derived from the master + clock. The slave clock does not need to be set. */ + + uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref SPI_MSB_LSB_transmission */ + + uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */ +}SPI_InitTypeDef; + +/** + * @brief I2S Init structure definition + */ + +typedef struct +{ + + uint16_t I2S_Mode; /*!< Specifies the I2S operating mode. + This parameter can be a value of @ref I2S_Mode */ + + uint16_t I2S_Standard; /*!< Specifies the standard used for the I2S communication. + This parameter can be a value of @ref I2S_Standard */ + + uint16_t I2S_DataFormat; /*!< Specifies the data format for the I2S communication. + This parameter can be a value of @ref I2S_Data_Format */ + + uint16_t I2S_MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not. + This parameter can be a value of @ref I2S_MCLK_Output */ + + uint32_t I2S_AudioFreq; /*!< Specifies the frequency selected for the I2S communication. + This parameter can be a value of @ref I2S_Audio_Frequency */ + + uint16_t I2S_CPOL; /*!< Specifies the idle state of the I2S clock. + This parameter can be a value of @ref I2S_Clock_Polarity */ +}I2S_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup SPI_Exported_Constants + * @{ + */ + +#define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI1) || \ + ((PERIPH) == SPI2) || \ + ((PERIPH) == SPI3)) + +#define IS_SPI_ALL_PERIPH_EXT(PERIPH) (((PERIPH) == SPI1) || \ + ((PERIPH) == SPI2) || \ + ((PERIPH) == SPI3) || \ + ((PERIPH) == I2S2ext) || \ + ((PERIPH) == I2S3ext)) + +#define IS_SPI_23_PERIPH(PERIPH) (((PERIPH) == SPI2) || \ + ((PERIPH) == SPI3)) + +#define IS_SPI_23_PERIPH_EXT(PERIPH) (((PERIPH) == SPI2) || \ + ((PERIPH) == SPI3) || \ + ((PERIPH) == I2S2ext) || \ + ((PERIPH) == I2S3ext)) + +#define IS_I2S_EXT_PERIPH(PERIPH) (((PERIPH) == I2S2ext) || \ + ((PERIPH) == I2S3ext)) + + +/** @defgroup SPI_data_direction + * @{ + */ + +#define SPI_Direction_2Lines_FullDuplex ((uint16_t)0x0000) +#define SPI_Direction_2Lines_RxOnly ((uint16_t)0x0400) +#define SPI_Direction_1Line_Rx ((uint16_t)0x8000) +#define SPI_Direction_1Line_Tx ((uint16_t)0xC000) +#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_2Lines_FullDuplex) || \ + ((MODE) == SPI_Direction_2Lines_RxOnly) || \ + ((MODE) == SPI_Direction_1Line_Rx) || \ + ((MODE) == SPI_Direction_1Line_Tx)) +/** + * @} + */ + +/** @defgroup SPI_mode + * @{ + */ + +#define SPI_Mode_Master ((uint16_t)0x0104) +#define SPI_Mode_Slave ((uint16_t)0x0000) +#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \ + ((MODE) == SPI_Mode_Slave)) +/** + * @} + */ + +/** @defgroup SPI_data_size + * @{ + */ + +#define SPI_DataSize_16b ((uint16_t)0x0800) +#define SPI_DataSize_8b ((uint16_t)0x0000) +#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DataSize_16b) || \ + ((DATASIZE) == SPI_DataSize_8b)) +/** + * @} + */ + +/** @defgroup SPI_Clock_Polarity + * @{ + */ + +#define SPI_CPOL_Low ((uint16_t)0x0000) +#define SPI_CPOL_High ((uint16_t)0x0002) +#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \ + ((CPOL) == SPI_CPOL_High)) +/** + * @} + */ + +/** @defgroup SPI_Clock_Phase + * @{ + */ + +#define SPI_CPHA_1Edge ((uint16_t)0x0000) +#define SPI_CPHA_2Edge ((uint16_t)0x0001) +#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \ + ((CPHA) == SPI_CPHA_2Edge)) +/** + * @} + */ + +/** @defgroup SPI_Slave_Select_management + * @{ + */ + +#define SPI_NSS_Soft ((uint16_t)0x0200) +#define SPI_NSS_Hard ((uint16_t)0x0000) +#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_Soft) || \ + ((NSS) == SPI_NSS_Hard)) +/** + * @} + */ + +/** @defgroup SPI_BaudRate_Prescaler + * @{ + */ + +#define SPI_BaudRatePrescaler_2 ((uint16_t)0x0000) +#define SPI_BaudRatePrescaler_4 ((uint16_t)0x0008) +#define SPI_BaudRatePrescaler_8 ((uint16_t)0x0010) +#define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018) +#define SPI_BaudRatePrescaler_32 ((uint16_t)0x0020) +#define SPI_BaudRatePrescaler_64 ((uint16_t)0x0028) +#define SPI_BaudRatePrescaler_128 ((uint16_t)0x0030) +#define SPI_BaudRatePrescaler_256 ((uint16_t)0x0038) +#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BaudRatePrescaler_2) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_4) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_8) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_16) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_32) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_64) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_128) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_256)) +/** + * @} + */ + +/** @defgroup SPI_MSB_LSB_transmission + * @{ + */ + +#define SPI_FirstBit_MSB ((uint16_t)0x0000) +#define SPI_FirstBit_LSB ((uint16_t)0x0080) +#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FirstBit_MSB) || \ + ((BIT) == SPI_FirstBit_LSB)) +/** + * @} + */ + +/** @defgroup SPI_I2S_Mode + * @{ + */ + +#define I2S_Mode_SlaveTx ((uint16_t)0x0000) +#define I2S_Mode_SlaveRx ((uint16_t)0x0100) +#define I2S_Mode_MasterTx ((uint16_t)0x0200) +#define I2S_Mode_MasterRx ((uint16_t)0x0300) +#define IS_I2S_MODE(MODE) (((MODE) == I2S_Mode_SlaveTx) || \ + ((MODE) == I2S_Mode_SlaveRx) || \ + ((MODE) == I2S_Mode_MasterTx)|| \ + ((MODE) == I2S_Mode_MasterRx)) +/** + * @} + */ + + +/** @defgroup SPI_I2S_Standard + * @{ + */ + +#define I2S_Standard_Phillips ((uint16_t)0x0000) +#define I2S_Standard_MSB ((uint16_t)0x0010) +#define I2S_Standard_LSB ((uint16_t)0x0020) +#define I2S_Standard_PCMShort ((uint16_t)0x0030) +#define I2S_Standard_PCMLong ((uint16_t)0x00B0) +#define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_Standard_Phillips) || \ + ((STANDARD) == I2S_Standard_MSB) || \ + ((STANDARD) == I2S_Standard_LSB) || \ + ((STANDARD) == I2S_Standard_PCMShort) || \ + ((STANDARD) == I2S_Standard_PCMLong)) +/** + * @} + */ + +/** @defgroup SPI_I2S_Data_Format + * @{ + */ + +#define I2S_DataFormat_16b ((uint16_t)0x0000) +#define I2S_DataFormat_16bextended ((uint16_t)0x0001) +#define I2S_DataFormat_24b ((uint16_t)0x0003) +#define I2S_DataFormat_32b ((uint16_t)0x0005) +#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_DataFormat_16b) || \ + ((FORMAT) == I2S_DataFormat_16bextended) || \ + ((FORMAT) == I2S_DataFormat_24b) || \ + ((FORMAT) == I2S_DataFormat_32b)) +/** + * @} + */ + +/** @defgroup SPI_I2S_MCLK_Output + * @{ + */ + +#define I2S_MCLKOutput_Enable ((uint16_t)0x0200) +#define I2S_MCLKOutput_Disable ((uint16_t)0x0000) +#define IS_I2S_MCLK_OUTPUT(OUTPUT) (((OUTPUT) == I2S_MCLKOutput_Enable) || \ + ((OUTPUT) == I2S_MCLKOutput_Disable)) +/** + * @} + */ + +/** @defgroup SPI_I2S_Audio_Frequency + * @{ + */ + +#define I2S_AudioFreq_192k ((uint32_t)192000) +#define I2S_AudioFreq_96k ((uint32_t)96000) +#define I2S_AudioFreq_48k ((uint32_t)48000) +#define I2S_AudioFreq_44k ((uint32_t)44100) +#define I2S_AudioFreq_32k ((uint32_t)32000) +#define I2S_AudioFreq_22k ((uint32_t)22050) +#define I2S_AudioFreq_16k ((uint32_t)16000) +#define I2S_AudioFreq_11k ((uint32_t)11025) +#define I2S_AudioFreq_8k ((uint32_t)8000) +#define I2S_AudioFreq_Default ((uint32_t)2) + +#define IS_I2S_AUDIO_FREQ(FREQ) ((((FREQ) >= I2S_AudioFreq_8k) && \ + ((FREQ) <= I2S_AudioFreq_192k)) || \ + ((FREQ) == I2S_AudioFreq_Default)) +/** + * @} + */ + +/** @defgroup SPI_I2S_Clock_Polarity + * @{ + */ + +#define I2S_CPOL_Low ((uint16_t)0x0000) +#define I2S_CPOL_High ((uint16_t)0x0008) +#define IS_I2S_CPOL(CPOL) (((CPOL) == I2S_CPOL_Low) || \ + ((CPOL) == I2S_CPOL_High)) +/** + * @} + */ + +/** @defgroup SPI_I2S_DMA_transfer_requests + * @{ + */ + +#define SPI_I2S_DMAReq_Tx ((uint16_t)0x0002) +#define SPI_I2S_DMAReq_Rx ((uint16_t)0x0001) +#define IS_SPI_I2S_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((DMAREQ) != 0x00)) +/** + * @} + */ + +/** @defgroup SPI_NSS_internal_software_management + * @{ + */ + +#define SPI_NSSInternalSoft_Set ((uint16_t)0x0100) +#define SPI_NSSInternalSoft_Reset ((uint16_t)0xFEFF) +#define IS_SPI_NSS_INTERNAL(INTERNAL) (((INTERNAL) == SPI_NSSInternalSoft_Set) || \ + ((INTERNAL) == SPI_NSSInternalSoft_Reset)) +/** + * @} + */ + +/** @defgroup SPI_CRC_Transmit_Receive + * @{ + */ + +#define SPI_CRC_Tx ((uint8_t)0x00) +#define SPI_CRC_Rx ((uint8_t)0x01) +#define IS_SPI_CRC(CRC) (((CRC) == SPI_CRC_Tx) || ((CRC) == SPI_CRC_Rx)) +/** + * @} + */ + +/** @defgroup SPI_direction_transmit_receive + * @{ + */ + +#define SPI_Direction_Rx ((uint16_t)0xBFFF) +#define SPI_Direction_Tx ((uint16_t)0x4000) +#define IS_SPI_DIRECTION(DIRECTION) (((DIRECTION) == SPI_Direction_Rx) || \ + ((DIRECTION) == SPI_Direction_Tx)) +/** + * @} + */ + +/** @defgroup SPI_I2S_interrupts_definition + * @{ + */ + +#define SPI_I2S_IT_TXE ((uint8_t)0x71) +#define SPI_I2S_IT_RXNE ((uint8_t)0x60) +#define SPI_I2S_IT_ERR ((uint8_t)0x50) +#define I2S_IT_UDR ((uint8_t)0x53) +#define SPI_I2S_IT_TIFRFE ((uint8_t)0x58) + +#define IS_SPI_I2S_CONFIG_IT(IT) (((IT) == SPI_I2S_IT_TXE) || \ + ((IT) == SPI_I2S_IT_RXNE) || \ + ((IT) == SPI_I2S_IT_ERR)) + +#define SPI_I2S_IT_OVR ((uint8_t)0x56) +#define SPI_IT_MODF ((uint8_t)0x55) +#define SPI_IT_CRCERR ((uint8_t)0x54) + +#define IS_SPI_I2S_CLEAR_IT(IT) (((IT) == SPI_IT_CRCERR)) + +#define IS_SPI_I2S_GET_IT(IT) (((IT) == SPI_I2S_IT_RXNE)|| ((IT) == SPI_I2S_IT_TXE) || \ + ((IT) == SPI_IT_CRCERR) || ((IT) == SPI_IT_MODF) || \ + ((IT) == SPI_I2S_IT_OVR) || ((IT) == I2S_IT_UDR) ||\ + ((IT) == SPI_I2S_IT_TIFRFE)) +/** + * @} + */ + +/** @defgroup SPI_I2S_flags_definition + * @{ + */ + +#define SPI_I2S_FLAG_RXNE ((uint16_t)0x0001) +#define SPI_I2S_FLAG_TXE ((uint16_t)0x0002) +#define I2S_FLAG_CHSIDE ((uint16_t)0x0004) +#define I2S_FLAG_UDR ((uint16_t)0x0008) +#define SPI_FLAG_CRCERR ((uint16_t)0x0010) +#define SPI_FLAG_MODF ((uint16_t)0x0020) +#define SPI_I2S_FLAG_OVR ((uint16_t)0x0040) +#define SPI_I2S_FLAG_BSY ((uint16_t)0x0080) +#define SPI_I2S_FLAG_TIFRFE ((uint16_t)0x0100) + +#define IS_SPI_I2S_CLEAR_FLAG(FLAG) (((FLAG) == SPI_FLAG_CRCERR)) +#define IS_SPI_I2S_GET_FLAG(FLAG) (((FLAG) == SPI_I2S_FLAG_BSY) || ((FLAG) == SPI_I2S_FLAG_OVR) || \ + ((FLAG) == SPI_FLAG_MODF) || ((FLAG) == SPI_FLAG_CRCERR) || \ + ((FLAG) == I2S_FLAG_UDR) || ((FLAG) == I2S_FLAG_CHSIDE) || \ + ((FLAG) == SPI_I2S_FLAG_TXE) || ((FLAG) == SPI_I2S_FLAG_RXNE)|| \ + ((FLAG) == SPI_I2S_FLAG_TIFRFE)) +/** + * @} + */ + +/** @defgroup SPI_CRC_polynomial + * @{ + */ + +#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) >= 0x1) +/** + * @} + */ + +/** @defgroup SPI_I2S_Legacy + * @{ + */ + +#define SPI_DMAReq_Tx SPI_I2S_DMAReq_Tx +#define SPI_DMAReq_Rx SPI_I2S_DMAReq_Rx +#define SPI_IT_TXE SPI_I2S_IT_TXE +#define SPI_IT_RXNE SPI_I2S_IT_RXNE +#define SPI_IT_ERR SPI_I2S_IT_ERR +#define SPI_IT_OVR SPI_I2S_IT_OVR +#define SPI_FLAG_RXNE SPI_I2S_FLAG_RXNE +#define SPI_FLAG_TXE SPI_I2S_FLAG_TXE +#define SPI_FLAG_OVR SPI_I2S_FLAG_OVR +#define SPI_FLAG_BSY SPI_I2S_FLAG_BSY +#define SPI_DeInit SPI_I2S_DeInit +#define SPI_ITConfig SPI_I2S_ITConfig +#define SPI_DMACmd SPI_I2S_DMACmd +#define SPI_SendData SPI_I2S_SendData +#define SPI_ReceiveData SPI_I2S_ReceiveData +#define SPI_GetFlagStatus SPI_I2S_GetFlagStatus +#define SPI_ClearFlag SPI_I2S_ClearFlag +#define SPI_GetITStatus SPI_I2S_GetITStatus +#define SPI_ClearITPendingBit SPI_I2S_ClearITPendingBit +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the SPI configuration to the default reset state *****/ +void SPI_I2S_DeInit(SPI_TypeDef* SPIx); + +/* Initialization and Configuration functions *********************************/ +void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct); +void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct); +void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct); +void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct); +void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); +void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); +void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize); +void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction); +void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft); +void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState); +void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState); + +void I2S_FullDuplexConfig(SPI_TypeDef* I2Sxext, I2S_InitTypeDef* I2S_InitStruct); + +/* Data transfers functions ***************************************************/ +void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data); +uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx); + +/* Hardware CRC Calculation functions *****************************************/ +void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState); +void SPI_TransmitCRC(SPI_TypeDef* SPIx); +uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC); +uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx); + +/* DMA transfers management functions *****************************************/ +void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState); +FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); +void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); +ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); +void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_SPI_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_syscfg.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_syscfg.h new file mode 100644 index 0000000..e8505e7 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_syscfg.h @@ -0,0 +1,173 @@ +/** + ****************************************************************************** + * @file stm32f4xx_syscfg.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the SYSCFG firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_SYSCFG_H +#define __STM32F4xx_SYSCFG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup SYSCFG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup SYSCFG_Exported_Constants + * @{ + */ + +/** @defgroup SYSCFG_EXTI_Port_Sources + * @{ + */ +#define EXTI_PortSourceGPIOA ((uint8_t)0x00) +#define EXTI_PortSourceGPIOB ((uint8_t)0x01) +#define EXTI_PortSourceGPIOC ((uint8_t)0x02) +#define EXTI_PortSourceGPIOD ((uint8_t)0x03) +#define EXTI_PortSourceGPIOE ((uint8_t)0x04) +#define EXTI_PortSourceGPIOF ((uint8_t)0x05) +#define EXTI_PortSourceGPIOG ((uint8_t)0x06) +#define EXTI_PortSourceGPIOH ((uint8_t)0x07) +#define EXTI_PortSourceGPIOI ((uint8_t)0x08) + +#define IS_EXTI_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == EXTI_PortSourceGPIOA) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOB) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOC) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOD) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOE) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOF) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOG) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOH) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOI)) +/** + * @} + */ + + +/** @defgroup SYSCFG_EXTI_Pin_Sources + * @{ + */ +#define EXTI_PinSource0 ((uint8_t)0x00) +#define EXTI_PinSource1 ((uint8_t)0x01) +#define EXTI_PinSource2 ((uint8_t)0x02) +#define EXTI_PinSource3 ((uint8_t)0x03) +#define EXTI_PinSource4 ((uint8_t)0x04) +#define EXTI_PinSource5 ((uint8_t)0x05) +#define EXTI_PinSource6 ((uint8_t)0x06) +#define EXTI_PinSource7 ((uint8_t)0x07) +#define EXTI_PinSource8 ((uint8_t)0x08) +#define EXTI_PinSource9 ((uint8_t)0x09) +#define EXTI_PinSource10 ((uint8_t)0x0A) +#define EXTI_PinSource11 ((uint8_t)0x0B) +#define EXTI_PinSource12 ((uint8_t)0x0C) +#define EXTI_PinSource13 ((uint8_t)0x0D) +#define EXTI_PinSource14 ((uint8_t)0x0E) +#define EXTI_PinSource15 ((uint8_t)0x0F) +#define IS_EXTI_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == EXTI_PinSource0) || \ + ((PINSOURCE) == EXTI_PinSource1) || \ + ((PINSOURCE) == EXTI_PinSource2) || \ + ((PINSOURCE) == EXTI_PinSource3) || \ + ((PINSOURCE) == EXTI_PinSource4) || \ + ((PINSOURCE) == EXTI_PinSource5) || \ + ((PINSOURCE) == EXTI_PinSource6) || \ + ((PINSOURCE) == EXTI_PinSource7) || \ + ((PINSOURCE) == EXTI_PinSource8) || \ + ((PINSOURCE) == EXTI_PinSource9) || \ + ((PINSOURCE) == EXTI_PinSource10) || \ + ((PINSOURCE) == EXTI_PinSource11) || \ + ((PINSOURCE) == EXTI_PinSource12) || \ + ((PINSOURCE) == EXTI_PinSource13) || \ + ((PINSOURCE) == EXTI_PinSource14) || \ + ((PINSOURCE) == EXTI_PinSource15)) +/** + * @} + */ + + +/** @defgroup SYSCFG_Memory_Remap_Config + * @{ + */ +#define SYSCFG_MemoryRemap_Flash ((uint8_t)0x00) +#define SYSCFG_MemoryRemap_SystemFlash ((uint8_t)0x01) +#define SYSCFG_MemoryRemap_FSMC ((uint8_t)0x02) +#define SYSCFG_MemoryRemap_SRAM ((uint8_t)0x03) + +#define IS_SYSCFG_MEMORY_REMAP_CONFING(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \ + ((REMAP) == SYSCFG_MemoryRemap_SystemFlash) || \ + ((REMAP) == SYSCFG_MemoryRemap_SRAM) || \ + ((REMAP) == SYSCFG_MemoryRemap_FSMC)) +/** + * @} + */ + + +/** @defgroup SYSCFG_ETHERNET_Media_Interface + * @{ + */ +#define SYSCFG_ETH_MediaInterface_MII ((uint32_t)0x00000000) +#define SYSCFG_ETH_MediaInterface_RMII ((uint32_t)0x00000001) + +#define IS_SYSCFG_ETH_MEDIA_INTERFACE(INTERFACE) (((INTERFACE) == SYSCFG_ETH_MediaInterface_MII) || \ + ((INTERFACE) == SYSCFG_ETH_MediaInterface_RMII)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +void SYSCFG_DeInit(void); +void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap); +void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex); +void SYSCFG_ETH_MediaInterfaceConfig(uint32_t SYSCFG_ETH_MediaInterface); +void SYSCFG_CompensationCellCmd(FunctionalState NewState); +FlagStatus SYSCFG_GetCompensationCellStatus(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_SYSCFG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h new file mode 100644 index 0000000..228e81a --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h @@ -0,0 +1,1144 @@ +/** + ****************************************************************************** + * @file stm32f4xx_tim.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the TIM firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_TIM_H +#define __STM32F4xx_TIM_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup TIM + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief TIM Time Base Init structure definition + * @note This structure is used with all TIMx except for TIM6 and TIM7. + */ + +typedef struct +{ + uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between 0x0000 and 0xFFFF */ + + uint16_t TIM_CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_Counter_Mode */ + + uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must be a number between 0x0000 and 0xFFFF. */ + + uint16_t TIM_ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_Clock_Division_CKD */ + + uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter + reaches zero, an update event is generated and counting restarts + from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned mode + This parameter must be a number between 0x00 and 0xFF. + @note This parameter is valid only for TIM1 and TIM8. */ +} TIM_TimeBaseInitTypeDef; + +/** + * @brief TIM Output Compare Init structure definition + */ + +typedef struct +{ + uint16_t TIM_OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint16_t TIM_OutputState; /*!< Specifies the TIM Output Compare state. + This parameter can be a value of @ref TIM_Output_Compare_State */ + + uint16_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state. + This parameter can be a value of @ref TIM_Output_Compare_N_State + @note This parameter is valid only for TIM1 and TIM8. */ + + uint32_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between 0x0000 and 0xFFFF */ + + uint16_t TIM_OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint16_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_Output_Compare_N_Polarity + @note This parameter is valid only for TIM1 and TIM8. */ + + uint16_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_Idle_State + @note This parameter is valid only for TIM1 and TIM8. */ + + uint16_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for TIM1 and TIM8. */ +} TIM_OCInitTypeDef; + +/** + * @brief TIM Input Capture Init structure definition + */ + +typedef struct +{ + + uint16_t TIM_Channel; /*!< Specifies the TIM channel. + This parameter can be a value of @ref TIM_Channel */ + + uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint16_t TIM_ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint16_t TIM_ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between 0x0 and 0xF */ +} TIM_ICInitTypeDef; + +/** + * @brief BDTR structure definition + * @note This structure is used only with TIM1 and TIM8. + */ + +typedef struct +{ + + uint16_t TIM_OSSRState; /*!< Specifies the Off-State selection used in Run mode. + This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */ + + uint16_t TIM_OSSIState; /*!< Specifies the Off-State used in Idle state. + This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */ + + uint16_t TIM_LOCKLevel; /*!< Specifies the LOCK level parameters. + This parameter can be a value of @ref TIM_Lock_level */ + + uint16_t TIM_DeadTime; /*!< Specifies the delay time between the switching-off and the + switching-on of the outputs. + This parameter can be a number between 0x00 and 0xFF */ + + uint16_t TIM_Break; /*!< Specifies whether the TIM Break input is enabled or not. + This parameter can be a value of @ref TIM_Break_Input_enable_disable */ + + uint16_t TIM_BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. + This parameter can be a value of @ref TIM_Break_Polarity */ + + uint16_t TIM_AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not. + This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */ +} TIM_BDTRInitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup TIM_Exported_constants + * @{ + */ + +#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM6) || \ + ((PERIPH) == TIM7) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM10) || \ + ((PERIPH) == TIM11) || \ + ((PERIPH) == TIM12) || \ + (((PERIPH) == TIM13) || \ + ((PERIPH) == TIM14))) +/* LIST1: TIM1, TIM2, TIM3, TIM4, TIM5, TIM8, TIM9, TIM10, TIM11, TIM12, TIM13 and TIM14 */ +#define IS_TIM_LIST1_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM10) || \ + ((PERIPH) == TIM11) || \ + ((PERIPH) == TIM12) || \ + ((PERIPH) == TIM13) || \ + ((PERIPH) == TIM14)) + +/* LIST2: TIM1, TIM2, TIM3, TIM4, TIM5, TIM8, TIM9 and TIM12 */ +#define IS_TIM_LIST2_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM12)) +/* LIST3: TIM1, TIM2, TIM3, TIM4, TIM5 and TIM8 */ +#define IS_TIM_LIST3_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8)) +/* LIST4: TIM1 and TIM8 */ +#define IS_TIM_LIST4_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM8)) +/* LIST5: TIM1, TIM2, TIM3, TIM4, TIM5, TIM6, TIM7 and TIM8 */ +#define IS_TIM_LIST5_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM6) || \ + ((PERIPH) == TIM7) || \ + ((PERIPH) == TIM8)) +/* LIST6: TIM2, TIM5 and TIM11 */ +#define IS_TIM_LIST6_PERIPH(TIMx)(((TIMx) == TIM2) || \ + ((TIMx) == TIM5) || \ + ((TIMx) == TIM11)) + +/** @defgroup TIM_Output_Compare_and_PWM_modes + * @{ + */ + +#define TIM_OCMode_Timing ((uint16_t)0x0000) +#define TIM_OCMode_Active ((uint16_t)0x0010) +#define TIM_OCMode_Inactive ((uint16_t)0x0020) +#define TIM_OCMode_Toggle ((uint16_t)0x0030) +#define TIM_OCMode_PWM1 ((uint16_t)0x0060) +#define TIM_OCMode_PWM2 ((uint16_t)0x0070) +#define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMode_Timing) || \ + ((MODE) == TIM_OCMode_Active) || \ + ((MODE) == TIM_OCMode_Inactive) || \ + ((MODE) == TIM_OCMode_Toggle)|| \ + ((MODE) == TIM_OCMode_PWM1) || \ + ((MODE) == TIM_OCMode_PWM2)) +#define IS_TIM_OCM(MODE) (((MODE) == TIM_OCMode_Timing) || \ + ((MODE) == TIM_OCMode_Active) || \ + ((MODE) == TIM_OCMode_Inactive) || \ + ((MODE) == TIM_OCMode_Toggle)|| \ + ((MODE) == TIM_OCMode_PWM1) || \ + ((MODE) == TIM_OCMode_PWM2) || \ + ((MODE) == TIM_ForcedAction_Active) || \ + ((MODE) == TIM_ForcedAction_InActive)) +/** + * @} + */ + +/** @defgroup TIM_One_Pulse_Mode + * @{ + */ + +#define TIM_OPMode_Single ((uint16_t)0x0008) +#define TIM_OPMode_Repetitive ((uint16_t)0x0000) +#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMode_Single) || \ + ((MODE) == TIM_OPMode_Repetitive)) +/** + * @} + */ + +/** @defgroup TIM_Channel + * @{ + */ + +#define TIM_Channel_1 ((uint16_t)0x0000) +#define TIM_Channel_2 ((uint16_t)0x0004) +#define TIM_Channel_3 ((uint16_t)0x0008) +#define TIM_Channel_4 ((uint16_t)0x000C) + +#define IS_TIM_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2) || \ + ((CHANNEL) == TIM_Channel_3) || \ + ((CHANNEL) == TIM_Channel_4)) + +#define IS_TIM_PWMI_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2)) +#define IS_TIM_COMPLEMENTARY_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2) || \ + ((CHANNEL) == TIM_Channel_3)) +/** + * @} + */ + +/** @defgroup TIM_Clock_Division_CKD + * @{ + */ + +#define TIM_CKD_DIV1 ((uint16_t)0x0000) +#define TIM_CKD_DIV2 ((uint16_t)0x0100) +#define TIM_CKD_DIV4 ((uint16_t)0x0200) +#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \ + ((DIV) == TIM_CKD_DIV2) || \ + ((DIV) == TIM_CKD_DIV4)) +/** + * @} + */ + +/** @defgroup TIM_Counter_Mode + * @{ + */ + +#define TIM_CounterMode_Up ((uint16_t)0x0000) +#define TIM_CounterMode_Down ((uint16_t)0x0010) +#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020) +#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040) +#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) +#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) || \ + ((MODE) == TIM_CounterMode_Down) || \ + ((MODE) == TIM_CounterMode_CenterAligned1) || \ + ((MODE) == TIM_CounterMode_CenterAligned2) || \ + ((MODE) == TIM_CounterMode_CenterAligned3)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Polarity + * @{ + */ + +#define TIM_OCPolarity_High ((uint16_t)0x0000) +#define TIM_OCPolarity_Low ((uint16_t)0x0002) +#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \ + ((POLARITY) == TIM_OCPolarity_Low)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Polarity + * @{ + */ + +#define TIM_OCNPolarity_High ((uint16_t)0x0000) +#define TIM_OCNPolarity_Low ((uint16_t)0x0008) +#define IS_TIM_OCN_POLARITY(POLARITY) (((POLARITY) == TIM_OCNPolarity_High) || \ + ((POLARITY) == TIM_OCNPolarity_Low)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_State + * @{ + */ + +#define TIM_OutputState_Disable ((uint16_t)0x0000) +#define TIM_OutputState_Enable ((uint16_t)0x0001) +#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OutputState_Disable) || \ + ((STATE) == TIM_OutputState_Enable)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_State + * @{ + */ + +#define TIM_OutputNState_Disable ((uint16_t)0x0000) +#define TIM_OutputNState_Enable ((uint16_t)0x0004) +#define IS_TIM_OUTPUTN_STATE(STATE) (((STATE) == TIM_OutputNState_Disable) || \ + ((STATE) == TIM_OutputNState_Enable)) +/** + * @} + */ + +/** @defgroup TIM_Capture_Compare_State + * @{ + */ + +#define TIM_CCx_Enable ((uint16_t)0x0001) +#define TIM_CCx_Disable ((uint16_t)0x0000) +#define IS_TIM_CCX(CCX) (((CCX) == TIM_CCx_Enable) || \ + ((CCX) == TIM_CCx_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Capture_Compare_N_State + * @{ + */ + +#define TIM_CCxN_Enable ((uint16_t)0x0004) +#define TIM_CCxN_Disable ((uint16_t)0x0000) +#define IS_TIM_CCXN(CCXN) (((CCXN) == TIM_CCxN_Enable) || \ + ((CCXN) == TIM_CCxN_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Break_Input_enable_disable + * @{ + */ + +#define TIM_Break_Enable ((uint16_t)0x1000) +#define TIM_Break_Disable ((uint16_t)0x0000) +#define IS_TIM_BREAK_STATE(STATE) (((STATE) == TIM_Break_Enable) || \ + ((STATE) == TIM_Break_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Break_Polarity + * @{ + */ + +#define TIM_BreakPolarity_Low ((uint16_t)0x0000) +#define TIM_BreakPolarity_High ((uint16_t)0x2000) +#define IS_TIM_BREAK_POLARITY(POLARITY) (((POLARITY) == TIM_BreakPolarity_Low) || \ + ((POLARITY) == TIM_BreakPolarity_High)) +/** + * @} + */ + +/** @defgroup TIM_AOE_Bit_Set_Reset + * @{ + */ + +#define TIM_AutomaticOutput_Enable ((uint16_t)0x4000) +#define TIM_AutomaticOutput_Disable ((uint16_t)0x0000) +#define IS_TIM_AUTOMATIC_OUTPUT_STATE(STATE) (((STATE) == TIM_AutomaticOutput_Enable) || \ + ((STATE) == TIM_AutomaticOutput_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Lock_level + * @{ + */ + +#define TIM_LOCKLevel_OFF ((uint16_t)0x0000) +#define TIM_LOCKLevel_1 ((uint16_t)0x0100) +#define TIM_LOCKLevel_2 ((uint16_t)0x0200) +#define TIM_LOCKLevel_3 ((uint16_t)0x0300) +#define IS_TIM_LOCK_LEVEL(LEVEL) (((LEVEL) == TIM_LOCKLevel_OFF) || \ + ((LEVEL) == TIM_LOCKLevel_1) || \ + ((LEVEL) == TIM_LOCKLevel_2) || \ + ((LEVEL) == TIM_LOCKLevel_3)) +/** + * @} + */ + +/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state + * @{ + */ + +#define TIM_OSSIState_Enable ((uint16_t)0x0400) +#define TIM_OSSIState_Disable ((uint16_t)0x0000) +#define IS_TIM_OSSI_STATE(STATE) (((STATE) == TIM_OSSIState_Enable) || \ + ((STATE) == TIM_OSSIState_Disable)) +/** + * @} + */ + +/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state + * @{ + */ + +#define TIM_OSSRState_Enable ((uint16_t)0x0800) +#define TIM_OSSRState_Disable ((uint16_t)0x0000) +#define IS_TIM_OSSR_STATE(STATE) (((STATE) == TIM_OSSRState_Enable) || \ + ((STATE) == TIM_OSSRState_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Idle_State + * @{ + */ + +#define TIM_OCIdleState_Set ((uint16_t)0x0100) +#define TIM_OCIdleState_Reset ((uint16_t)0x0000) +#define IS_TIM_OCIDLE_STATE(STATE) (((STATE) == TIM_OCIdleState_Set) || \ + ((STATE) == TIM_OCIdleState_Reset)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Idle_State + * @{ + */ + +#define TIM_OCNIdleState_Set ((uint16_t)0x0200) +#define TIM_OCNIdleState_Reset ((uint16_t)0x0000) +#define IS_TIM_OCNIDLE_STATE(STATE) (((STATE) == TIM_OCNIdleState_Set) || \ + ((STATE) == TIM_OCNIdleState_Reset)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Polarity + * @{ + */ + +#define TIM_ICPolarity_Rising ((uint16_t)0x0000) +#define TIM_ICPolarity_Falling ((uint16_t)0x0002) +#define TIM_ICPolarity_BothEdge ((uint16_t)0x000A) +#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \ + ((POLARITY) == TIM_ICPolarity_Falling)|| \ + ((POLARITY) == TIM_ICPolarity_BothEdge)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Selection + * @{ + */ + +#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC1, IC2, IC3 or IC4, respectively */ +#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC2, IC1, IC4 or IC3, respectively. */ +#define TIM_ICSelection_TRC ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. */ +#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSelection_DirectTI) || \ + ((SELECTION) == TIM_ICSelection_IndirectTI) || \ + ((SELECTION) == TIM_ICSelection_TRC)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Prescaler + * @{ + */ + +#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. */ +#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) /*!< Capture performed once every 2 events. */ +#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) /*!< Capture performed once every 4 events. */ +#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) /*!< Capture performed once every 8 events. */ +#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \ + ((PRESCALER) == TIM_ICPSC_DIV2) || \ + ((PRESCALER) == TIM_ICPSC_DIV4) || \ + ((PRESCALER) == TIM_ICPSC_DIV8)) +/** + * @} + */ + +/** @defgroup TIM_interrupt_sources + * @{ + */ + +#define TIM_IT_Update ((uint16_t)0x0001) +#define TIM_IT_CC1 ((uint16_t)0x0002) +#define TIM_IT_CC2 ((uint16_t)0x0004) +#define TIM_IT_CC3 ((uint16_t)0x0008) +#define TIM_IT_CC4 ((uint16_t)0x0010) +#define TIM_IT_COM ((uint16_t)0x0020) +#define TIM_IT_Trigger ((uint16_t)0x0040) +#define TIM_IT_Break ((uint16_t)0x0080) +#define IS_TIM_IT(IT) ((((IT) & (uint16_t)0xFF00) == 0x0000) && ((IT) != 0x0000)) + +#define IS_TIM_GET_IT(IT) (((IT) == TIM_IT_Update) || \ + ((IT) == TIM_IT_CC1) || \ + ((IT) == TIM_IT_CC2) || \ + ((IT) == TIM_IT_CC3) || \ + ((IT) == TIM_IT_CC4) || \ + ((IT) == TIM_IT_COM) || \ + ((IT) == TIM_IT_Trigger) || \ + ((IT) == TIM_IT_Break)) +/** + * @} + */ + +/** @defgroup TIM_DMA_Base_address + * @{ + */ + +#define TIM_DMABase_CR1 ((uint16_t)0x0000) +#define TIM_DMABase_CR2 ((uint16_t)0x0001) +#define TIM_DMABase_SMCR ((uint16_t)0x0002) +#define TIM_DMABase_DIER ((uint16_t)0x0003) +#define TIM_DMABase_SR ((uint16_t)0x0004) +#define TIM_DMABase_EGR ((uint16_t)0x0005) +#define TIM_DMABase_CCMR1 ((uint16_t)0x0006) +#define TIM_DMABase_CCMR2 ((uint16_t)0x0007) +#define TIM_DMABase_CCER ((uint16_t)0x0008) +#define TIM_DMABase_CNT ((uint16_t)0x0009) +#define TIM_DMABase_PSC ((uint16_t)0x000A) +#define TIM_DMABase_ARR ((uint16_t)0x000B) +#define TIM_DMABase_RCR ((uint16_t)0x000C) +#define TIM_DMABase_CCR1 ((uint16_t)0x000D) +#define TIM_DMABase_CCR2 ((uint16_t)0x000E) +#define TIM_DMABase_CCR3 ((uint16_t)0x000F) +#define TIM_DMABase_CCR4 ((uint16_t)0x0010) +#define TIM_DMABase_BDTR ((uint16_t)0x0011) +#define TIM_DMABase_DCR ((uint16_t)0x0012) +#define TIM_DMABase_OR ((uint16_t)0x0013) +#define IS_TIM_DMA_BASE(BASE) (((BASE) == TIM_DMABase_CR1) || \ + ((BASE) == TIM_DMABase_CR2) || \ + ((BASE) == TIM_DMABase_SMCR) || \ + ((BASE) == TIM_DMABase_DIER) || \ + ((BASE) == TIM_DMABase_SR) || \ + ((BASE) == TIM_DMABase_EGR) || \ + ((BASE) == TIM_DMABase_CCMR1) || \ + ((BASE) == TIM_DMABase_CCMR2) || \ + ((BASE) == TIM_DMABase_CCER) || \ + ((BASE) == TIM_DMABase_CNT) || \ + ((BASE) == TIM_DMABase_PSC) || \ + ((BASE) == TIM_DMABase_ARR) || \ + ((BASE) == TIM_DMABase_RCR) || \ + ((BASE) == TIM_DMABase_CCR1) || \ + ((BASE) == TIM_DMABase_CCR2) || \ + ((BASE) == TIM_DMABase_CCR3) || \ + ((BASE) == TIM_DMABase_CCR4) || \ + ((BASE) == TIM_DMABase_BDTR) || \ + ((BASE) == TIM_DMABase_DCR) || \ + ((BASE) == TIM_DMABase_OR)) +/** + * @} + */ + +/** @defgroup TIM_DMA_Burst_Length + * @{ + */ + +#define TIM_DMABurstLength_1Transfer ((uint16_t)0x0000) +#define TIM_DMABurstLength_2Transfers ((uint16_t)0x0100) +#define TIM_DMABurstLength_3Transfers ((uint16_t)0x0200) +#define TIM_DMABurstLength_4Transfers ((uint16_t)0x0300) +#define TIM_DMABurstLength_5Transfers ((uint16_t)0x0400) +#define TIM_DMABurstLength_6Transfers ((uint16_t)0x0500) +#define TIM_DMABurstLength_7Transfers ((uint16_t)0x0600) +#define TIM_DMABurstLength_8Transfers ((uint16_t)0x0700) +#define TIM_DMABurstLength_9Transfers ((uint16_t)0x0800) +#define TIM_DMABurstLength_10Transfers ((uint16_t)0x0900) +#define TIM_DMABurstLength_11Transfers ((uint16_t)0x0A00) +#define TIM_DMABurstLength_12Transfers ((uint16_t)0x0B00) +#define TIM_DMABurstLength_13Transfers ((uint16_t)0x0C00) +#define TIM_DMABurstLength_14Transfers ((uint16_t)0x0D00) +#define TIM_DMABurstLength_15Transfers ((uint16_t)0x0E00) +#define TIM_DMABurstLength_16Transfers ((uint16_t)0x0F00) +#define TIM_DMABurstLength_17Transfers ((uint16_t)0x1000) +#define TIM_DMABurstLength_18Transfers ((uint16_t)0x1100) +#define IS_TIM_DMA_LENGTH(LENGTH) (((LENGTH) == TIM_DMABurstLength_1Transfer) || \ + ((LENGTH) == TIM_DMABurstLength_2Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_3Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_4Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_5Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_6Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_7Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_8Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_9Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_10Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_11Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_12Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_13Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_14Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_15Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_16Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_17Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_18Transfers)) +/** + * @} + */ + +/** @defgroup TIM_DMA_sources + * @{ + */ + +#define TIM_DMA_Update ((uint16_t)0x0100) +#define TIM_DMA_CC1 ((uint16_t)0x0200) +#define TIM_DMA_CC2 ((uint16_t)0x0400) +#define TIM_DMA_CC3 ((uint16_t)0x0800) +#define TIM_DMA_CC4 ((uint16_t)0x1000) +#define TIM_DMA_COM ((uint16_t)0x2000) +#define TIM_DMA_Trigger ((uint16_t)0x4000) +#define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0x80FF) == 0x0000) && ((SOURCE) != 0x0000)) + +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Prescaler + * @{ + */ + +#define TIM_ExtTRGPSC_OFF ((uint16_t)0x0000) +#define TIM_ExtTRGPSC_DIV2 ((uint16_t)0x1000) +#define TIM_ExtTRGPSC_DIV4 ((uint16_t)0x2000) +#define TIM_ExtTRGPSC_DIV8 ((uint16_t)0x3000) +#define IS_TIM_EXT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ExtTRGPSC_OFF) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV2) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV4) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV8)) +/** + * @} + */ + +/** @defgroup TIM_Internal_Trigger_Selection + * @{ + */ + +#define TIM_TS_ITR0 ((uint16_t)0x0000) +#define TIM_TS_ITR1 ((uint16_t)0x0010) +#define TIM_TS_ITR2 ((uint16_t)0x0020) +#define TIM_TS_ITR3 ((uint16_t)0x0030) +#define TIM_TS_TI1F_ED ((uint16_t)0x0040) +#define TIM_TS_TI1FP1 ((uint16_t)0x0050) +#define TIM_TS_TI2FP2 ((uint16_t)0x0060) +#define TIM_TS_ETRF ((uint16_t)0x0070) +#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3) || \ + ((SELECTION) == TIM_TS_TI1F_ED) || \ + ((SELECTION) == TIM_TS_TI1FP1) || \ + ((SELECTION) == TIM_TS_TI2FP2) || \ + ((SELECTION) == TIM_TS_ETRF)) +#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3)) +/** + * @} + */ + +/** @defgroup TIM_TIx_External_Clock_Source + * @{ + */ + +#define TIM_TIxExternalCLK1Source_TI1 ((uint16_t)0x0050) +#define TIM_TIxExternalCLK1Source_TI2 ((uint16_t)0x0060) +#define TIM_TIxExternalCLK1Source_TI1ED ((uint16_t)0x0040) + +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Polarity + * @{ + */ +#define TIM_ExtTRGPolarity_Inverted ((uint16_t)0x8000) +#define TIM_ExtTRGPolarity_NonInverted ((uint16_t)0x0000) +#define IS_TIM_EXT_POLARITY(POLARITY) (((POLARITY) == TIM_ExtTRGPolarity_Inverted) || \ + ((POLARITY) == TIM_ExtTRGPolarity_NonInverted)) +/** + * @} + */ + +/** @defgroup TIM_Prescaler_Reload_Mode + * @{ + */ + +#define TIM_PSCReloadMode_Update ((uint16_t)0x0000) +#define TIM_PSCReloadMode_Immediate ((uint16_t)0x0001) +#define IS_TIM_PRESCALER_RELOAD(RELOAD) (((RELOAD) == TIM_PSCReloadMode_Update) || \ + ((RELOAD) == TIM_PSCReloadMode_Immediate)) +/** + * @} + */ + +/** @defgroup TIM_Forced_Action + * @{ + */ + +#define TIM_ForcedAction_Active ((uint16_t)0x0050) +#define TIM_ForcedAction_InActive ((uint16_t)0x0040) +#define IS_TIM_FORCED_ACTION(ACTION) (((ACTION) == TIM_ForcedAction_Active) || \ + ((ACTION) == TIM_ForcedAction_InActive)) +/** + * @} + */ + +/** @defgroup TIM_Encoder_Mode + * @{ + */ + +#define TIM_EncoderMode_TI1 ((uint16_t)0x0001) +#define TIM_EncoderMode_TI2 ((uint16_t)0x0002) +#define TIM_EncoderMode_TI12 ((uint16_t)0x0003) +#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_EncoderMode_TI1) || \ + ((MODE) == TIM_EncoderMode_TI2) || \ + ((MODE) == TIM_EncoderMode_TI12)) +/** + * @} + */ + + +/** @defgroup TIM_Event_Source + * @{ + */ + +#define TIM_EventSource_Update ((uint16_t)0x0001) +#define TIM_EventSource_CC1 ((uint16_t)0x0002) +#define TIM_EventSource_CC2 ((uint16_t)0x0004) +#define TIM_EventSource_CC3 ((uint16_t)0x0008) +#define TIM_EventSource_CC4 ((uint16_t)0x0010) +#define TIM_EventSource_COM ((uint16_t)0x0020) +#define TIM_EventSource_Trigger ((uint16_t)0x0040) +#define TIM_EventSource_Break ((uint16_t)0x0080) +#define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xFF00) == 0x0000) && ((SOURCE) != 0x0000)) + +/** + * @} + */ + +/** @defgroup TIM_Update_Source + * @{ + */ + +#define TIM_UpdateSource_Global ((uint16_t)0x0000) /*!< Source of update is the counter overflow/underflow + or the setting of UG bit, or an update generation + through the slave mode controller. */ +#define TIM_UpdateSource_Regular ((uint16_t)0x0001) /*!< Source of update is counter overflow/underflow. */ +#define IS_TIM_UPDATE_SOURCE(SOURCE) (((SOURCE) == TIM_UpdateSource_Global) || \ + ((SOURCE) == TIM_UpdateSource_Regular)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Preload_State + * @{ + */ + +#define TIM_OCPreload_Enable ((uint16_t)0x0008) +#define TIM_OCPreload_Disable ((uint16_t)0x0000) +#define IS_TIM_OCPRELOAD_STATE(STATE) (((STATE) == TIM_OCPreload_Enable) || \ + ((STATE) == TIM_OCPreload_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Fast_State + * @{ + */ + +#define TIM_OCFast_Enable ((uint16_t)0x0004) +#define TIM_OCFast_Disable ((uint16_t)0x0000) +#define IS_TIM_OCFAST_STATE(STATE) (((STATE) == TIM_OCFast_Enable) || \ + ((STATE) == TIM_OCFast_Disable)) + +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Clear_State + * @{ + */ + +#define TIM_OCClear_Enable ((uint16_t)0x0080) +#define TIM_OCClear_Disable ((uint16_t)0x0000) +#define IS_TIM_OCCLEAR_STATE(STATE) (((STATE) == TIM_OCClear_Enable) || \ + ((STATE) == TIM_OCClear_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Trigger_Output_Source + * @{ + */ + +#define TIM_TRGOSource_Reset ((uint16_t)0x0000) +#define TIM_TRGOSource_Enable ((uint16_t)0x0010) +#define TIM_TRGOSource_Update ((uint16_t)0x0020) +#define TIM_TRGOSource_OC1 ((uint16_t)0x0030) +#define TIM_TRGOSource_OC1Ref ((uint16_t)0x0040) +#define TIM_TRGOSource_OC2Ref ((uint16_t)0x0050) +#define TIM_TRGOSource_OC3Ref ((uint16_t)0x0060) +#define TIM_TRGOSource_OC4Ref ((uint16_t)0x0070) +#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGOSource_Reset) || \ + ((SOURCE) == TIM_TRGOSource_Enable) || \ + ((SOURCE) == TIM_TRGOSource_Update) || \ + ((SOURCE) == TIM_TRGOSource_OC1) || \ + ((SOURCE) == TIM_TRGOSource_OC1Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC2Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC3Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC4Ref)) +/** + * @} + */ + +/** @defgroup TIM_Slave_Mode + * @{ + */ + +#define TIM_SlaveMode_Reset ((uint16_t)0x0004) +#define TIM_SlaveMode_Gated ((uint16_t)0x0005) +#define TIM_SlaveMode_Trigger ((uint16_t)0x0006) +#define TIM_SlaveMode_External1 ((uint16_t)0x0007) +#define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SlaveMode_Reset) || \ + ((MODE) == TIM_SlaveMode_Gated) || \ + ((MODE) == TIM_SlaveMode_Trigger) || \ + ((MODE) == TIM_SlaveMode_External1)) +/** + * @} + */ + +/** @defgroup TIM_Master_Slave_Mode + * @{ + */ + +#define TIM_MasterSlaveMode_Enable ((uint16_t)0x0080) +#define TIM_MasterSlaveMode_Disable ((uint16_t)0x0000) +#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MasterSlaveMode_Enable) || \ + ((STATE) == TIM_MasterSlaveMode_Disable)) +/** + * @} + */ +/** @defgroup TIM_Remap + * @{ + */ + +#define TIM2_TIM8_TRGO ((uint16_t)0x0000) +#define TIM2_ETH_PTP ((uint16_t)0x0400) +#define TIM2_USBFS_SOF ((uint16_t)0x0800) +#define TIM2_USBHS_SOF ((uint16_t)0x0C00) + +#define TIM5_GPIO ((uint16_t)0x0000) +#define TIM5_LSI ((uint16_t)0x0040) +#define TIM5_LSE ((uint16_t)0x0080) +#define TIM5_RTC ((uint16_t)0x00C0) + +#define TIM11_GPIO ((uint16_t)0x0000) +#define TIM11_HSE ((uint16_t)0x0002) + +#define IS_TIM_REMAP(TIM_REMAP) (((TIM_REMAP) == TIM2_TIM8_TRGO)||\ + ((TIM_REMAP) == TIM2_ETH_PTP)||\ + ((TIM_REMAP) == TIM2_USBFS_SOF)||\ + ((TIM_REMAP) == TIM2_USBHS_SOF)||\ + ((TIM_REMAP) == TIM5_GPIO)||\ + ((TIM_REMAP) == TIM5_LSI)||\ + ((TIM_REMAP) == TIM5_LSE)||\ + ((TIM_REMAP) == TIM5_RTC)||\ + ((TIM_REMAP) == TIM11_GPIO)||\ + ((TIM_REMAP) == TIM11_HSE)) + +/** + * @} + */ +/** @defgroup TIM_Flags + * @{ + */ + +#define TIM_FLAG_Update ((uint16_t)0x0001) +#define TIM_FLAG_CC1 ((uint16_t)0x0002) +#define TIM_FLAG_CC2 ((uint16_t)0x0004) +#define TIM_FLAG_CC3 ((uint16_t)0x0008) +#define TIM_FLAG_CC4 ((uint16_t)0x0010) +#define TIM_FLAG_COM ((uint16_t)0x0020) +#define TIM_FLAG_Trigger ((uint16_t)0x0040) +#define TIM_FLAG_Break ((uint16_t)0x0080) +#define TIM_FLAG_CC1OF ((uint16_t)0x0200) +#define TIM_FLAG_CC2OF ((uint16_t)0x0400) +#define TIM_FLAG_CC3OF ((uint16_t)0x0800) +#define TIM_FLAG_CC4OF ((uint16_t)0x1000) +#define IS_TIM_GET_FLAG(FLAG) (((FLAG) == TIM_FLAG_Update) || \ + ((FLAG) == TIM_FLAG_CC1) || \ + ((FLAG) == TIM_FLAG_CC2) || \ + ((FLAG) == TIM_FLAG_CC3) || \ + ((FLAG) == TIM_FLAG_CC4) || \ + ((FLAG) == TIM_FLAG_COM) || \ + ((FLAG) == TIM_FLAG_Trigger) || \ + ((FLAG) == TIM_FLAG_Break) || \ + ((FLAG) == TIM_FLAG_CC1OF) || \ + ((FLAG) == TIM_FLAG_CC2OF) || \ + ((FLAG) == TIM_FLAG_CC3OF) || \ + ((FLAG) == TIM_FLAG_CC4OF)) + +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Filer_Value + * @{ + */ + +#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF) +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Filter + * @{ + */ + +#define IS_TIM_EXT_FILTER(EXTFILTER) ((EXTFILTER) <= 0xF) +/** + * @} + */ + +/** @defgroup TIM_Legacy + * @{ + */ + +#define TIM_DMABurstLength_1Byte TIM_DMABurstLength_1Transfer +#define TIM_DMABurstLength_2Bytes TIM_DMABurstLength_2Transfers +#define TIM_DMABurstLength_3Bytes TIM_DMABurstLength_3Transfers +#define TIM_DMABurstLength_4Bytes TIM_DMABurstLength_4Transfers +#define TIM_DMABurstLength_5Bytes TIM_DMABurstLength_5Transfers +#define TIM_DMABurstLength_6Bytes TIM_DMABurstLength_6Transfers +#define TIM_DMABurstLength_7Bytes TIM_DMABurstLength_7Transfers +#define TIM_DMABurstLength_8Bytes TIM_DMABurstLength_8Transfers +#define TIM_DMABurstLength_9Bytes TIM_DMABurstLength_9Transfers +#define TIM_DMABurstLength_10Bytes TIM_DMABurstLength_10Transfers +#define TIM_DMABurstLength_11Bytes TIM_DMABurstLength_11Transfers +#define TIM_DMABurstLength_12Bytes TIM_DMABurstLength_12Transfers +#define TIM_DMABurstLength_13Bytes TIM_DMABurstLength_13Transfers +#define TIM_DMABurstLength_14Bytes TIM_DMABurstLength_14Transfers +#define TIM_DMABurstLength_15Bytes TIM_DMABurstLength_15Transfers +#define TIM_DMABurstLength_16Bytes TIM_DMABurstLength_16Transfers +#define TIM_DMABurstLength_17Bytes TIM_DMABurstLength_17Transfers +#define TIM_DMABurstLength_18Bytes TIM_DMABurstLength_18Transfers +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* TimeBase management ********************************************************/ +void TIM_DeInit(TIM_TypeDef* TIMx); +void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); +void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode); +void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode); +void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter); +void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload); +uint32_t TIM_GetCounter(TIM_TypeDef* TIMx); +uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx); +void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource); +void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode); +void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD); +void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Output Compare management **************************************************/ +void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode); +void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1); +void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2); +void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3); +void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4); +void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); +void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); +void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); +void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx); +void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN); + +/* Input Capture management ***************************************************/ +void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); +void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct); +void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); +uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx); +void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); + +/* Advanced-control timers (TIM1 and TIM8) specific features ******************/ +void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct); +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct); +void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Interrupts, DMA and flags management ***************************************/ +void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); +void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource); +FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); +void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); +ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT); +void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT); +void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength); +void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState); +void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Clocks management **********************************************************/ +void TIM_InternalClockConfig(TIM_TypeDef* TIMx); +void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); +void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, + uint16_t TIM_ICPolarity, uint16_t ICFilter); +void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter); +void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); + +/* Synchronization management *************************************************/ +void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); +void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); +void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); +void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode); +void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter); + +/* Specific interface management **********************************************/ +void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, + uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity); +void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Specific remapping management **********************************************/ +void TIM_RemapConfig(TIM_TypeDef* TIMx, uint16_t TIM_Remap); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_TIM_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_usart.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_usart.h new file mode 100644 index 0000000..c4025e3 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_usart.h @@ -0,0 +1,423 @@ +/** + ****************************************************************************** + * @file stm32f4xx_usart.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the USART + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_USART_H +#define __STM32F4xx_USART_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup USART + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief USART Init Structure definition + */ + +typedef struct +{ + uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate. + The baud rate is computed using the following formula: + - IntegerDivider = ((PCLKx) / (8 * (OVR8+1) * (USART_InitStruct->USART_BaudRate))) + - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 8 * (OVR8+1)) + 0.5 + Where OVR8 is the "oversampling by 8 mode" configuration bit in the CR1 register. */ + + uint16_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref USART_Word_Length */ + + uint16_t USART_StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref USART_Stop_Bits */ + + uint16_t USART_Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref USART_Parity + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits). */ + + uint16_t USART_Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref USART_Mode */ + + uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled + or disabled. + This parameter can be a value of @ref USART_Hardware_Flow_Control */ +} USART_InitTypeDef; + +/** + * @brief USART Clock Init Structure definition + */ + +typedef struct +{ + + uint16_t USART_Clock; /*!< Specifies whether the USART clock is enabled or disabled. + This parameter can be a value of @ref USART_Clock */ + + uint16_t USART_CPOL; /*!< Specifies the steady state of the serial clock. + This parameter can be a value of @ref USART_Clock_Polarity */ + + uint16_t USART_CPHA; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref USART_Clock_Phase */ + + uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted + data bit (MSB) has to be output on the SCLK pin in synchronous mode. + This parameter can be a value of @ref USART_Last_Bit */ +} USART_ClockInitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup USART_Exported_Constants + * @{ + */ + +#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \ + ((PERIPH) == USART2) || \ + ((PERIPH) == USART3) || \ + ((PERIPH) == UART4) || \ + ((PERIPH) == UART5) || \ + ((PERIPH) == USART6)) + +#define IS_USART_1236_PERIPH(PERIPH) (((PERIPH) == USART1) || \ + ((PERIPH) == USART2) || \ + ((PERIPH) == USART3) || \ + ((PERIPH) == USART6)) + +/** @defgroup USART_Word_Length + * @{ + */ + +#define USART_WordLength_8b ((uint16_t)0x0000) +#define USART_WordLength_9b ((uint16_t)0x1000) + +#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \ + ((LENGTH) == USART_WordLength_9b)) +/** + * @} + */ + +/** @defgroup USART_Stop_Bits + * @{ + */ + +#define USART_StopBits_1 ((uint16_t)0x0000) +#define USART_StopBits_0_5 ((uint16_t)0x1000) +#define USART_StopBits_2 ((uint16_t)0x2000) +#define USART_StopBits_1_5 ((uint16_t)0x3000) +#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \ + ((STOPBITS) == USART_StopBits_0_5) || \ + ((STOPBITS) == USART_StopBits_2) || \ + ((STOPBITS) == USART_StopBits_1_5)) +/** + * @} + */ + +/** @defgroup USART_Parity + * @{ + */ + +#define USART_Parity_No ((uint16_t)0x0000) +#define USART_Parity_Even ((uint16_t)0x0400) +#define USART_Parity_Odd ((uint16_t)0x0600) +#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \ + ((PARITY) == USART_Parity_Even) || \ + ((PARITY) == USART_Parity_Odd)) +/** + * @} + */ + +/** @defgroup USART_Mode + * @{ + */ + +#define USART_Mode_Rx ((uint16_t)0x0004) +#define USART_Mode_Tx ((uint16_t)0x0008) +#define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00)) +/** + * @} + */ + +/** @defgroup USART_Hardware_Flow_Control + * @{ + */ +#define USART_HardwareFlowControl_None ((uint16_t)0x0000) +#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100) +#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200) +#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300) +#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\ + (((CONTROL) == USART_HardwareFlowControl_None) || \ + ((CONTROL) == USART_HardwareFlowControl_RTS) || \ + ((CONTROL) == USART_HardwareFlowControl_CTS) || \ + ((CONTROL) == USART_HardwareFlowControl_RTS_CTS)) +/** + * @} + */ + +/** @defgroup USART_Clock + * @{ + */ +#define USART_Clock_Disable ((uint16_t)0x0000) +#define USART_Clock_Enable ((uint16_t)0x0800) +#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \ + ((CLOCK) == USART_Clock_Enable)) +/** + * @} + */ + +/** @defgroup USART_Clock_Polarity + * @{ + */ + +#define USART_CPOL_Low ((uint16_t)0x0000) +#define USART_CPOL_High ((uint16_t)0x0400) +#define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High)) + +/** + * @} + */ + +/** @defgroup USART_Clock_Phase + * @{ + */ + +#define USART_CPHA_1Edge ((uint16_t)0x0000) +#define USART_CPHA_2Edge ((uint16_t)0x0200) +#define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge)) + +/** + * @} + */ + +/** @defgroup USART_Last_Bit + * @{ + */ + +#define USART_LastBit_Disable ((uint16_t)0x0000) +#define USART_LastBit_Enable ((uint16_t)0x0100) +#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \ + ((LASTBIT) == USART_LastBit_Enable)) +/** + * @} + */ + +/** @defgroup USART_Interrupt_definition + * @{ + */ + +#define USART_IT_PE ((uint16_t)0x0028) +#define USART_IT_TXE ((uint16_t)0x0727) +#define USART_IT_TC ((uint16_t)0x0626) +#define USART_IT_RXNE ((uint16_t)0x0525) +#define USART_IT_ORE_RX ((uint16_t)0x0325) /* In case interrupt is generated if the RXNEIE bit is set */ +#define USART_IT_IDLE ((uint16_t)0x0424) +#define USART_IT_LBD ((uint16_t)0x0846) +#define USART_IT_CTS ((uint16_t)0x096A) +#define USART_IT_ERR ((uint16_t)0x0060) +#define USART_IT_ORE_ER ((uint16_t)0x0360) /* In case interrupt is generated if the EIE bit is set */ +#define USART_IT_NE ((uint16_t)0x0260) +#define USART_IT_FE ((uint16_t)0x0160) + +/** @defgroup USART_Legacy + * @{ + */ +#define USART_IT_ORE USART_IT_ORE_ER +/** + * @} + */ + +#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ + ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ + ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ + ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR)) +#define IS_USART_GET_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ + ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ + ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ + ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ORE) || \ + ((IT) == USART_IT_ORE_RX) || ((IT) == USART_IT_ORE_ER) || \ + ((IT) == USART_IT_NE) || ((IT) == USART_IT_FE)) +#define IS_USART_CLEAR_IT(IT) (((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ + ((IT) == USART_IT_LBD) || ((IT) == USART_IT_CTS)) +/** + * @} + */ + +/** @defgroup USART_DMA_Requests + * @{ + */ + +#define USART_DMAReq_Tx ((uint16_t)0x0080) +#define USART_DMAReq_Rx ((uint16_t)0x0040) +#define IS_USART_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFF3F) == 0x00) && ((DMAREQ) != (uint16_t)0x00)) + +/** + * @} + */ + +/** @defgroup USART_WakeUp_methods + * @{ + */ + +#define USART_WakeUp_IdleLine ((uint16_t)0x0000) +#define USART_WakeUp_AddressMark ((uint16_t)0x0800) +#define IS_USART_WAKEUP(WAKEUP) (((WAKEUP) == USART_WakeUp_IdleLine) || \ + ((WAKEUP) == USART_WakeUp_AddressMark)) +/** + * @} + */ + +/** @defgroup USART_LIN_Break_Detection_Length + * @{ + */ + +#define USART_LINBreakDetectLength_10b ((uint16_t)0x0000) +#define USART_LINBreakDetectLength_11b ((uint16_t)0x0020) +#define IS_USART_LIN_BREAK_DETECT_LENGTH(LENGTH) \ + (((LENGTH) == USART_LINBreakDetectLength_10b) || \ + ((LENGTH) == USART_LINBreakDetectLength_11b)) +/** + * @} + */ + +/** @defgroup USART_IrDA_Low_Power + * @{ + */ + +#define USART_IrDAMode_LowPower ((uint16_t)0x0004) +#define USART_IrDAMode_Normal ((uint16_t)0x0000) +#define IS_USART_IRDA_MODE(MODE) (((MODE) == USART_IrDAMode_LowPower) || \ + ((MODE) == USART_IrDAMode_Normal)) +/** + * @} + */ + +/** @defgroup USART_Flags + * @{ + */ + +#define USART_FLAG_CTS ((uint16_t)0x0200) +#define USART_FLAG_LBD ((uint16_t)0x0100) +#define USART_FLAG_TXE ((uint16_t)0x0080) +#define USART_FLAG_TC ((uint16_t)0x0040) +#define USART_FLAG_RXNE ((uint16_t)0x0020) +#define USART_FLAG_IDLE ((uint16_t)0x0010) +#define USART_FLAG_ORE ((uint16_t)0x0008) +#define USART_FLAG_NE ((uint16_t)0x0004) +#define USART_FLAG_FE ((uint16_t)0x0002) +#define USART_FLAG_PE ((uint16_t)0x0001) +#define IS_USART_FLAG(FLAG) (((FLAG) == USART_FLAG_PE) || ((FLAG) == USART_FLAG_TXE) || \ + ((FLAG) == USART_FLAG_TC) || ((FLAG) == USART_FLAG_RXNE) || \ + ((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_FLAG_LBD) || \ + ((FLAG) == USART_FLAG_CTS) || ((FLAG) == USART_FLAG_ORE) || \ + ((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE)) + +#define IS_USART_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFC9F) == 0x00) && ((FLAG) != (uint16_t)0x00)) + +#define IS_USART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) < 7500001)) +#define IS_USART_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF) +#define IS_USART_DATA(DATA) ((DATA) <= 0x1FF) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the USART configuration to the default reset state ***/ +void USART_DeInit(USART_TypeDef* USARTx); + +/* Initialization and Configuration functions *********************************/ +void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct); +void USART_StructInit(USART_InitTypeDef* USART_InitStruct); +void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct); +void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct); +void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler); +void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState); + +/* Data transfers functions ***************************************************/ +void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); +uint16_t USART_ReceiveData(USART_TypeDef* USARTx); + +/* Multi-Processor Communication functions ************************************/ +void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address); +void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp); +void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState); + +/* LIN mode functions *********************************************************/ +void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength); +void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_SendBreak(USART_TypeDef* USARTx); + +/* Half-duplex mode function **************************************************/ +void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState); + +/* Smartcard mode functions ***************************************************/ +void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime); + +/* IrDA mode functions ********************************************************/ +void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode); +void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState); + +/* DMA transfers management functions *****************************************/ +void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); +FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); +void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG); +ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); +void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_USART_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_wwdg.h b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_wwdg.h new file mode 100644 index 0000000..b054e68 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_wwdg.h @@ -0,0 +1,105 @@ +/** + ****************************************************************************** + * @file stm32f4xx_wwdg.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file contains all the functions prototypes for the WWDG firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_WWDG_H +#define __STM32F4xx_WWDG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup WWDG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup WWDG_Exported_Constants + * @{ + */ + +/** @defgroup WWDG_Prescaler + * @{ + */ + +#define WWDG_Prescaler_1 ((uint32_t)0x00000000) +#define WWDG_Prescaler_2 ((uint32_t)0x00000080) +#define WWDG_Prescaler_4 ((uint32_t)0x00000100) +#define WWDG_Prescaler_8 ((uint32_t)0x00000180) +#define IS_WWDG_PRESCALER(PRESCALER) (((PRESCALER) == WWDG_Prescaler_1) || \ + ((PRESCALER) == WWDG_Prescaler_2) || \ + ((PRESCALER) == WWDG_Prescaler_4) || \ + ((PRESCALER) == WWDG_Prescaler_8)) +#define IS_WWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0x7F) +#define IS_WWDG_COUNTER(COUNTER) (((COUNTER) >= 0x40) && ((COUNTER) <= 0x7F)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the WWDG configuration to the default reset state ****/ +void WWDG_DeInit(void); + +/* Prescaler, Refresh window and Counter configuration functions **************/ +void WWDG_SetPrescaler(uint32_t WWDG_Prescaler); +void WWDG_SetWindowValue(uint8_t WindowValue); +void WWDG_EnableIT(void); +void WWDG_SetCounter(uint8_t Counter); + +/* WWDG activation function ***************************************************/ +void WWDG_Enable(uint8_t Counter); + +/* Interrupts and flags management functions **********************************/ +FlagStatus WWDG_GetFlagStatus(void); +void WWDG_ClearFlag(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_WWDG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/misc.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/misc.c new file mode 100644 index 0000000..80f5c1d --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/misc.c @@ -0,0 +1,243 @@ +/** + ****************************************************************************** + * @file misc.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides all the miscellaneous firmware functions (add-on + * to CMSIS functions). + * + * @verbatim + * + * =================================================================== + * How to configure Interrupts using driver + * =================================================================== + * + * This section provide functions allowing to configure the NVIC interrupts (IRQ). + * The Cortex-M4 exceptions are managed by CMSIS functions. + * + * 1. Configure the NVIC Priority Grouping using NVIC_PriorityGroupConfig() + * function according to the following table. + + * The table below gives the allowed values of the pre-emption priority and subpriority according + * to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function + * ========================================================================================================================== + * NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description + * ========================================================================================================================== + * NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority + * | | | 4 bits for subpriority + * -------------------------------------------------------------------------------------------------------------------------- + * NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority + * | | | 3 bits for subpriority + * -------------------------------------------------------------------------------------------------------------------------- + * NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority + * | | | 2 bits for subpriority + * -------------------------------------------------------------------------------------------------------------------------- + * NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority + * | | | 1 bits for subpriority + * -------------------------------------------------------------------------------------------------------------------------- + * NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority + * | | | 0 bits for subpriority + * ========================================================================================================================== + * + * 2. Enable and Configure the priority of the selected IRQ Channels using NVIC_Init() + * + * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. + * The pending IRQ priority will be managed only by the subpriority. + * + * @note IRQ priority order (sorted by highest to lowest priority): + * - Lowest pre-emption priority + * - Lowest subpriority + * - Lowest hardware priority (IRQ number) + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "misc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup MISC + * @brief MISC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup MISC_Private_Functions + * @{ + */ + +/** + * @brief Configures the priority grouping: pre-emption priority and subpriority. + * @param NVIC_PriorityGroup: specifies the priority grouping bits length. + * This parameter can be one of the following values: + * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority + * 4 bits for subpriority + * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority + * 3 bits for subpriority + * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority + * 2 bits for subpriority + * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority + * 1 bits for subpriority + * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority + * 0 bits for subpriority + * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. + * The pending IRQ priority will be managed only by the subpriority. + * @retval None + */ +void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); + + /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ + SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; +} + +/** + * @brief Initializes the NVIC peripheral according to the specified + * parameters in the NVIC_InitStruct. + * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() + * function should be called before. + * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains + * the configuration information for the specified NVIC peripheral. + * @retval None + */ +void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) +{ + uint8_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); + assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); + assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); + + if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) + { + /* Compute the Corresponding IRQ Priority --------------------------------*/ + tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08; + tmppre = (0x4 - tmppriority); + tmpsub = tmpsub >> tmppriority; + + tmppriority = NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; + tmppriority |= (uint8_t)(NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub); + + tmppriority = tmppriority << 0x04; + + NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; + + /* Enable the Selected IRQ Channels --------------------------------------*/ + NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } + else + { + /* Disable the Selected IRQ Channels -------------------------------------*/ + NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } +} + +/** + * @brief Sets the vector table location and Offset. + * @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory. + * This parameter can be one of the following values: + * @arg NVIC_VectTab_RAM: Vector Table in internal SRAM. + * @arg NVIC_VectTab_FLASH: Vector Table in internal FLASH. + * @param Offset: Vector Table base offset field. This value must be a multiple of 0x200. + * @retval None + */ +void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) +{ + /* Check the parameters */ + assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); + assert_param(IS_NVIC_OFFSET(Offset)); + + SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); +} + +/** + * @brief Selects the condition for the system to enter low power mode. + * @param LowPowerMode: Specifies the new mode for the system to enter low power mode. + * This parameter can be one of the following values: + * @arg NVIC_LP_SEVONPEND: Low Power SEV on Pend. + * @arg NVIC_LP_SLEEPDEEP: Low Power DEEPSLEEP request. + * @arg NVIC_LP_SLEEPONEXIT: Low Power Sleep on Exit. + * @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_NVIC_LP(LowPowerMode)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + SCB->SCR |= LowPowerMode; + } + else + { + SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode); + } +} + +/** + * @brief Configures the SysTick clock source. + * @param SysTick_CLKSource: specifies the SysTick clock source. + * This parameter can be one of the following values: + * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. + * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source. + * @retval None + */ +void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) +{ + /* Check the parameters */ + assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); + if (SysTick_CLKSource == SysTick_CLKSource_HCLK) + { + SysTick->CTRL |= SysTick_CLKSource_HCLK; + } + else + { + SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c new file mode 100644 index 0000000..d0206c3 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c @@ -0,0 +1,1742 @@ +/** + ****************************************************************************** + * @file stm32f4xx_adc.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Analog to Digital Convertor (ADC) peripheral: + * - Initialization and Configuration (in addition to ADC multi mode + * selection) + * - Analog Watchdog configuration + * - Temperature Sensor & Vrefint (Voltage Reference internal) & VBAT + * management + * - Regular Channels Configuration + * - Regular Channels DMA Configuration + * - Injected channels Configuration + * - Interrupts and flags management + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + + * 1. Enable the ADC interface clock using + * RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADCx, ENABLE); + * + * 2. ADC pins configuration + * - Enable the clock for the ADC GPIOs using the following function: + * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); + * - Configure these ADC pins in analog mode using GPIO_Init(); + * + * 3. Configure the ADC Prescaler, conversion resolution and data + * alignment using the ADC_Init() function. + * 4. Activate the ADC peripheral using ADC_Cmd() function. + * + * Regular channels group configuration + * ==================================== + * - To configure the ADC regular channels group features, use + * ADC_Init() and ADC_RegularChannelConfig() functions. + * - To activate the continuous mode, use the ADC_continuousModeCmd() + * function. + * - To configurate and activate the Discontinuous mode, use the + * ADC_DiscModeChannelCountConfig() and ADC_DiscModeCmd() functions. + * - To read the ADC converted values, use the ADC_GetConversionValue() + * function. + * + * Multi mode ADCs Regular channels configuration + * =============================================== + * - Refer to "Regular channels group configuration" description to + * configure the ADC1, ADC2 and ADC3 regular channels. + * - Select the Multi mode ADC regular channels features (dual or + * triple mode) using ADC_CommonInit() function and configure + * the DMA mode using ADC_MultiModeDMARequestAfterLastTransferCmd() + * functions. + * - Read the ADCs converted values using the + * ADC_GetMultiModeConversionValue() function. + * + * DMA for Regular channels group features configuration + * ====================================================== + * - To enable the DMA mode for regular channels group, use the + * ADC_DMACmd() function. + * - To enable the generation of DMA requests continuously at the end + * of the last DMA transfer, use the ADC_DMARequestAfterLastTransferCmd() + * function. + * + * Injected channels group configuration + * ===================================== + * - To configure the ADC Injected channels group features, use + * ADC_InjectedChannelConfig() and ADC_InjectedSequencerLengthConfig() + * functions. + * - To activate the continuous mode, use the ADC_continuousModeCmd() + * function. + * - To activate the Injected Discontinuous mode, use the + * ADC_InjectedDiscModeCmd() function. + * - To activate the AutoInjected mode, use the ADC_AutoInjectedConvCmd() + * function. + * - To read the ADC converted values, use the ADC_GetInjectedConversionValue() + * function. + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_adc.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup ADC + * @brief ADC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* ADC DISCNUM mask */ +#define CR1_DISCNUM_RESET ((uint32_t)0xFFFF1FFF) + +/* ADC AWDCH mask */ +#define CR1_AWDCH_RESET ((uint32_t)0xFFFFFFE0) + +/* ADC Analog watchdog enable mode mask */ +#define CR1_AWDMode_RESET ((uint32_t)0xFF3FFDFF) + +/* CR1 register Mask */ +#define CR1_CLEAR_MASK ((uint32_t)0xFCFFFEFF) + +/* ADC EXTEN mask */ +#define CR2_EXTEN_RESET ((uint32_t)0xCFFFFFFF) + +/* ADC JEXTEN mask */ +#define CR2_JEXTEN_RESET ((uint32_t)0xFFCFFFFF) + +/* ADC JEXTSEL mask */ +#define CR2_JEXTSEL_RESET ((uint32_t)0xFFF0FFFF) + +/* CR2 register Mask */ +#define CR2_CLEAR_MASK ((uint32_t)0xC0FFF7FD) + +/* ADC SQx mask */ +#define SQR3_SQ_SET ((uint32_t)0x0000001F) +#define SQR2_SQ_SET ((uint32_t)0x0000001F) +#define SQR1_SQ_SET ((uint32_t)0x0000001F) + +/* ADC L Mask */ +#define SQR1_L_RESET ((uint32_t)0xFF0FFFFF) + +/* ADC JSQx mask */ +#define JSQR_JSQ_SET ((uint32_t)0x0000001F) + +/* ADC JL mask */ +#define JSQR_JL_SET ((uint32_t)0x00300000) +#define JSQR_JL_RESET ((uint32_t)0xFFCFFFFF) + +/* ADC SMPx mask */ +#define SMPR1_SMP_SET ((uint32_t)0x00000007) +#define SMPR2_SMP_SET ((uint32_t)0x00000007) + +/* ADC JDRx registers offset */ +#define JDR_OFFSET ((uint8_t)0x28) + +/* ADC CDR register base address */ +#define CDR_ADDRESS ((uint32_t)0x40012308) + +/* ADC CCR register Mask */ +#define CR_CLEAR_MASK ((uint32_t)0xFFFC30E0) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup ADC_Private_Functions + * @{ + */ + +/** @defgroup ADC_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + This section provides functions allowing to: + - Initialize and configure the ADC Prescaler + - ADC Conversion Resolution (12bit..6bit) + - Scan Conversion Mode (multichannels or one channel) for regular group + - ADC Continuous Conversion Mode (Continuous or Single conversion) for + regular group + - External trigger Edge and source of regular group, + - Converted data alignment (left or right) + - The number of ADC conversions that will be done using the sequencer for + regular channel group + - Multi ADC mode selection + - Direct memory access mode selection for multi ADC mode + - Delay between 2 sampling phases (used in dual or triple interleaved modes) + - Enable or disable the ADC peripheral + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes all ADCs peripherals registers to their default reset + * values. + * @param None + * @retval None + */ +void ADC_DeInit(void) +{ + /* Enable all ADCs reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, ENABLE); + + /* Release all ADCs from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, DISABLE); +} + +/** + * @brief Initializes the ADCx peripheral according to the specified parameters + * in the ADC_InitStruct. + * @note This function is used to configure the global features of the ADC ( + * Resolution and Data Alignment), however, the rest of the configuration + * parameters are specific to the regular channels group (scan mode + * activation, continuous mode activation, External trigger source and + * edge, number of conversion in the regular channels group sequencer). + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains + * the configuration information for the specified ADC peripheral. + * @retval None + */ +void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) +{ + uint32_t tmpreg1 = 0; + uint8_t tmpreg2 = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_RESOLUTION(ADC_InitStruct->ADC_Resolution)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ScanConvMode)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG_EDGE(ADC_InitStruct->ADC_ExternalTrigConvEdge)); + assert_param(IS_ADC_EXT_TRIG(ADC_InitStruct->ADC_ExternalTrigConv)); + assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign)); + assert_param(IS_ADC_REGULAR_LENGTH(ADC_InitStruct->ADC_NbrOfConversion)); + + /*---------------------------- ADCx CR1 Configuration -----------------*/ + /* Get the ADCx CR1 value */ + tmpreg1 = ADCx->CR1; + + /* Clear RES and SCAN bits */ + tmpreg1 &= CR1_CLEAR_MASK; + + /* Configure ADCx: scan conversion mode and resolution */ + /* Set SCAN bit according to ADC_ScanConvMode value */ + /* Set RES bit according to ADC_Resolution value */ + tmpreg1 |= (uint32_t)(((uint32_t)ADC_InitStruct->ADC_ScanConvMode << 8) | \ + ADC_InitStruct->ADC_Resolution); + /* Write to ADCx CR1 */ + ADCx->CR1 = tmpreg1; + /*---------------------------- ADCx CR2 Configuration -----------------*/ + /* Get the ADCx CR2 value */ + tmpreg1 = ADCx->CR2; + + /* Clear CONT, ALIGN, EXTEN and EXTSEL bits */ + tmpreg1 &= CR2_CLEAR_MASK; + + /* Configure ADCx: external trigger event and edge, data alignment and + continuous conversion mode */ + /* Set ALIGN bit according to ADC_DataAlign value */ + /* Set EXTEN bits according to ADC_ExternalTrigConvEdge value */ + /* Set EXTSEL bits according to ADC_ExternalTrigConv value */ + /* Set CONT bit according to ADC_ContinuousConvMode value */ + tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_DataAlign | \ + ADC_InitStruct->ADC_ExternalTrigConv | + ADC_InitStruct->ADC_ExternalTrigConvEdge | \ + ((uint32_t)ADC_InitStruct->ADC_ContinuousConvMode << 1)); + + /* Write to ADCx CR2 */ + ADCx->CR2 = tmpreg1; + /*---------------------------- ADCx SQR1 Configuration -----------------*/ + /* Get the ADCx SQR1 value */ + tmpreg1 = ADCx->SQR1; + + /* Clear L bits */ + tmpreg1 &= SQR1_L_RESET; + + /* Configure ADCx: regular channel sequence length */ + /* Set L bits according to ADC_NbrOfConversion value */ + tmpreg2 |= (uint8_t)(ADC_InitStruct->ADC_NbrOfConversion - (uint8_t)1); + tmpreg1 |= ((uint32_t)tmpreg2 << 20); + + /* Write to ADCx SQR1 */ + ADCx->SQR1 = tmpreg1; +} + +/** + * @brief Fills each ADC_InitStruct member with its default value. + * @note This function is used to initialize the global features of the ADC ( + * Resolution and Data Alignment), however, the rest of the configuration + * parameters are specific to the regular channels group (scan mode + * activation, continuous mode activation, External trigger source and + * edge, number of conversion in the regular channels group sequencer). + * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct) +{ + /* Initialize the ADC_Mode member */ + ADC_InitStruct->ADC_Resolution = ADC_Resolution_12b; + + /* initialize the ADC_ScanConvMode member */ + ADC_InitStruct->ADC_ScanConvMode = DISABLE; + + /* Initialize the ADC_ContinuousConvMode member */ + ADC_InitStruct->ADC_ContinuousConvMode = DISABLE; + + /* Initialize the ADC_ExternalTrigConvEdge member */ + ADC_InitStruct->ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; + + /* Initialize the ADC_ExternalTrigConv member */ + ADC_InitStruct->ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; + + /* Initialize the ADC_DataAlign member */ + ADC_InitStruct->ADC_DataAlign = ADC_DataAlign_Right; + + /* Initialize the ADC_NbrOfConversion member */ + ADC_InitStruct->ADC_NbrOfConversion = 1; +} + +/** + * @brief Initializes the ADCs peripherals according to the specified parameters + * in the ADC_CommonInitStruct. + * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure + * that contains the configuration information for All ADCs peripherals. + * @retval None + */ +void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) +{ + uint32_t tmpreg1 = 0; + /* Check the parameters */ + assert_param(IS_ADC_MODE(ADC_CommonInitStruct->ADC_Mode)); + assert_param(IS_ADC_PRESCALER(ADC_CommonInitStruct->ADC_Prescaler)); + assert_param(IS_ADC_DMA_ACCESS_MODE(ADC_CommonInitStruct->ADC_DMAAccessMode)); + assert_param(IS_ADC_SAMPLING_DELAY(ADC_CommonInitStruct->ADC_TwoSamplingDelay)); + /*---------------------------- ADC CCR Configuration -----------------*/ + /* Get the ADC CCR value */ + tmpreg1 = ADC->CCR; + + /* Clear MULTI, DELAY, DMA and ADCPRE bits */ + tmpreg1 &= CR_CLEAR_MASK; + + /* Configure ADCx: Multi mode, Delay between two sampling time, ADC prescaler, + and DMA access mode for multimode */ + /* Set MULTI bits according to ADC_Mode value */ + /* Set ADCPRE bits according to ADC_Prescaler value */ + /* Set DMA bits according to ADC_DMAAccessMode value */ + /* Set DELAY bits according to ADC_TwoSamplingDelay value */ + tmpreg1 |= (uint32_t)(ADC_CommonInitStruct->ADC_Mode | + ADC_CommonInitStruct->ADC_Prescaler | + ADC_CommonInitStruct->ADC_DMAAccessMode | + ADC_CommonInitStruct->ADC_TwoSamplingDelay); + + /* Write to ADC CCR */ + ADC->CCR = tmpreg1; +} + +/** + * @brief Fills each ADC_CommonInitStruct member with its default value. + * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure + * which will be initialized. + * @retval None + */ +void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) +{ + /* Initialize the ADC_Mode member */ + ADC_CommonInitStruct->ADC_Mode = ADC_Mode_Independent; + + /* initialize the ADC_Prescaler member */ + ADC_CommonInitStruct->ADC_Prescaler = ADC_Prescaler_Div2; + + /* Initialize the ADC_DMAAccessMode member */ + ADC_CommonInitStruct->ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; + + /* Initialize the ADC_TwoSamplingDelay member */ + ADC_CommonInitStruct->ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; +} + +/** + * @brief Enables or disables the specified ADC peripheral. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the ADCx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Set the ADON bit to wake up the ADC from power down mode */ + ADCx->CR2 |= (uint32_t)ADC_CR2_ADON; + } + else + { + /* Disable the selected ADC peripheral */ + ADCx->CR2 &= (uint32_t)(~ADC_CR2_ADON); + } +} +/** + * @} + */ + +/** @defgroup ADC_Group2 Analog Watchdog configuration functions + * @brief Analog Watchdog configuration functions + * +@verbatim + =============================================================================== + Analog Watchdog configuration functions + =============================================================================== + + This section provides functions allowing to configure the Analog Watchdog + (AWD) feature in the ADC. + + A typical configuration Analog Watchdog is done following these steps : + 1. the ADC guarded channel(s) is (are) selected using the + ADC_AnalogWatchdogSingleChannelConfig() function. + 2. The Analog watchdog lower and higher threshold are configured using the + ADC_AnalogWatchdogThresholdsConfig() function. + 3. The Analog watchdog is enabled and configured to enable the check, on one + or more channels, using the ADC_AnalogWatchdogCmd() function. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the analog watchdog on single/all regular or + * injected channels + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_AnalogWatchdog: the ADC analog watchdog configuration. + * This parameter can be one of the following values: + * @arg ADC_AnalogWatchdog_SingleRegEnable: Analog watchdog on a single regular channel + * @arg ADC_AnalogWatchdog_SingleInjecEnable: Analog watchdog on a single injected channel + * @arg ADC_AnalogWatchdog_SingleRegOrInjecEnable: Analog watchdog on a single regular or injected channel + * @arg ADC_AnalogWatchdog_AllRegEnable: Analog watchdog on all regular channel + * @arg ADC_AnalogWatchdog_AllInjecEnable: Analog watchdog on all injected channel + * @arg ADC_AnalogWatchdog_AllRegAllInjecEnable: Analog watchdog on all regular and injected channels + * @arg ADC_AnalogWatchdog_None: No channel guarded by the analog watchdog + * @retval None + */ +void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_ANALOG_WATCHDOG(ADC_AnalogWatchdog)); + + /* Get the old register value */ + tmpreg = ADCx->CR1; + + /* Clear AWDEN, JAWDEN and AWDSGL bits */ + tmpreg &= CR1_AWDMode_RESET; + + /* Set the analog watchdog enable mode */ + tmpreg |= ADC_AnalogWatchdog; + + /* Store the new register value */ + ADCx->CR1 = tmpreg; +} + +/** + * @brief Configures the high and low thresholds of the analog watchdog. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param HighThreshold: the ADC analog watchdog High threshold value. + * This parameter must be a 12-bit value. + * @param LowThreshold: the ADC analog watchdog Low threshold value. + * This parameter must be a 12-bit value. + * @retval None + */ +void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, + uint16_t LowThreshold) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_THRESHOLD(HighThreshold)); + assert_param(IS_ADC_THRESHOLD(LowThreshold)); + + /* Set the ADCx high threshold */ + ADCx->HTR = HighThreshold; + + /* Set the ADCx low threshold */ + ADCx->LTR = LowThreshold; +} + +/** + * @brief Configures the analog watchdog guarded single channel + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_Channel: the ADC channel to configure for the analog watchdog. + * This parameter can be one of the following values: + * @arg ADC_Channel_0: ADC Channel0 selected + * @arg ADC_Channel_1: ADC Channel1 selected + * @arg ADC_Channel_2: ADC Channel2 selected + * @arg ADC_Channel_3: ADC Channel3 selected + * @arg ADC_Channel_4: ADC Channel4 selected + * @arg ADC_Channel_5: ADC Channel5 selected + * @arg ADC_Channel_6: ADC Channel6 selected + * @arg ADC_Channel_7: ADC Channel7 selected + * @arg ADC_Channel_8: ADC Channel8 selected + * @arg ADC_Channel_9: ADC Channel9 selected + * @arg ADC_Channel_10: ADC Channel10 selected + * @arg ADC_Channel_11: ADC Channel11 selected + * @arg ADC_Channel_12: ADC Channel12 selected + * @arg ADC_Channel_13: ADC Channel13 selected + * @arg ADC_Channel_14: ADC Channel14 selected + * @arg ADC_Channel_15: ADC Channel15 selected + * @arg ADC_Channel_16: ADC Channel16 selected + * @arg ADC_Channel_17: ADC Channel17 selected + * @arg ADC_Channel_18: ADC Channel18 selected + * @retval None + */ +void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CHANNEL(ADC_Channel)); + + /* Get the old register value */ + tmpreg = ADCx->CR1; + + /* Clear the Analog watchdog channel select bits */ + tmpreg &= CR1_AWDCH_RESET; + + /* Set the Analog watchdog channel */ + tmpreg |= ADC_Channel; + + /* Store the new register value */ + ADCx->CR1 = tmpreg; +} +/** + * @} + */ + +/** @defgroup ADC_Group3 Temperature Sensor, Vrefint (Voltage Reference internal) + * and VBAT (Voltage BATtery) management functions + * @brief Temperature Sensor, Vrefint and VBAT management functions + * +@verbatim + =============================================================================== + Temperature Sensor, Vrefint and VBAT management functions + =============================================================================== + + This section provides functions allowing to enable/ disable the internal + connections between the ADC and the Temperature Sensor, the Vrefint and the + Vbat sources. + + A typical configuration to get the Temperature sensor and Vrefint channels + voltages is done following these steps : + 1. Enable the internal connection of Temperature sensor and Vrefint sources + with the ADC channels using ADC_TempSensorVrefintCmd() function. + 2. Select the ADC_Channel_TempSensor and/or ADC_Channel_Vrefint using + ADC_RegularChannelConfig() or ADC_InjectedChannelConfig() functions + 3. Get the voltage values, using ADC_GetConversionValue() or + ADC_GetInjectedConversionValue(). + + A typical configuration to get the VBAT channel voltage is done following + these steps : + 1. Enable the internal connection of VBAT source with the ADC channel using + ADC_VBATCmd() function. + 2. Select the ADC_Channel_Vbat using ADC_RegularChannelConfig() or + ADC_InjectedChannelConfig() functions + 3. Get the voltage value, using ADC_GetConversionValue() or + ADC_GetInjectedConversionValue(). + +@endverbatim + * @{ + */ + + +/** + * @brief Enables or disables the temperature sensor and Vrefint channels. + * @param NewState: new state of the temperature sensor and Vrefint channels. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_TempSensorVrefintCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the temperature sensor and Vrefint channel*/ + ADC->CCR |= (uint32_t)ADC_CCR_TSVREFE; + } + else + { + /* Disable the temperature sensor and Vrefint channel*/ + ADC->CCR &= (uint32_t)(~ADC_CCR_TSVREFE); + } +} + +/** + * @brief Enables or disables the VBAT (Voltage Battery) channel. + * @param NewState: new state of the VBAT channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_VBATCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the VBAT channel*/ + ADC->CCR |= (uint32_t)ADC_CCR_VBATE; + } + else + { + /* Disable the VBAT channel*/ + ADC->CCR &= (uint32_t)(~ADC_CCR_VBATE); + } +} + +/** + * @} + */ + +/** @defgroup ADC_Group4 Regular Channels Configuration functions + * @brief Regular Channels Configuration functions + * +@verbatim + =============================================================================== + Regular Channels Configuration functions + =============================================================================== + + This section provides functions allowing to manage the ADC's regular channels, + it is composed of 2 sub sections : + + 1. Configuration and management functions for regular channels: This subsection + provides functions allowing to configure the ADC regular channels : + - Configure the rank in the regular group sequencer for each channel + - Configure the sampling time for each channel + - select the conversion Trigger for regular channels + - select the desired EOC event behavior configuration + - Activate the continuous Mode (*) + - Activate the Discontinuous Mode + Please Note that the following features for regular channels are configurated + using the ADC_Init() function : + - scan mode activation + - continuous mode activation (**) + - External trigger source + - External trigger edge + - number of conversion in the regular channels group sequencer. + + @note (*) and (**) are performing the same configuration + + 2. Get the conversion data: This subsection provides an important function in + the ADC peripheral since it returns the converted data of the current + regular channel. When the Conversion value is read, the EOC Flag is + automatically cleared. + + @note For multi ADC mode, the last ADC1, ADC2 and ADC3 regular conversions + results data (in the selected multi mode) can be returned in the same + time using ADC_GetMultiModeConversionValue() function. + + +@endverbatim + * @{ + */ +/** + * @brief Configures for the selected ADC regular channel its corresponding + * rank in the sequencer and its sample time. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_Channel: the ADC channel to configure. + * This parameter can be one of the following values: + * @arg ADC_Channel_0: ADC Channel0 selected + * @arg ADC_Channel_1: ADC Channel1 selected + * @arg ADC_Channel_2: ADC Channel2 selected + * @arg ADC_Channel_3: ADC Channel3 selected + * @arg ADC_Channel_4: ADC Channel4 selected + * @arg ADC_Channel_5: ADC Channel5 selected + * @arg ADC_Channel_6: ADC Channel6 selected + * @arg ADC_Channel_7: ADC Channel7 selected + * @arg ADC_Channel_8: ADC Channel8 selected + * @arg ADC_Channel_9: ADC Channel9 selected + * @arg ADC_Channel_10: ADC Channel10 selected + * @arg ADC_Channel_11: ADC Channel11 selected + * @arg ADC_Channel_12: ADC Channel12 selected + * @arg ADC_Channel_13: ADC Channel13 selected + * @arg ADC_Channel_14: ADC Channel14 selected + * @arg ADC_Channel_15: ADC Channel15 selected + * @arg ADC_Channel_16: ADC Channel16 selected + * @arg ADC_Channel_17: ADC Channel17 selected + * @arg ADC_Channel_18: ADC Channel18 selected + * @param Rank: The rank in the regular group sequencer. + * This parameter must be between 1 to 16. + * @param ADC_SampleTime: The sample time value to be set for the selected channel. + * This parameter can be one of the following values: + * @arg ADC_SampleTime_3Cycles: Sample time equal to 3 cycles + * @arg ADC_SampleTime_15Cycles: Sample time equal to 15 cycles + * @arg ADC_SampleTime_28Cycles: Sample time equal to 28 cycles + * @arg ADC_SampleTime_56Cycles: Sample time equal to 56 cycles + * @arg ADC_SampleTime_84Cycles: Sample time equal to 84 cycles + * @arg ADC_SampleTime_112Cycles: Sample time equal to 112 cycles + * @arg ADC_SampleTime_144Cycles: Sample time equal to 144 cycles + * @arg ADC_SampleTime_480Cycles: Sample time equal to 480 cycles + * @retval None + */ +void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) +{ + uint32_t tmpreg1 = 0, tmpreg2 = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CHANNEL(ADC_Channel)); + assert_param(IS_ADC_REGULAR_RANK(Rank)); + assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); + + /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ + if (ADC_Channel > ADC_Channel_9) + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR1; + + /* Calculate the mask to clear */ + tmpreg2 = SMPR1_SMP_SET << (3 * (ADC_Channel - 10)); + + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10)); + + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + + /* Store the new register value */ + ADCx->SMPR1 = tmpreg1; + } + else /* ADC_Channel include in ADC_Channel_[0..9] */ + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR2; + + /* Calculate the mask to clear */ + tmpreg2 = SMPR2_SMP_SET << (3 * ADC_Channel); + + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); + + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + + /* Store the new register value */ + ADCx->SMPR2 = tmpreg1; + } + /* For Rank 1 to 6 */ + if (Rank < 7) + { + /* Get the old register value */ + tmpreg1 = ADCx->SQR3; + + /* Calculate the mask to clear */ + tmpreg2 = SQR3_SQ_SET << (5 * (Rank - 1)); + + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 1)); + + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + + /* Store the new register value */ + ADCx->SQR3 = tmpreg1; + } + /* For Rank 7 to 12 */ + else if (Rank < 13) + { + /* Get the old register value */ + tmpreg1 = ADCx->SQR2; + + /* Calculate the mask to clear */ + tmpreg2 = SQR2_SQ_SET << (5 * (Rank - 7)); + + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 7)); + + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + + /* Store the new register value */ + ADCx->SQR2 = tmpreg1; + } + /* For Rank 13 to 16 */ + else + { + /* Get the old register value */ + tmpreg1 = ADCx->SQR1; + + /* Calculate the mask to clear */ + tmpreg2 = SQR1_SQ_SET << (5 * (Rank - 13)); + + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 13)); + + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + + /* Store the new register value */ + ADCx->SQR1 = tmpreg1; + } +} + +/** + * @brief Enables the selected ADC software start conversion of the regular channels. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval None + */ +void ADC_SoftwareStartConv(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Enable the selected ADC conversion for regular group */ + ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART; +} + +/** + * @brief Gets the selected ADC Software start regular conversion Status. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval The new state of ADC software start conversion (SET or RESET). + */ +FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Check the status of SWSTART bit */ + if ((ADCx->CR2 & ADC_CR2_JSWSTART) != (uint32_t)RESET) + { + /* SWSTART bit is set */ + bitstatus = SET; + } + else + { + /* SWSTART bit is reset */ + bitstatus = RESET; + } + + /* Return the SWSTART bit status */ + return bitstatus; +} + + +/** + * @brief Enables or disables the EOC on each regular channel conversion + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC EOC flag rising + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC EOC rising on each regular channel conversion */ + ADCx->CR2 |= (uint32_t)ADC_CR2_EOCS; + } + else + { + /* Disable the selected ADC EOC rising on each regular channel conversion */ + ADCx->CR2 &= (uint32_t)(~ADC_CR2_EOCS); + } +} + +/** + * @brief Enables or disables the ADC continuous conversion mode + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC continuous conversion mode + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC continuous conversion mode */ + ADCx->CR2 |= (uint32_t)ADC_CR2_CONT; + } + else + { + /* Disable the selected ADC continuous conversion mode */ + ADCx->CR2 &= (uint32_t)(~ADC_CR2_CONT); + } +} + +/** + * @brief Configures the discontinuous mode for the selected ADC regular group + * channel. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param Number: specifies the discontinuous mode regular channel count value. + * This number must be between 1 and 8. + * @retval None + */ +void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number) +{ + uint32_t tmpreg1 = 0; + uint32_t tmpreg2 = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_REGULAR_DISC_NUMBER(Number)); + + /* Get the old register value */ + tmpreg1 = ADCx->CR1; + + /* Clear the old discontinuous mode channel count */ + tmpreg1 &= CR1_DISCNUM_RESET; + + /* Set the discontinuous mode channel count */ + tmpreg2 = Number - 1; + tmpreg1 |= tmpreg2 << 13; + + /* Store the new register value */ + ADCx->CR1 = tmpreg1; +} + +/** + * @brief Enables or disables the discontinuous mode on regular group channel + * for the specified ADC + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC discontinuous mode on + * regular group channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC regular discontinuous mode */ + ADCx->CR1 |= (uint32_t)ADC_CR1_DISCEN; + } + else + { + /* Disable the selected ADC regular discontinuous mode */ + ADCx->CR1 &= (uint32_t)(~ADC_CR1_DISCEN); + } +} + +/** + * @brief Returns the last ADCx conversion result data for regular channel. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval The Data conversion value. + */ +uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Return the selected ADC conversion value */ + return (uint16_t) ADCx->DR; +} + +/** + * @brief Returns the last ADC1, ADC2 and ADC3 regular conversions results + * data in the selected multi mode. + * @param None + * @retval The Data conversion value. + * @note In dual mode, the value returned by this function is as following + * Data[15:0] : these bits contain the regular data of ADC1. + * Data[31:16]: these bits contain the regular data of ADC2. + * @note In triple mode, the value returned by this function is as following + * Data[15:0] : these bits contain alternatively the regular data of ADC1, ADC3 and ADC2. + * Data[31:16]: these bits contain alternatively the regular data of ADC2, ADC1 and ADC3. + */ +uint32_t ADC_GetMultiModeConversionValue(void) +{ + /* Return the multi mode conversion value */ + return (*(__IO uint32_t *) CDR_ADDRESS); +} +/** + * @} + */ + +/** @defgroup ADC_Group5 Regular Channels DMA Configuration functions + * @brief Regular Channels DMA Configuration functions + * +@verbatim + =============================================================================== + Regular Channels DMA Configuration functions + =============================================================================== + + This section provides functions allowing to configure the DMA for ADC regular + channels. + Since converted regular channel values are stored into a unique data register, + it is useful to use DMA for conversion of more than one regular channel. This + avoids the loss of the data already stored in the ADC Data register. + + When the DMA mode is enabled (using the ADC_DMACmd() function), after each + conversion of a regular channel, a DMA request is generated. + + Depending on the "DMA disable selection for Independent ADC mode" + configuration (using the ADC_DMARequestAfterLastTransferCmd() function), + at the end of the last DMA transfer, two possibilities are allowed: + - No new DMA request is issued to the DMA controller (feature DISABLED) + - Requests can continue to be generated (feature ENABLED). + + Depending on the "DMA disable selection for multi ADC mode" configuration + (using the void ADC_MultiModeDMARequestAfterLastTransferCmd() function), + at the end of the last DMA transfer, two possibilities are allowed: + - No new DMA request is issued to the DMA controller (feature DISABLED) + - Requests can continue to be generated (feature ENABLED). + +@endverbatim + * @{ + */ + + /** + * @brief Enables or disables the specified ADC DMA request. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC DMA transfer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC DMA request */ + ADCx->CR2 |= (uint32_t)ADC_CR2_DMA; + } + else + { + /* Disable the selected ADC DMA request */ + ADCx->CR2 &= (uint32_t)(~ADC_CR2_DMA); + } +} + +/** + * @brief Enables or disables the ADC DMA request after last transfer (Single-ADC mode) + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC DMA request after last transfer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC DMA request after last transfer */ + ADCx->CR2 |= (uint32_t)ADC_CR2_DDS; + } + else + { + /* Disable the selected ADC DMA request after last transfer */ + ADCx->CR2 &= (uint32_t)(~ADC_CR2_DDS); + } +} + +/** + * @brief Enables or disables the ADC DMA request after last transfer in multi ADC mode + * @param NewState: new state of the selected ADC DMA request after last transfer. + * This parameter can be: ENABLE or DISABLE. + * @note if Enabled, DMA requests are issued as long as data are converted and + * DMA mode for multi ADC mode (selected using ADC_CommonInit() function + * by ADC_CommonInitStruct.ADC_DMAAccessMode structure member) is + * ADC_DMAAccessMode_1, ADC_DMAAccessMode_2 or ADC_DMAAccessMode_3. + * @retval None + */ +void ADC_MultiModeDMARequestAfterLastTransferCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC DMA request after last transfer */ + ADC->CCR |= (uint32_t)ADC_CCR_DDS; + } + else + { + /* Disable the selected ADC DMA request after last transfer */ + ADC->CCR &= (uint32_t)(~ADC_CCR_DDS); + } +} +/** + * @} + */ + +/** @defgroup ADC_Group6 Injected channels Configuration functions + * @brief Injected channels Configuration functions + * +@verbatim + =============================================================================== + Injected channels Configuration functions + =============================================================================== + + This section provide functions allowing to configure the ADC Injected channels, + it is composed of 2 sub sections : + + 1. Configuration functions for Injected channels: This subsection provides + functions allowing to configure the ADC injected channels : + - Configure the rank in the injected group sequencer for each channel + - Configure the sampling time for each channel + - Activate the Auto injected Mode + - Activate the Discontinuous Mode + - scan mode activation + - External/software trigger source + - External trigger edge + - injected channels sequencer. + + 2. Get the Specified Injected channel conversion data: This subsection + provides an important function in the ADC peripheral since it returns the + converted data of the specific injected channel. + +@endverbatim + * @{ + */ +/** + * @brief Configures for the selected ADC injected channel its corresponding + * rank in the sequencer and its sample time. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_Channel: the ADC channel to configure. + * This parameter can be one of the following values: + * @arg ADC_Channel_0: ADC Channel0 selected + * @arg ADC_Channel_1: ADC Channel1 selected + * @arg ADC_Channel_2: ADC Channel2 selected + * @arg ADC_Channel_3: ADC Channel3 selected + * @arg ADC_Channel_4: ADC Channel4 selected + * @arg ADC_Channel_5: ADC Channel5 selected + * @arg ADC_Channel_6: ADC Channel6 selected + * @arg ADC_Channel_7: ADC Channel7 selected + * @arg ADC_Channel_8: ADC Channel8 selected + * @arg ADC_Channel_9: ADC Channel9 selected + * @arg ADC_Channel_10: ADC Channel10 selected + * @arg ADC_Channel_11: ADC Channel11 selected + * @arg ADC_Channel_12: ADC Channel12 selected + * @arg ADC_Channel_13: ADC Channel13 selected + * @arg ADC_Channel_14: ADC Channel14 selected + * @arg ADC_Channel_15: ADC Channel15 selected + * @arg ADC_Channel_16: ADC Channel16 selected + * @arg ADC_Channel_17: ADC Channel17 selected + * @arg ADC_Channel_18: ADC Channel18 selected + * @param Rank: The rank in the injected group sequencer. + * This parameter must be between 1 to 4. + * @param ADC_SampleTime: The sample time value to be set for the selected channel. + * This parameter can be one of the following values: + * @arg ADC_SampleTime_3Cycles: Sample time equal to 3 cycles + * @arg ADC_SampleTime_15Cycles: Sample time equal to 15 cycles + * @arg ADC_SampleTime_28Cycles: Sample time equal to 28 cycles + * @arg ADC_SampleTime_56Cycles: Sample time equal to 56 cycles + * @arg ADC_SampleTime_84Cycles: Sample time equal to 84 cycles + * @arg ADC_SampleTime_112Cycles: Sample time equal to 112 cycles + * @arg ADC_SampleTime_144Cycles: Sample time equal to 144 cycles + * @arg ADC_SampleTime_480Cycles: Sample time equal to 480 cycles + * @retval None + */ +void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) +{ + uint32_t tmpreg1 = 0, tmpreg2 = 0, tmpreg3 = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CHANNEL(ADC_Channel)); + assert_param(IS_ADC_INJECTED_RANK(Rank)); + assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); + /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ + if (ADC_Channel > ADC_Channel_9) + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR1; + /* Calculate the mask to clear */ + tmpreg2 = SMPR1_SMP_SET << (3*(ADC_Channel - 10)); + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3*(ADC_Channel - 10)); + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR1 = tmpreg1; + } + else /* ADC_Channel include in ADC_Channel_[0..9] */ + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR2; + /* Calculate the mask to clear */ + tmpreg2 = SMPR2_SMP_SET << (3 * ADC_Channel); + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR2 = tmpreg1; + } + /* Rank configuration */ + /* Get the old register value */ + tmpreg1 = ADCx->JSQR; + /* Get JL value: Number = JL+1 */ + tmpreg3 = (tmpreg1 & JSQR_JL_SET)>> 20; + /* Calculate the mask to clear: ((Rank-1)+(4-JL-1)) */ + tmpreg2 = JSQR_JSQ_SET << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); + /* Clear the old JSQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set: ((Rank-1)+(4-JL-1)) */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); + /* Set the JSQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->JSQR = tmpreg1; +} + +/** + * @brief Configures the sequencer length for injected channels + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param Length: The sequencer length. + * This parameter must be a number between 1 to 4. + * @retval None + */ +void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length) +{ + uint32_t tmpreg1 = 0; + uint32_t tmpreg2 = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_INJECTED_LENGTH(Length)); + + /* Get the old register value */ + tmpreg1 = ADCx->JSQR; + + /* Clear the old injected sequence length JL bits */ + tmpreg1 &= JSQR_JL_RESET; + + /* Set the injected sequence length JL bits */ + tmpreg2 = Length - 1; + tmpreg1 |= tmpreg2 << 20; + + /* Store the new register value */ + ADCx->JSQR = tmpreg1; +} + +/** + * @brief Set the injected channels conversion value offset + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_InjectedChannel: the ADC injected channel to set its offset. + * This parameter can be one of the following values: + * @arg ADC_InjectedChannel_1: Injected Channel1 selected + * @arg ADC_InjectedChannel_2: Injected Channel2 selected + * @arg ADC_InjectedChannel_3: Injected Channel3 selected + * @arg ADC_InjectedChannel_4: Injected Channel4 selected + * @param Offset: the offset value for the selected ADC injected channel + * This parameter must be a 12bit value. + * @retval None + */ +void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset) +{ + __IO uint32_t tmp = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); + assert_param(IS_ADC_OFFSET(Offset)); + + tmp = (uint32_t)ADCx; + tmp += ADC_InjectedChannel; + + /* Set the selected injected channel data offset */ + *(__IO uint32_t *) tmp = (uint32_t)Offset; +} + + /** + * @brief Configures the ADCx external trigger for injected channels conversion. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_ExternalTrigInjecConv: specifies the ADC trigger to start injected conversion. + * This parameter can be one of the following values: + * @arg ADC_ExternalTrigInjecConv_T1_CC4: Timer1 capture compare4 selected + * @arg ADC_ExternalTrigInjecConv_T1_TRGO: Timer1 TRGO event selected + * @arg ADC_ExternalTrigInjecConv_T2_CC1: Timer2 capture compare1 selected + * @arg ADC_ExternalTrigInjecConv_T2_TRGO: Timer2 TRGO event selected + * @arg ADC_ExternalTrigInjecConv_T3_CC2: Timer3 capture compare2 selected + * @arg ADC_ExternalTrigInjecConv_T3_CC4: Timer3 capture compare4 selected + * @arg ADC_ExternalTrigInjecConv_T4_CC1: Timer4 capture compare1 selected + * @arg ADC_ExternalTrigInjecConv_T4_CC2: Timer4 capture compare2 selected + * @arg ADC_ExternalTrigInjecConv_T4_CC3: Timer4 capture compare3 selected + * @arg ADC_ExternalTrigInjecConv_T4_TRGO: Timer4 TRGO event selected + * @arg ADC_ExternalTrigInjecConv_T5_CC4: Timer5 capture compare4 selected + * @arg ADC_ExternalTrigInjecConv_T5_TRGO: Timer5 TRGO event selected + * @arg ADC_ExternalTrigInjecConv_T8_CC2: Timer8 capture compare2 selected + * @arg ADC_ExternalTrigInjecConv_T8_CC3: Timer8 capture compare3 selected + * @arg ADC_ExternalTrigInjecConv_T8_CC4: Timer8 capture compare4 selected + * @arg ADC_ExternalTrigInjecConv_Ext_IT15: External interrupt line 15 event selected + * @retval None + */ +void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_EXT_INJEC_TRIG(ADC_ExternalTrigInjecConv)); + + /* Get the old register value */ + tmpreg = ADCx->CR2; + + /* Clear the old external event selection for injected group */ + tmpreg &= CR2_JEXTSEL_RESET; + + /* Set the external event selection for injected group */ + tmpreg |= ADC_ExternalTrigInjecConv; + + /* Store the new register value */ + ADCx->CR2 = tmpreg; +} + +/** + * @brief Configures the ADCx external trigger edge for injected channels conversion. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_ExternalTrigInjecConvEdge: specifies the ADC external trigger edge + * to start injected conversion. + * This parameter can be one of the following values: + * @arg ADC_ExternalTrigInjecConvEdge_None: external trigger disabled for + * injected conversion + * @arg ADC_ExternalTrigInjecConvEdge_Rising: detection on rising edge + * @arg ADC_ExternalTrigInjecConvEdge_Falling: detection on falling edge + * @arg ADC_ExternalTrigInjecConvEdge_RisingFalling: detection on both rising + * and falling edge + * @retval None + */ +void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(ADC_ExternalTrigInjecConvEdge)); + /* Get the old register value */ + tmpreg = ADCx->CR2; + /* Clear the old external trigger edge for injected group */ + tmpreg &= CR2_JEXTEN_RESET; + /* Set the new external trigger edge for injected group */ + tmpreg |= ADC_ExternalTrigInjecConvEdge; + /* Store the new register value */ + ADCx->CR2 = tmpreg; +} + +/** + * @brief Enables the selected ADC software start conversion of the injected channels. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval None + */ +void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + /* Enable the selected ADC conversion for injected group */ + ADCx->CR2 |= (uint32_t)ADC_CR2_JSWSTART; +} + +/** + * @brief Gets the selected ADC Software start injected conversion Status. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval The new state of ADC software start injected conversion (SET or RESET). + */ +FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Check the status of JSWSTART bit */ + if ((ADCx->CR2 & ADC_CR2_JSWSTART) != (uint32_t)RESET) + { + /* JSWSTART bit is set */ + bitstatus = SET; + } + else + { + /* JSWSTART bit is reset */ + bitstatus = RESET; + } + /* Return the JSWSTART bit status */ + return bitstatus; +} + +/** + * @brief Enables or disables the selected ADC automatic injected group + * conversion after regular one. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC auto injected conversion + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC automatic injected group conversion */ + ADCx->CR1 |= (uint32_t)ADC_CR1_JAUTO; + } + else + { + /* Disable the selected ADC automatic injected group conversion */ + ADCx->CR1 &= (uint32_t)(~ADC_CR1_JAUTO); + } +} + +/** + * @brief Enables or disables the discontinuous mode for injected group + * channel for the specified ADC + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC discontinuous mode on injected + * group channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC injected discontinuous mode */ + ADCx->CR1 |= (uint32_t)ADC_CR1_JDISCEN; + } + else + { + /* Disable the selected ADC injected discontinuous mode */ + ADCx->CR1 &= (uint32_t)(~ADC_CR1_JDISCEN); + } +} + +/** + * @brief Returns the ADC injected channel conversion result + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_InjectedChannel: the converted ADC injected channel. + * This parameter can be one of the following values: + * @arg ADC_InjectedChannel_1: Injected Channel1 selected + * @arg ADC_InjectedChannel_2: Injected Channel2 selected + * @arg ADC_InjectedChannel_3: Injected Channel3 selected + * @arg ADC_InjectedChannel_4: Injected Channel4 selected + * @retval The Data conversion value. + */ +uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); + + tmp = (uint32_t)ADCx; + tmp += ADC_InjectedChannel + JDR_OFFSET; + + /* Returns the selected injected channel conversion data value */ + return (uint16_t) (*(__IO uint32_t*) tmp); +} +/** + * @} + */ + +/** @defgroup ADC_Group7 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + + This section provides functions allowing to configure the ADC Interrupts and + to get the status and clear flags and Interrupts pending bits. + + Each ADC provides 4 Interrupts sources and 6 Flags which can be divided into + 3 groups: + + I. Flags and Interrupts for ADC regular channels + ================================================= + Flags : + ---------- + 1. ADC_FLAG_OVR : Overrun detection when regular converted data are lost + + 2. ADC_FLAG_EOC : Regular channel end of conversion ==> to indicate (depending + on EOCS bit, managed by ADC_EOCOnEachRegularChannelCmd() ) the end of: + ==> a regular CHANNEL conversion + ==> sequence of regular GROUP conversions . + + 3. ADC_FLAG_STRT: Regular channel start ==> to indicate when regular CHANNEL + conversion starts. + + Interrupts : + ------------ + 1. ADC_IT_OVR : specifies the interrupt source for Overrun detection event. + 2. ADC_IT_EOC : specifies the interrupt source for Regular channel end of + conversion event. + + + II. Flags and Interrupts for ADC Injected channels + ================================================= + Flags : + ---------- + 1. ADC_FLAG_JEOC : Injected channel end of conversion ==> to indicate at + the end of injected GROUP conversion + + 2. ADC_FLAG_JSTRT: Injected channel start ==> to indicate hardware when + injected GROUP conversion starts. + + Interrupts : + ------------ + 1. ADC_IT_JEOC : specifies the interrupt source for Injected channel end of + conversion event. + + III. General Flags and Interrupts for the ADC + ================================================= + Flags : + ---------- + 1. ADC_FLAG_AWD: Analog watchdog ==> to indicate if the converted voltage + crosses the programmed thresholds values. + + Interrupts : + ------------ + 1. ADC_IT_AWD : specifies the interrupt source for Analog watchdog event. + + + The user should identify which mode will be used in his application to manage + the ADC controller events: Polling mode or Interrupt mode. + + In the Polling Mode it is advised to use the following functions: + - ADC_GetFlagStatus() : to check if flags events occur. + - ADC_ClearFlag() : to clear the flags events. + + In the Interrupt Mode it is advised to use the following functions: + - ADC_ITConfig() : to enable or disable the interrupt source. + - ADC_GetITStatus() : to check if Interrupt occurs. + - ADC_ClearITPendingBit() : to clear the Interrupt pending Bit + (corresponding Flag). +@endverbatim + * @{ + */ +/** + * @brief Enables or disables the specified ADC interrupts. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_IT: specifies the ADC interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg ADC_IT_EOC: End of conversion interrupt mask + * @arg ADC_IT_AWD: Analog watchdog interrupt mask + * @arg ADC_IT_JEOC: End of injected conversion interrupt mask + * @arg ADC_IT_OVR: Overrun interrupt enable + * @param NewState: new state of the specified ADC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState) +{ + uint32_t itmask = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_ADC_IT(ADC_IT)); + + /* Get the ADC IT index */ + itmask = (uint8_t)ADC_IT; + itmask = (uint32_t)0x01 << itmask; + + if (NewState != DISABLE) + { + /* Enable the selected ADC interrupts */ + ADCx->CR1 |= itmask; + } + else + { + /* Disable the selected ADC interrupts */ + ADCx->CR1 &= (~(uint32_t)itmask); + } +} + +/** + * @brief Checks whether the specified ADC flag is set or not. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg ADC_FLAG_AWD: Analog watchdog flag + * @arg ADC_FLAG_EOC: End of conversion flag + * @arg ADC_FLAG_JEOC: End of injected group conversion flag + * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag + * @arg ADC_FLAG_STRT: Start of regular group conversion flag + * @arg ADC_FLAG_OVR: Overrun flag + * @retval The new state of ADC_FLAG (SET or RESET). + */ +FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_GET_FLAG(ADC_FLAG)); + + /* Check the status of the specified ADC flag */ + if ((ADCx->SR & ADC_FLAG) != (uint8_t)RESET) + { + /* ADC_FLAG is set */ + bitstatus = SET; + } + else + { + /* ADC_FLAG is reset */ + bitstatus = RESET; + } + /* Return the ADC_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the ADCx's pending flags. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg ADC_FLAG_AWD: Analog watchdog flag + * @arg ADC_FLAG_EOC: End of conversion flag + * @arg ADC_FLAG_JEOC: End of injected group conversion flag + * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag + * @arg ADC_FLAG_STRT: Start of regular group conversion flag + * @arg ADC_FLAG_OVR: Overrun flag + * @retval None + */ +void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CLEAR_FLAG(ADC_FLAG)); + + /* Clear the selected ADC flags */ + ADCx->SR = ~(uint32_t)ADC_FLAG; +} + +/** + * @brief Checks whether the specified ADC interrupt has occurred or not. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_IT: specifies the ADC interrupt source to check. + * This parameter can be one of the following values: + * @arg ADC_IT_EOC: End of conversion interrupt mask + * @arg ADC_IT_AWD: Analog watchdog interrupt mask + * @arg ADC_IT_JEOC: End of injected conversion interrupt mask + * @arg ADC_IT_OVR: Overrun interrupt mask + * @retval The new state of ADC_IT (SET or RESET). + */ +ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t itmask = 0, enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_IT(ADC_IT)); + + /* Get the ADC IT index */ + itmask = ADC_IT >> 8; + + /* Get the ADC_IT enable bit status */ + enablestatus = (ADCx->CR1 & ((uint32_t)0x01 << (uint8_t)ADC_IT)) ; + + /* Check the status of the specified ADC interrupt */ + if (((ADCx->SR & itmask) != (uint32_t)RESET) && enablestatus) + { + /* ADC_IT is set */ + bitstatus = SET; + } + else + { + /* ADC_IT is reset */ + bitstatus = RESET; + } + /* Return the ADC_IT status */ + return bitstatus; +} + +/** + * @brief Clears the ADCx's interrupt pending bits. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_IT: specifies the ADC interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg ADC_IT_EOC: End of conversion interrupt mask + * @arg ADC_IT_AWD: Analog watchdog interrupt mask + * @arg ADC_IT_JEOC: End of injected conversion interrupt mask + * @arg ADC_IT_OVR: Overrun interrupt mask + * @retval None + */ +void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT) +{ + uint8_t itmask = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_IT(ADC_IT)); + /* Get the ADC IT index */ + itmask = (uint8_t)(ADC_IT >> 8); + /* Clear the selected ADC interrupt pending bits */ + ADCx->SR = ~(uint32_t)itmask; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_can.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_can.c new file mode 100644 index 0000000..8543ab8 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_can.c @@ -0,0 +1,1698 @@ +/** + ****************************************************************************** + * @file stm32f4xx_can.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Controller area network (CAN) peripheral: + * - Initialization and Configuration + * - CAN Frames Transmission + * - CAN Frames Reception + * - Operation modes switch + * - Error management + * - Interrupts and flags + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + + * 1. Enable the CAN controller interface clock using + * RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); for CAN1 + * and RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE); for CAN2 + * @note In case you are using CAN2 only, you have to enable the CAN1 clock. + * + * 2. CAN pins configuration + * - Enable the clock for the CAN GPIOs using the following function: + * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); + * - Connect the involved CAN pins to AF9 using the following function + * GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_CANx); + * - Configure these CAN pins in alternate function mode by calling + * the function GPIO_Init(); + * + * 3. Initialise and configure the CAN using CAN_Init() and + * CAN_FilterInit() functions. + * + * 4. Transmit the desired CAN frame using CAN_Transmit() function. + * + * 5. Check the transmission of a CAN frame using CAN_TransmitStatus() + * function. + * + * 6. Cancel the transmission of a CAN frame using CAN_CancelTransmit() + * function. + * + * 7. Receive a CAN frame using CAN_Recieve() function. + * + * 8. Release the receive FIFOs using CAN_FIFORelease() function. + * + * 9. Return the number of pending received frames using + * CAN_MessagePending() function. + * + * 10. To control CAN events you can use one of the following two methods: + * - Check on CAN flags using the CAN_GetFlagStatus() function. + * - Use CAN interrupts through the function CAN_ITConfig() at + * initialization phase and CAN_GetITStatus() function into + * interrupt routines to check if the event has occurred or not. + * After checking on a flag you should clear it using CAN_ClearFlag() + * function. And after checking on an interrupt event you should + * clear it using CAN_ClearITPendingBit() function. + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_can.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup CAN + * @brief CAN driver modules + * @{ + */ +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* CAN Master Control Register bits */ +#define MCR_DBF ((uint32_t)0x00010000) /* software master reset */ + +/* CAN Mailbox Transmit Request */ +#define TMIDxR_TXRQ ((uint32_t)0x00000001) /* Transmit mailbox request */ + +/* CAN Filter Master Register bits */ +#define FMR_FINIT ((uint32_t)0x00000001) /* Filter init mode */ + +/* Time out for INAK bit */ +#define INAK_TIMEOUT ((uint32_t)0x0000FFFF) +/* Time out for SLAK bit */ +#define SLAK_TIMEOUT ((uint32_t)0x0000FFFF) + +/* Flags in TSR register */ +#define CAN_FLAGS_TSR ((uint32_t)0x08000000) +/* Flags in RF1R register */ +#define CAN_FLAGS_RF1R ((uint32_t)0x04000000) +/* Flags in RF0R register */ +#define CAN_FLAGS_RF0R ((uint32_t)0x02000000) +/* Flags in MSR register */ +#define CAN_FLAGS_MSR ((uint32_t)0x01000000) +/* Flags in ESR register */ +#define CAN_FLAGS_ESR ((uint32_t)0x00F00000) + +/* Mailboxes definition */ +#define CAN_TXMAILBOX_0 ((uint8_t)0x00) +#define CAN_TXMAILBOX_1 ((uint8_t)0x01) +#define CAN_TXMAILBOX_2 ((uint8_t)0x02) + +#define CAN_MODE_MASK ((uint32_t) 0x00000003) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit); + +/** @defgroup CAN_Private_Functions + * @{ + */ + +/** @defgroup CAN_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + This section provides functions allowing to + - Initialize the CAN peripherals : Prescaler, operating mode, the maximum number + of time quanta to perform resynchronization, the number of time quanta in + Bit Segment 1 and 2 and many other modes. + Refer to @ref CAN_InitTypeDef for more details. + - Configures the CAN reception filter. + - Select the start bank filter for slave CAN. + - Enables or disables the Debug Freeze mode for CAN + - Enables or disables the CAN Time Trigger Operation communication mode + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the CAN peripheral registers to their default reset values. + * @param CANx: where x can be 1 or 2 to select the CAN peripheral. + * @retval None. + */ +void CAN_DeInit(CAN_TypeDef* CANx) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + + if (CANx == CAN1) + { + /* Enable CAN1 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE); + /* Release CAN1 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE); + } + else + { + /* Enable CAN2 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, ENABLE); + /* Release CAN2 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, DISABLE); + } +} + +/** + * @brief Initializes the CAN peripheral according to the specified + * parameters in the CAN_InitStruct. + * @param CANx: where x can be 1 or 2 to select the CAN peripheral. + * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure that contains + * the configuration information for the CAN peripheral. + * @retval Constant indicates initialization succeed which will be + * CAN_InitStatus_Failed or CAN_InitStatus_Success. + */ +uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct) +{ + uint8_t InitStatus = CAN_InitStatus_Failed; + uint32_t wait_ack = 0x00000000; + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TTCM)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_ABOM)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_AWUM)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_NART)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_RFLM)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TXFP)); + assert_param(IS_CAN_MODE(CAN_InitStruct->CAN_Mode)); + assert_param(IS_CAN_SJW(CAN_InitStruct->CAN_SJW)); + assert_param(IS_CAN_BS1(CAN_InitStruct->CAN_BS1)); + assert_param(IS_CAN_BS2(CAN_InitStruct->CAN_BS2)); + assert_param(IS_CAN_PRESCALER(CAN_InitStruct->CAN_Prescaler)); + + /* Exit from sleep mode */ + CANx->MCR &= (~(uint32_t)CAN_MCR_SLEEP); + + /* Request initialisation */ + CANx->MCR |= CAN_MCR_INRQ ; + + /* Wait the acknowledge */ + while (((CANx->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) && (wait_ack != INAK_TIMEOUT)) + { + wait_ack++; + } + + /* Check acknowledge */ + if ((CANx->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) + { + InitStatus = CAN_InitStatus_Failed; + } + else + { + /* Set the time triggered communication mode */ + if (CAN_InitStruct->CAN_TTCM == ENABLE) + { + CANx->MCR |= CAN_MCR_TTCM; + } + else + { + CANx->MCR &= ~(uint32_t)CAN_MCR_TTCM; + } + + /* Set the automatic bus-off management */ + if (CAN_InitStruct->CAN_ABOM == ENABLE) + { + CANx->MCR |= CAN_MCR_ABOM; + } + else + { + CANx->MCR &= ~(uint32_t)CAN_MCR_ABOM; + } + + /* Set the automatic wake-up mode */ + if (CAN_InitStruct->CAN_AWUM == ENABLE) + { + CANx->MCR |= CAN_MCR_AWUM; + } + else + { + CANx->MCR &= ~(uint32_t)CAN_MCR_AWUM; + } + + /* Set the no automatic retransmission */ + if (CAN_InitStruct->CAN_NART == ENABLE) + { + CANx->MCR |= CAN_MCR_NART; + } + else + { + CANx->MCR &= ~(uint32_t)CAN_MCR_NART; + } + + /* Set the receive FIFO locked mode */ + if (CAN_InitStruct->CAN_RFLM == ENABLE) + { + CANx->MCR |= CAN_MCR_RFLM; + } + else + { + CANx->MCR &= ~(uint32_t)CAN_MCR_RFLM; + } + + /* Set the transmit FIFO priority */ + if (CAN_InitStruct->CAN_TXFP == ENABLE) + { + CANx->MCR |= CAN_MCR_TXFP; + } + else + { + CANx->MCR &= ~(uint32_t)CAN_MCR_TXFP; + } + + /* Set the bit timing register */ + CANx->BTR = (uint32_t)((uint32_t)CAN_InitStruct->CAN_Mode << 30) | \ + ((uint32_t)CAN_InitStruct->CAN_SJW << 24) | \ + ((uint32_t)CAN_InitStruct->CAN_BS1 << 16) | \ + ((uint32_t)CAN_InitStruct->CAN_BS2 << 20) | \ + ((uint32_t)CAN_InitStruct->CAN_Prescaler - 1); + + /* Request leave initialisation */ + CANx->MCR &= ~(uint32_t)CAN_MCR_INRQ; + + /* Wait the acknowledge */ + wait_ack = 0; + + while (((CANx->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) && (wait_ack != INAK_TIMEOUT)) + { + wait_ack++; + } + + /* ...and check acknowledged */ + if ((CANx->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) + { + InitStatus = CAN_InitStatus_Failed; + } + else + { + InitStatus = CAN_InitStatus_Success ; + } + } + + /* At this step, return the status of initialization */ + return InitStatus; +} + +/** + * @brief Configures the CAN reception filter according to the specified + * parameters in the CAN_FilterInitStruct. + * @param CAN_FilterInitStruct: pointer to a CAN_FilterInitTypeDef structure that + * contains the configuration information. + * @retval None + */ +void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct) +{ + uint32_t filter_number_bit_pos = 0; + /* Check the parameters */ + assert_param(IS_CAN_FILTER_NUMBER(CAN_FilterInitStruct->CAN_FilterNumber)); + assert_param(IS_CAN_FILTER_MODE(CAN_FilterInitStruct->CAN_FilterMode)); + assert_param(IS_CAN_FILTER_SCALE(CAN_FilterInitStruct->CAN_FilterScale)); + assert_param(IS_CAN_FILTER_FIFO(CAN_FilterInitStruct->CAN_FilterFIFOAssignment)); + assert_param(IS_FUNCTIONAL_STATE(CAN_FilterInitStruct->CAN_FilterActivation)); + + filter_number_bit_pos = ((uint32_t)1) << CAN_FilterInitStruct->CAN_FilterNumber; + + /* Initialisation mode for the filter */ + CAN1->FMR |= FMR_FINIT; + + /* Filter Deactivation */ + CAN1->FA1R &= ~(uint32_t)filter_number_bit_pos; + + /* Filter Scale */ + if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_16bit) + { + /* 16-bit scale for the filter */ + CAN1->FS1R &= ~(uint32_t)filter_number_bit_pos; + + /* First 16-bit identifier and First 16-bit mask */ + /* Or First 16-bit identifier and Second 16-bit identifier */ + CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = + ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow) << 16) | + (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow); + + /* Second 16-bit identifier and Second 16-bit mask */ + /* Or Third 16-bit identifier and Fourth 16-bit identifier */ + CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 = + ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) | + (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh); + } + + if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_32bit) + { + /* 32-bit scale for the filter */ + CAN1->FS1R |= filter_number_bit_pos; + /* 32-bit identifier or First 32-bit identifier */ + CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = + ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh) << 16) | + (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow); + /* 32-bit mask or Second 32-bit identifier */ + CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 = + ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) | + (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow); + } + + /* Filter Mode */ + if (CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdMask) + { + /*Id/Mask mode for the filter*/ + CAN1->FM1R &= ~(uint32_t)filter_number_bit_pos; + } + else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */ + { + /*Identifier list mode for the filter*/ + CAN1->FM1R |= (uint32_t)filter_number_bit_pos; + } + + /* Filter FIFO assignment */ + if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_Filter_FIFO0) + { + /* FIFO 0 assignation for the filter */ + CAN1->FFA1R &= ~(uint32_t)filter_number_bit_pos; + } + + if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_Filter_FIFO1) + { + /* FIFO 1 assignation for the filter */ + CAN1->FFA1R |= (uint32_t)filter_number_bit_pos; + } + + /* Filter activation */ + if (CAN_FilterInitStruct->CAN_FilterActivation == ENABLE) + { + CAN1->FA1R |= filter_number_bit_pos; + } + + /* Leave the initialisation mode for the filter */ + CAN1->FMR &= ~FMR_FINIT; +} + +/** + * @brief Fills each CAN_InitStruct member with its default value. + * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure which ill be initialized. + * @retval None + */ +void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct) +{ + /* Reset CAN init structure parameters values */ + + /* Initialize the time triggered communication mode */ + CAN_InitStruct->CAN_TTCM = DISABLE; + + /* Initialize the automatic bus-off management */ + CAN_InitStruct->CAN_ABOM = DISABLE; + + /* Initialize the automatic wake-up mode */ + CAN_InitStruct->CAN_AWUM = DISABLE; + + /* Initialize the no automatic retransmission */ + CAN_InitStruct->CAN_NART = DISABLE; + + /* Initialize the receive FIFO locked mode */ + CAN_InitStruct->CAN_RFLM = DISABLE; + + /* Initialize the transmit FIFO priority */ + CAN_InitStruct->CAN_TXFP = DISABLE; + + /* Initialize the CAN_Mode member */ + CAN_InitStruct->CAN_Mode = CAN_Mode_Normal; + + /* Initialize the CAN_SJW member */ + CAN_InitStruct->CAN_SJW = CAN_SJW_1tq; + + /* Initialize the CAN_BS1 member */ + CAN_InitStruct->CAN_BS1 = CAN_BS1_4tq; + + /* Initialize the CAN_BS2 member */ + CAN_InitStruct->CAN_BS2 = CAN_BS2_3tq; + + /* Initialize the CAN_Prescaler member */ + CAN_InitStruct->CAN_Prescaler = 1; +} + +/** + * @brief Select the start bank filter for slave CAN. + * @param CAN_BankNumber: Select the start slave bank filter from 1..27. + * @retval None + */ +void CAN_SlaveStartBank(uint8_t CAN_BankNumber) +{ + /* Check the parameters */ + assert_param(IS_CAN_BANKNUMBER(CAN_BankNumber)); + + /* Enter Initialisation mode for the filter */ + CAN1->FMR |= FMR_FINIT; + + /* Select the start slave bank */ + CAN1->FMR &= (uint32_t)0xFFFFC0F1 ; + CAN1->FMR |= (uint32_t)(CAN_BankNumber)<<8; + + /* Leave Initialisation mode for the filter */ + CAN1->FMR &= ~FMR_FINIT; +} + +/** + * @brief Enables or disables the DBG Freeze for CAN. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param NewState: new state of the CAN peripheral. + * This parameter can be: ENABLE (CAN reception/transmission is frozen + * during debug. Reception FIFOs can still be accessed/controlled normally) + * or DISABLE (CAN is working during debug). + * @retval None + */ +void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable Debug Freeze */ + CANx->MCR |= MCR_DBF; + } + else + { + /* Disable Debug Freeze */ + CANx->MCR &= ~MCR_DBF; + } +} + + +/** + * @brief Enables or disables the CAN Time TriggerOperation communication mode. + * @note DLC must be programmed as 8 in order Time Stamp (2 bytes) to be + * sent over the CAN bus. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param NewState: Mode new state. This parameter can be: ENABLE or DISABLE. + * When enabled, Time stamp (TIME[15:0]) value is sent in the last two + * data bytes of the 8-byte message: TIME[7:0] in data byte 6 and TIME[15:8] + * in data byte 7. + * @retval None + */ +void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the TTCM mode */ + CANx->MCR |= CAN_MCR_TTCM; + + /* Set TGT bits */ + CANx->sTxMailBox[0].TDTR |= ((uint32_t)CAN_TDT0R_TGT); + CANx->sTxMailBox[1].TDTR |= ((uint32_t)CAN_TDT1R_TGT); + CANx->sTxMailBox[2].TDTR |= ((uint32_t)CAN_TDT2R_TGT); + } + else + { + /* Disable the TTCM mode */ + CANx->MCR &= (uint32_t)(~(uint32_t)CAN_MCR_TTCM); + + /* Reset TGT bits */ + CANx->sTxMailBox[0].TDTR &= ((uint32_t)~CAN_TDT0R_TGT); + CANx->sTxMailBox[1].TDTR &= ((uint32_t)~CAN_TDT1R_TGT); + CANx->sTxMailBox[2].TDTR &= ((uint32_t)~CAN_TDT2R_TGT); + } +} +/** + * @} + */ + + +/** @defgroup CAN_Group2 CAN Frames Transmission functions + * @brief CAN Frames Transmission functions + * +@verbatim + =============================================================================== + CAN Frames Transmission functions + =============================================================================== + This section provides functions allowing to + - Initiate and transmit a CAN frame message (if there is an empty mailbox). + - Check the transmission status of a CAN Frame + - Cancel a transmit request + +@endverbatim + * @{ + */ + +/** + * @brief Initiates and transmits a CAN frame message. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param TxMessage: pointer to a structure which contains CAN Id, CAN DLC and CAN data. + * @retval The number of the mailbox that is used for transmission or + * CAN_TxStatus_NoMailBox if there is no empty mailbox. + */ +uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage) +{ + uint8_t transmit_mailbox = 0; + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_IDTYPE(TxMessage->IDE)); + assert_param(IS_CAN_RTR(TxMessage->RTR)); + assert_param(IS_CAN_DLC(TxMessage->DLC)); + + /* Select one empty transmit mailbox */ + if ((CANx->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) + { + transmit_mailbox = 0; + } + else if ((CANx->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) + { + transmit_mailbox = 1; + } + else if ((CANx->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) + { + transmit_mailbox = 2; + } + else + { + transmit_mailbox = CAN_TxStatus_NoMailBox; + } + + if (transmit_mailbox != CAN_TxStatus_NoMailBox) + { + /* Set up the Id */ + CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ; + if (TxMessage->IDE == CAN_Id_Standard) + { + assert_param(IS_CAN_STDID(TxMessage->StdId)); + CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | \ + TxMessage->RTR); + } + else + { + assert_param(IS_CAN_EXTID(TxMessage->ExtId)); + CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId << 3) | \ + TxMessage->IDE | \ + TxMessage->RTR); + } + + /* Set up the DLC */ + TxMessage->DLC &= (uint8_t)0x0000000F; + CANx->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0; + CANx->sTxMailBox[transmit_mailbox].TDTR |= TxMessage->DLC; + + /* Set up the data field */ + CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] << 24) | + ((uint32_t)TxMessage->Data[2] << 16) | + ((uint32_t)TxMessage->Data[1] << 8) | + ((uint32_t)TxMessage->Data[0])); + CANx->sTxMailBox[transmit_mailbox].TDHR = (((uint32_t)TxMessage->Data[7] << 24) | + ((uint32_t)TxMessage->Data[6] << 16) | + ((uint32_t)TxMessage->Data[5] << 8) | + ((uint32_t)TxMessage->Data[4])); + /* Request transmission */ + CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ; + } + return transmit_mailbox; +} + +/** + * @brief Checks the transmission status of a CAN Frame. + * @param CANx: where x can be 1 or 2 to select the CAN peripheral. + * @param TransmitMailbox: the number of the mailbox that is used for transmission. + * @retval CAN_TxStatus_Ok if the CAN driver transmits the message, + * CAN_TxStatus_Failed in an other case. + */ +uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox) +{ + uint32_t state = 0; + + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_TRANSMITMAILBOX(TransmitMailbox)); + + switch (TransmitMailbox) + { + case (CAN_TXMAILBOX_0): + state = CANx->TSR & (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0); + break; + case (CAN_TXMAILBOX_1): + state = CANx->TSR & (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1); + break; + case (CAN_TXMAILBOX_2): + state = CANx->TSR & (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2); + break; + default: + state = CAN_TxStatus_Failed; + break; + } + switch (state) + { + /* transmit pending */ + case (0x0): state = CAN_TxStatus_Pending; + break; + /* transmit failed */ + case (CAN_TSR_RQCP0 | CAN_TSR_TME0): state = CAN_TxStatus_Failed; + break; + case (CAN_TSR_RQCP1 | CAN_TSR_TME1): state = CAN_TxStatus_Failed; + break; + case (CAN_TSR_RQCP2 | CAN_TSR_TME2): state = CAN_TxStatus_Failed; + break; + /* transmit succeeded */ + case (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0):state = CAN_TxStatus_Ok; + break; + case (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1):state = CAN_TxStatus_Ok; + break; + case (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2):state = CAN_TxStatus_Ok; + break; + default: state = CAN_TxStatus_Failed; + break; + } + return (uint8_t) state; +} + +/** + * @brief Cancels a transmit request. + * @param CANx: where x can be 1 or 2 to select the CAN peripheral. + * @param Mailbox: Mailbox number. + * @retval None + */ +void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_TRANSMITMAILBOX(Mailbox)); + /* abort transmission */ + switch (Mailbox) + { + case (CAN_TXMAILBOX_0): CANx->TSR |= CAN_TSR_ABRQ0; + break; + case (CAN_TXMAILBOX_1): CANx->TSR |= CAN_TSR_ABRQ1; + break; + case (CAN_TXMAILBOX_2): CANx->TSR |= CAN_TSR_ABRQ2; + break; + default: + break; + } +} +/** + * @} + */ + + +/** @defgroup CAN_Group3 CAN Frames Reception functions + * @brief CAN Frames Reception functions + * +@verbatim + =============================================================================== + CAN Frames Reception functions + =============================================================================== + This section provides functions allowing to + - Receive a correct CAN frame + - Release a specified receive FIFO (2 FIFOs are available) + - Return the number of the pending received CAN frames + +@endverbatim + * @{ + */ + +/** + * @brief Receives a correct CAN frame. + * @param CANx: where x can be 1 or 2 to select the CAN peripheral. + * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1. + * @param RxMessage: pointer to a structure receive frame which contains CAN Id, + * CAN DLC, CAN data and FMI number. + * @retval None + */ +void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_FIFO(FIFONumber)); + /* Get the Id */ + RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR; + if (RxMessage->IDE == CAN_Id_Standard) + { + RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21); + } + else + { + RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 3); + } + + RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONumber].RIR; + /* Get the DLC */ + RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONumber].RDTR; + /* Get the FMI */ + RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDTR >> 8); + /* Get the data field */ + RxMessage->Data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDLR; + RxMessage->Data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 8); + RxMessage->Data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 16); + RxMessage->Data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 24); + RxMessage->Data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDHR; + RxMessage->Data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 8); + RxMessage->Data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 16); + RxMessage->Data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 24); + /* Release the FIFO */ + /* Release FIFO0 */ + if (FIFONumber == CAN_FIFO0) + { + CANx->RF0R |= CAN_RF0R_RFOM0; + } + /* Release FIFO1 */ + else /* FIFONumber == CAN_FIFO1 */ + { + CANx->RF1R |= CAN_RF1R_RFOM1; + } +} + +/** + * @brief Releases the specified receive FIFO. + * @param CANx: where x can be 1 or 2 to select the CAN peripheral. + * @param FIFONumber: FIFO to release, CAN_FIFO0 or CAN_FIFO1. + * @retval None + */ +void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_FIFO(FIFONumber)); + /* Release FIFO0 */ + if (FIFONumber == CAN_FIFO0) + { + CANx->RF0R |= CAN_RF0R_RFOM0; + } + /* Release FIFO1 */ + else /* FIFONumber == CAN_FIFO1 */ + { + CANx->RF1R |= CAN_RF1R_RFOM1; + } +} + +/** + * @brief Returns the number of pending received messages. + * @param CANx: where x can be 1 or 2 to select the CAN peripheral. + * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1. + * @retval NbMessage : which is the number of pending message. + */ +uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber) +{ + uint8_t message_pending=0; + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_FIFO(FIFONumber)); + if (FIFONumber == CAN_FIFO0) + { + message_pending = (uint8_t)(CANx->RF0R&(uint32_t)0x03); + } + else if (FIFONumber == CAN_FIFO1) + { + message_pending = (uint8_t)(CANx->RF1R&(uint32_t)0x03); + } + else + { + message_pending = 0; + } + return message_pending; +} +/** + * @} + */ + + +/** @defgroup CAN_Group4 CAN Operation modes functions + * @brief CAN Operation modes functions + * +@verbatim + =============================================================================== + CAN Operation modes functions + =============================================================================== + This section provides functions allowing to select the CAN Operation modes + - sleep mode + - normal mode + - initialization mode + +@endverbatim + * @{ + */ + + +/** + * @brief Selects the CAN Operation mode. + * @param CAN_OperatingMode: CAN Operating Mode. + * This parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration. + * @retval status of the requested mode which can be + * - CAN_ModeStatus_Failed: CAN failed entering the specific mode + * - CAN_ModeStatus_Success: CAN Succeed entering the specific mode + */ +uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode) +{ + uint8_t status = CAN_ModeStatus_Failed; + + /* Timeout for INAK or also for SLAK bits*/ + uint32_t timeout = INAK_TIMEOUT; + + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_OPERATING_MODE(CAN_OperatingMode)); + + if (CAN_OperatingMode == CAN_OperatingMode_Initialization) + { + /* Request initialisation */ + CANx->MCR = (uint32_t)((CANx->MCR & (uint32_t)(~(uint32_t)CAN_MCR_SLEEP)) | CAN_MCR_INRQ); + + /* Wait the acknowledge */ + while (((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_INAK) && (timeout != 0)) + { + timeout--; + } + if ((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_INAK) + { + status = CAN_ModeStatus_Failed; + } + else + { + status = CAN_ModeStatus_Success; + } + } + else if (CAN_OperatingMode == CAN_OperatingMode_Normal) + { + /* Request leave initialisation and sleep mode and enter Normal mode */ + CANx->MCR &= (uint32_t)(~(CAN_MCR_SLEEP|CAN_MCR_INRQ)); + + /* Wait the acknowledge */ + while (((CANx->MSR & CAN_MODE_MASK) != 0) && (timeout!=0)) + { + timeout--; + } + if ((CANx->MSR & CAN_MODE_MASK) != 0) + { + status = CAN_ModeStatus_Failed; + } + else + { + status = CAN_ModeStatus_Success; + } + } + else if (CAN_OperatingMode == CAN_OperatingMode_Sleep) + { + /* Request Sleep mode */ + CANx->MCR = (uint32_t)((CANx->MCR & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP); + + /* Wait the acknowledge */ + while (((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK) && (timeout!=0)) + { + timeout--; + } + if ((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK) + { + status = CAN_ModeStatus_Failed; + } + else + { + status = CAN_ModeStatus_Success; + } + } + else + { + status = CAN_ModeStatus_Failed; + } + + return (uint8_t) status; +} + +/** + * @brief Enters the Sleep (low power) mode. + * @param CANx: where x can be 1 or 2 to select the CAN peripheral. + * @retval CAN_Sleep_Ok if sleep entered, CAN_Sleep_Failed otherwise. + */ +uint8_t CAN_Sleep(CAN_TypeDef* CANx) +{ + uint8_t sleepstatus = CAN_Sleep_Failed; + + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + + /* Request Sleep mode */ + CANx->MCR = (((CANx->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP); + + /* Sleep mode status */ + if ((CANx->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) == CAN_MSR_SLAK) + { + /* Sleep mode not entered */ + sleepstatus = CAN_Sleep_Ok; + } + /* return sleep mode status */ + return (uint8_t)sleepstatus; +} + +/** + * @brief Wakes up the CAN peripheral from sleep mode . + * @param CANx: where x can be 1 or 2 to select the CAN peripheral. + * @retval CAN_WakeUp_Ok if sleep mode left, CAN_WakeUp_Failed otherwise. + */ +uint8_t CAN_WakeUp(CAN_TypeDef* CANx) +{ + uint32_t wait_slak = SLAK_TIMEOUT; + uint8_t wakeupstatus = CAN_WakeUp_Failed; + + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + + /* Wake up request */ + CANx->MCR &= ~(uint32_t)CAN_MCR_SLEEP; + + /* Sleep mode status */ + while(((CANx->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)&&(wait_slak!=0x00)) + { + wait_slak--; + } + if((CANx->MSR & CAN_MSR_SLAK) != CAN_MSR_SLAK) + { + /* wake up done : Sleep mode exited */ + wakeupstatus = CAN_WakeUp_Ok; + } + /* return wakeup status */ + return (uint8_t)wakeupstatus; +} +/** + * @} + */ + + +/** @defgroup CAN_Group5 CAN Bus Error management functions + * @brief CAN Bus Error management functions + * +@verbatim + =============================================================================== + CAN Bus Error management functions + =============================================================================== + This section provides functions allowing to + - Return the CANx's last error code (LEC) + - Return the CANx Receive Error Counter (REC) + - Return the LSB of the 9-bit CANx Transmit Error Counter(TEC). + + @note If TEC is greater than 255, The CAN is in bus-off state. + @note if REC or TEC are greater than 96, an Error warning flag occurs. + @note if REC or TEC are greater than 127, an Error Passive Flag occurs. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the CANx's last error code (LEC). + * @param CANx: where x can be 1 or 2 to select the CAN peripheral. + * @retval Error code: + * - CAN_ERRORCODE_NoErr: No Error + * - CAN_ERRORCODE_StuffErr: Stuff Error + * - CAN_ERRORCODE_FormErr: Form Error + * - CAN_ERRORCODE_ACKErr : Acknowledgment Error + * - CAN_ERRORCODE_BitRecessiveErr: Bit Recessive Error + * - CAN_ERRORCODE_BitDominantErr: Bit Dominant Error + * - CAN_ERRORCODE_CRCErr: CRC Error + * - CAN_ERRORCODE_SoftwareSetErr: Software Set Error + */ +uint8_t CAN_GetLastErrorCode(CAN_TypeDef* CANx) +{ + uint8_t errorcode=0; + + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + + /* Get the error code*/ + errorcode = (((uint8_t)CANx->ESR) & (uint8_t)CAN_ESR_LEC); + + /* Return the error code*/ + return errorcode; +} + +/** + * @brief Returns the CANx Receive Error Counter (REC). + * @note In case of an error during reception, this counter is incremented + * by 1 or by 8 depending on the error condition as defined by the CAN + * standard. After every successful reception, the counter is + * decremented by 1 or reset to 120 if its value was higher than 128. + * When the counter value exceeds 127, the CAN controller enters the + * error passive state. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @retval CAN Receive Error Counter. + */ +uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef* CANx) +{ + uint8_t counter=0; + + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + + /* Get the Receive Error Counter*/ + counter = (uint8_t)((CANx->ESR & CAN_ESR_REC)>> 24); + + /* Return the Receive Error Counter*/ + return counter; +} + + +/** + * @brief Returns the LSB of the 9-bit CANx Transmit Error Counter(TEC). + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @retval LSB of the 9-bit CAN Transmit Error Counter. + */ +uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef* CANx) +{ + uint8_t counter=0; + + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + + /* Get the LSB of the 9-bit CANx Transmit Error Counter(TEC) */ + counter = (uint8_t)((CANx->ESR & CAN_ESR_TEC)>> 16); + + /* Return the LSB of the 9-bit CANx Transmit Error Counter(TEC) */ + return counter; +} +/** + * @} + */ + +/** @defgroup CAN_Group6 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + + This section provides functions allowing to configure the CAN Interrupts and + to get the status and clear flags and Interrupts pending bits. + + The CAN provides 14 Interrupts sources and 15 Flags: + + =============== + Flags : + =============== + The 15 flags can be divided on 4 groups: + + A. Transmit Flags + ----------------------- + CAN_FLAG_RQCP0, + CAN_FLAG_RQCP1, + CAN_FLAG_RQCP2 : Request completed MailBoxes 0, 1 and 2 Flags + Set when when the last request (transmit or abort) has + been performed. + + B. Receive Flags + ----------------------- + + CAN_FLAG_FMP0, + CAN_FLAG_FMP1 : FIFO 0 and 1 Message Pending Flags + set to signal that messages are pending in the receive + FIFO. + These Flags are cleared only by hardware. + + CAN_FLAG_FF0, + CAN_FLAG_FF1 : FIFO 0 and 1 Full Flags + set when three messages are stored in the selected + FIFO. + + CAN_FLAG_FOV0 + CAN_FLAG_FOV1 : FIFO 0 and 1 Overrun Flags + set when a new message has been received and passed + the filter while the FIFO was full. + + C. Operating Mode Flags + ----------------------- + CAN_FLAG_WKU : Wake up Flag + set to signal that a SOF bit has been detected while + the CAN hardware was in Sleep mode. + + CAN_FLAG_SLAK : Sleep acknowledge Flag + Set to signal that the CAN has entered Sleep Mode. + + D. Error Flags + ----------------------- + CAN_FLAG_EWG : Error Warning Flag + Set when the warning limit has been reached (Receive + Error Counter or Transmit Error Counter greater than 96). + This Flag is cleared only by hardware. + + CAN_FLAG_EPV : Error Passive Flag + Set when the Error Passive limit has been reached + (Receive Error Counter or Transmit Error Counter + greater than 127). + This Flag is cleared only by hardware. + + CAN_FLAG_BOF : Bus-Off Flag + set when CAN enters the bus-off state. The bus-off + state is entered on TEC overflow, greater than 255. + This Flag is cleared only by hardware. + + CAN_FLAG_LEC : Last error code Flag + set If a message has been transferred (reception or + transmission) with error, and the error code is hold. + + =============== + Interrupts : + =============== + The 14 interrupts can be divided on 4 groups: + + A. Transmit interrupt + ----------------------- + CAN_IT_TME : Transmit mailbox empty Interrupt + if enabled, this interrupt source is pending when + no transmit request are pending for Tx mailboxes. + + B. Receive Interrupts + ----------------------- + CAN_IT_FMP0, + CAN_IT_FMP1 : FIFO 0 and FIFO1 message pending Interrupts + if enabled, these interrupt sources are pending when + messages are pending in the receive FIFO. + The corresponding interrupt pending bits are cleared + only by hardware. + + CAN_IT_FF0, + CAN_IT_FF1 : FIFO 0 and FIFO1 full Interrupts + if enabled, these interrupt sources are pending when + three messages are stored in the selected FIFO. + + CAN_IT_FOV0, + CAN_IT_FOV1 : FIFO 0 and FIFO1 overrun Interrupts + if enabled, these interrupt sources are pending when + a new message has been received and passed the filter + while the FIFO was full. + + C. Operating Mode Interrupts + ------------------------------- + CAN_IT_WKU : Wake-up Interrupt + if enabled, this interrupt source is pending when + a SOF bit has been detected while the CAN hardware was + in Sleep mode. + + CAN_IT_SLK : Sleep acknowledge Interrupt + if enabled, this interrupt source is pending when + the CAN has entered Sleep Mode. + + D. Error Interrupts + ----------------------- + CAN_IT_EWG : Error warning Interrupt + if enabled, this interrupt source is pending when + the warning limit has been reached (Receive Error + Counter or Transmit Error Counter=96). + + CAN_IT_EPV : Error passive Interrupt + if enabled, this interrupt source is pending when + the Error Passive limit has been reached (Receive + Error Counter or Transmit Error Counter>127). + + CAN_IT_BOF : Bus-off Interrupt + if enabled, this interrupt source is pending when + CAN enters the bus-off state. The bus-off state is + entered on TEC overflow, greater than 255. + This Flag is cleared only by hardware. + + CAN_IT_LEC : Last error code Interrupt + if enabled, this interrupt source is pending when + a message has been transferred (reception or + transmission) with error, and the error code is hold. + + CAN_IT_ERR : Error Interrupt + if enabled, this interrupt source is pending when + an error condition is pending. + + + Managing the CAN controller events : + ------------------------------------ + The user should identify which mode will be used in his application to manage + the CAN controller events: Polling mode or Interrupt mode. + + 1. In the Polling Mode it is advised to use the following functions: + - CAN_GetFlagStatus() : to check if flags events occur. + - CAN_ClearFlag() : to clear the flags events. + + + + 2. In the Interrupt Mode it is advised to use the following functions: + - CAN_ITConfig() : to enable or disable the interrupt source. + - CAN_GetITStatus() : to check if Interrupt occurs. + - CAN_ClearITPendingBit() : to clear the Interrupt pending Bit (corresponding Flag). + @note This function has no impact on CAN_IT_FMP0 and CAN_IT_FMP1 Interrupts + pending bits since there are cleared only by hardware. + +@endverbatim + * @{ + */ +/** + * @brief Enables or disables the specified CANx interrupts. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param CAN_IT: specifies the CAN interrupt sources to be enabled or disabled. + * This parameter can be: + * @arg CAN_IT_TME: Transmit mailbox empty Interrupt + * @arg CAN_IT_FMP0: FIFO 0 message pending Interrupt + * @arg CAN_IT_FF0: FIFO 0 full Interrupt + * @arg CAN_IT_FOV0: FIFO 0 overrun Interrupt + * @arg CAN_IT_FMP1: FIFO 1 message pending Interrupt + * @arg CAN_IT_FF1: FIFO 1 full Interrupt + * @arg CAN_IT_FOV1: FIFO 1 overrun Interrupt + * @arg CAN_IT_WKU: Wake-up Interrupt + * @arg CAN_IT_SLK: Sleep acknowledge Interrupt + * @arg CAN_IT_EWG: Error warning Interrupt + * @arg CAN_IT_EPV: Error passive Interrupt + * @arg CAN_IT_BOF: Bus-off Interrupt + * @arg CAN_IT_LEC: Last error code Interrupt + * @arg CAN_IT_ERR: Error Interrupt + * @param NewState: new state of the CAN interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_IT(CAN_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected CANx interrupt */ + CANx->IER |= CAN_IT; + } + else + { + /* Disable the selected CANx interrupt */ + CANx->IER &= ~CAN_IT; + } +} +/** + * @brief Checks whether the specified CAN flag is set or not. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param CAN_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag + * @arg CAN_FLAG_RQCP1: Request MailBox1 Flag + * @arg CAN_FLAG_RQCP2: Request MailBox2 Flag + * @arg CAN_FLAG_FMP0: FIFO 0 Message Pending Flag + * @arg CAN_FLAG_FF0: FIFO 0 Full Flag + * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag + * @arg CAN_FLAG_FMP1: FIFO 1 Message Pending Flag + * @arg CAN_FLAG_FF1: FIFO 1 Full Flag + * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag + * @arg CAN_FLAG_WKU: Wake up Flag + * @arg CAN_FLAG_SLAK: Sleep acknowledge Flag + * @arg CAN_FLAG_EWG: Error Warning Flag + * @arg CAN_FLAG_EPV: Error Passive Flag + * @arg CAN_FLAG_BOF: Bus-Off Flag + * @arg CAN_FLAG_LEC: Last error code Flag + * @retval The new state of CAN_FLAG (SET or RESET). + */ +FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_GET_FLAG(CAN_FLAG)); + + + if((CAN_FLAG & CAN_FLAGS_ESR) != (uint32_t)RESET) + { + /* Check the status of the specified CAN flag */ + if ((CANx->ESR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET) + { + /* CAN_FLAG is set */ + bitstatus = SET; + } + else + { + /* CAN_FLAG is reset */ + bitstatus = RESET; + } + } + else if((CAN_FLAG & CAN_FLAGS_MSR) != (uint32_t)RESET) + { + /* Check the status of the specified CAN flag */ + if ((CANx->MSR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET) + { + /* CAN_FLAG is set */ + bitstatus = SET; + } + else + { + /* CAN_FLAG is reset */ + bitstatus = RESET; + } + } + else if((CAN_FLAG & CAN_FLAGS_TSR) != (uint32_t)RESET) + { + /* Check the status of the specified CAN flag */ + if ((CANx->TSR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET) + { + /* CAN_FLAG is set */ + bitstatus = SET; + } + else + { + /* CAN_FLAG is reset */ + bitstatus = RESET; + } + } + else if((CAN_FLAG & CAN_FLAGS_RF0R) != (uint32_t)RESET) + { + /* Check the status of the specified CAN flag */ + if ((CANx->RF0R & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET) + { + /* CAN_FLAG is set */ + bitstatus = SET; + } + else + { + /* CAN_FLAG is reset */ + bitstatus = RESET; + } + } + else /* If(CAN_FLAG & CAN_FLAGS_RF1R != (uint32_t)RESET) */ + { + /* Check the status of the specified CAN flag */ + if ((uint32_t)(CANx->RF1R & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET) + { + /* CAN_FLAG is set */ + bitstatus = SET; + } + else + { + /* CAN_FLAG is reset */ + bitstatus = RESET; + } + } + /* Return the CAN_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the CAN's pending flags. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param CAN_FLAG: specifies the flag to clear. + * This parameter can be one of the following values: + * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag + * @arg CAN_FLAG_RQCP1: Request MailBox1 Flag + * @arg CAN_FLAG_RQCP2: Request MailBox2 Flag + * @arg CAN_FLAG_FF0: FIFO 0 Full Flag + * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag + * @arg CAN_FLAG_FF1: FIFO 1 Full Flag + * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag + * @arg CAN_FLAG_WKU: Wake up Flag + * @arg CAN_FLAG_SLAK: Sleep acknowledge Flag + * @arg CAN_FLAG_LEC: Last error code Flag + * @retval None + */ +void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG) +{ + uint32_t flagtmp=0; + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_CLEAR_FLAG(CAN_FLAG)); + + if (CAN_FLAG == CAN_FLAG_LEC) /* ESR register */ + { + /* Clear the selected CAN flags */ + CANx->ESR = (uint32_t)RESET; + } + else /* MSR or TSR or RF0R or RF1R */ + { + flagtmp = CAN_FLAG & 0x000FFFFF; + + if ((CAN_FLAG & CAN_FLAGS_RF0R)!=(uint32_t)RESET) + { + /* Receive Flags */ + CANx->RF0R = (uint32_t)(flagtmp); + } + else if ((CAN_FLAG & CAN_FLAGS_RF1R)!=(uint32_t)RESET) + { + /* Receive Flags */ + CANx->RF1R = (uint32_t)(flagtmp); + } + else if ((CAN_FLAG & CAN_FLAGS_TSR)!=(uint32_t)RESET) + { + /* Transmit Flags */ + CANx->TSR = (uint32_t)(flagtmp); + } + else /* If((CAN_FLAG & CAN_FLAGS_MSR)!=(uint32_t)RESET) */ + { + /* Operating mode Flags */ + CANx->MSR = (uint32_t)(flagtmp); + } + } +} + +/** + * @brief Checks whether the specified CANx interrupt has occurred or not. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param CAN_IT: specifies the CAN interrupt source to check. + * This parameter can be one of the following values: + * @arg CAN_IT_TME: Transmit mailbox empty Interrupt + * @arg CAN_IT_FMP0: FIFO 0 message pending Interrupt + * @arg CAN_IT_FF0: FIFO 0 full Interrupt + * @arg CAN_IT_FOV0: FIFO 0 overrun Interrupt + * @arg CAN_IT_FMP1: FIFO 1 message pending Interrupt + * @arg CAN_IT_FF1: FIFO 1 full Interrupt + * @arg CAN_IT_FOV1: FIFO 1 overrun Interrupt + * @arg CAN_IT_WKU: Wake-up Interrupt + * @arg CAN_IT_SLK: Sleep acknowledge Interrupt + * @arg CAN_IT_EWG: Error warning Interrupt + * @arg CAN_IT_EPV: Error passive Interrupt + * @arg CAN_IT_BOF: Bus-off Interrupt + * @arg CAN_IT_LEC: Last error code Interrupt + * @arg CAN_IT_ERR: Error Interrupt + * @retval The current state of CAN_IT (SET or RESET). + */ +ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT) +{ + ITStatus itstatus = RESET; + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_IT(CAN_IT)); + + /* check the interrupt enable bit */ + if((CANx->IER & CAN_IT) != RESET) + { + /* in case the Interrupt is enabled, .... */ + switch (CAN_IT) + { + case CAN_IT_TME: + /* Check CAN_TSR_RQCPx bits */ + itstatus = CheckITStatus(CANx->TSR, CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2); + break; + case CAN_IT_FMP0: + /* Check CAN_RF0R_FMP0 bit */ + itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FMP0); + break; + case CAN_IT_FF0: + /* Check CAN_RF0R_FULL0 bit */ + itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FULL0); + break; + case CAN_IT_FOV0: + /* Check CAN_RF0R_FOVR0 bit */ + itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FOVR0); + break; + case CAN_IT_FMP1: + /* Check CAN_RF1R_FMP1 bit */ + itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FMP1); + break; + case CAN_IT_FF1: + /* Check CAN_RF1R_FULL1 bit */ + itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FULL1); + break; + case CAN_IT_FOV1: + /* Check CAN_RF1R_FOVR1 bit */ + itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FOVR1); + break; + case CAN_IT_WKU: + /* Check CAN_MSR_WKUI bit */ + itstatus = CheckITStatus(CANx->MSR, CAN_MSR_WKUI); + break; + case CAN_IT_SLK: + /* Check CAN_MSR_SLAKI bit */ + itstatus = CheckITStatus(CANx->MSR, CAN_MSR_SLAKI); + break; + case CAN_IT_EWG: + /* Check CAN_ESR_EWGF bit */ + itstatus = CheckITStatus(CANx->ESR, CAN_ESR_EWGF); + break; + case CAN_IT_EPV: + /* Check CAN_ESR_EPVF bit */ + itstatus = CheckITStatus(CANx->ESR, CAN_ESR_EPVF); + break; + case CAN_IT_BOF: + /* Check CAN_ESR_BOFF bit */ + itstatus = CheckITStatus(CANx->ESR, CAN_ESR_BOFF); + break; + case CAN_IT_LEC: + /* Check CAN_ESR_LEC bit */ + itstatus = CheckITStatus(CANx->ESR, CAN_ESR_LEC); + break; + case CAN_IT_ERR: + /* Check CAN_MSR_ERRI bit */ + itstatus = CheckITStatus(CANx->MSR, CAN_MSR_ERRI); + break; + default: + /* in case of error, return RESET */ + itstatus = RESET; + break; + } + } + else + { + /* in case the Interrupt is not enabled, return RESET */ + itstatus = RESET; + } + + /* Return the CAN_IT status */ + return itstatus; +} + +/** + * @brief Clears the CANx's interrupt pending bits. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param CAN_IT: specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg CAN_IT_TME: Transmit mailbox empty Interrupt + * @arg CAN_IT_FF0: FIFO 0 full Interrupt + * @arg CAN_IT_FOV0: FIFO 0 overrun Interrupt + * @arg CAN_IT_FF1: FIFO 1 full Interrupt + * @arg CAN_IT_FOV1: FIFO 1 overrun Interrupt + * @arg CAN_IT_WKU: Wake-up Interrupt + * @arg CAN_IT_SLK: Sleep acknowledge Interrupt + * @arg CAN_IT_EWG: Error warning Interrupt + * @arg CAN_IT_EPV: Error passive Interrupt + * @arg CAN_IT_BOF: Bus-off Interrupt + * @arg CAN_IT_LEC: Last error code Interrupt + * @arg CAN_IT_ERR: Error Interrupt + * @retval None + */ +void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_CLEAR_IT(CAN_IT)); + + switch (CAN_IT) + { + case CAN_IT_TME: + /* Clear CAN_TSR_RQCPx (rc_w1)*/ + CANx->TSR = CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2; + break; + case CAN_IT_FF0: + /* Clear CAN_RF0R_FULL0 (rc_w1)*/ + CANx->RF0R = CAN_RF0R_FULL0; + break; + case CAN_IT_FOV0: + /* Clear CAN_RF0R_FOVR0 (rc_w1)*/ + CANx->RF0R = CAN_RF0R_FOVR0; + break; + case CAN_IT_FF1: + /* Clear CAN_RF1R_FULL1 (rc_w1)*/ + CANx->RF1R = CAN_RF1R_FULL1; + break; + case CAN_IT_FOV1: + /* Clear CAN_RF1R_FOVR1 (rc_w1)*/ + CANx->RF1R = CAN_RF1R_FOVR1; + break; + case CAN_IT_WKU: + /* Clear CAN_MSR_WKUI (rc_w1)*/ + CANx->MSR = CAN_MSR_WKUI; + break; + case CAN_IT_SLK: + /* Clear CAN_MSR_SLAKI (rc_w1)*/ + CANx->MSR = CAN_MSR_SLAKI; + break; + case CAN_IT_EWG: + /* Clear CAN_MSR_ERRI (rc_w1) */ + CANx->MSR = CAN_MSR_ERRI; + /* @note the corresponding Flag is cleared by hardware depending on the CAN Bus status*/ + break; + case CAN_IT_EPV: + /* Clear CAN_MSR_ERRI (rc_w1) */ + CANx->MSR = CAN_MSR_ERRI; + /* @note the corresponding Flag is cleared by hardware depending on the CAN Bus status*/ + break; + case CAN_IT_BOF: + /* Clear CAN_MSR_ERRI (rc_w1) */ + CANx->MSR = CAN_MSR_ERRI; + /* @note the corresponding Flag is cleared by hardware depending on the CAN Bus status*/ + break; + case CAN_IT_LEC: + /* Clear LEC bits */ + CANx->ESR = RESET; + /* Clear CAN_MSR_ERRI (rc_w1) */ + CANx->MSR = CAN_MSR_ERRI; + break; + case CAN_IT_ERR: + /*Clear LEC bits */ + CANx->ESR = RESET; + /* Clear CAN_MSR_ERRI (rc_w1) */ + CANx->MSR = CAN_MSR_ERRI; + /* @note BOFF, EPVF and EWGF Flags are cleared by hardware depending on the CAN Bus status*/ + break; + default: + break; + } +} + /** + * @} + */ + +/** + * @brief Checks whether the CAN interrupt has occurred or not. + * @param CAN_Reg: specifies the CAN interrupt register to check. + * @param It_Bit: specifies the interrupt source bit to check. + * @retval The new state of the CAN Interrupt (SET or RESET). + */ +static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit) +{ + ITStatus pendingbitstatus = RESET; + + if ((CAN_Reg & It_Bit) != (uint32_t)RESET) + { + /* CAN_IT is set */ + pendingbitstatus = SET; + } + else + { + /* CAN_IT is reset */ + pendingbitstatus = RESET; + } + return pendingbitstatus; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_crc.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_crc.c new file mode 100644 index 0000000..c2c6bbb --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_crc.c @@ -0,0 +1,127 @@ +/** + ****************************************************************************** + * @file stm32f4xx_crc.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides all the CRC firmware functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_crc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup CRC + * @brief CRC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup CRC_Private_Functions + * @{ + */ + +/** + * @brief Resets the CRC Data register (DR). + * @param None + * @retval None + */ +void CRC_ResetDR(void) +{ + /* Reset CRC generator */ + CRC->CR = CRC_CR_RESET; +} + +/** + * @brief Computes the 32-bit CRC of a given data word(32-bit). + * @param Data: data word(32-bit) to compute its CRC + * @retval 32-bit CRC + */ +uint32_t CRC_CalcCRC(uint32_t Data) +{ + CRC->DR = Data; + + return (CRC->DR); +} + +/** + * @brief Computes the 32-bit CRC of a given buffer of data word(32-bit). + * @param pBuffer: pointer to the buffer containing the data to be computed + * @param BufferLength: length of the buffer to be computed + * @retval 32-bit CRC + */ +uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength) +{ + uint32_t index = 0; + + for(index = 0; index < BufferLength; index++) + { + CRC->DR = pBuffer[index]; + } + return (CRC->DR); +} + +/** + * @brief Returns the current CRC value. + * @param None + * @retval 32-bit CRC + */ +uint32_t CRC_GetCRC(void) +{ + return (CRC->DR); +} + +/** + * @brief Stores a 8-bit data in the Independent Data(ID) register. + * @param IDValue: 8-bit value to be stored in the ID register + * @retval None + */ +void CRC_SetIDRegister(uint8_t IDValue) +{ + CRC->IDR = IDValue; +} + +/** + * @brief Returns the 8-bit data stored in the Independent Data(ID) register + * @param None + * @retval 8-bit value of the ID register + */ +uint8_t CRC_GetIDRegister(void) +{ + return (CRC->IDR); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp.c new file mode 100644 index 0000000..dcdbef8 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp.c @@ -0,0 +1,850 @@ +/** + ****************************************************************************** + * @file stm32f4xx_cryp.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Cryptographic processor (CRYP) peripheral: + * - Initialization and Configuration functions + * - Data treatment functions + * - Context swapping functions + * - DMA interface function + * - Interrupts and flags management + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + * 1. Enable the CRYP controller clock using + * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); function. + * + * 2. Initialise the CRYP using CRYP_Init(), CRYP_KeyInit() and if + * needed CRYP_IVInit(). + * + * 3. Flush the IN and OUT FIFOs by using CRYP_FIFOFlush() function. + * + * 4. Enable the CRYP controller using the CRYP_Cmd() function. + * + * 5. If using DMA for Data input and output transfer, + * Activate the needed DMA Requests using CRYP_DMACmd() function + + * 6. If DMA is not used for data transfer, use CRYP_DataIn() and + * CRYP_DataOut() functions to enter data to IN FIFO and get result + * from OUT FIFO. + * + * 7. To control CRYP events you can use one of the following + * two methods: + * - Check on CRYP flags using the CRYP_GetFlagStatus() function. + * - Use CRYP interrupts through the function CRYP_ITConfig() at + * initialization phase and CRYP_GetITStatus() function into + * interrupt routines in processing phase. + * + * 8. Save and restore Cryptographic processor context using + * CRYP_SaveContext() and CRYP_RestoreContext() functions. + * + * + * =================================================================== + * Procedure to perform an encryption or a decryption + * =================================================================== + * + * Initialization + * =============== + * 1. Initialize the peripheral using CRYP_Init(), CRYP_KeyInit() and + * CRYP_IVInit functions: + * - Configure the key size (128-, 192- or 256-bit, in the AES only) + * - Enter the symmetric key + * - Configure the data type + * - In case of decryption in AES-ECB or AES-CBC, you must prepare + * the key: configure the key preparation mode. Then Enable the CRYP + * peripheral using CRYP_Cmd() function: the BUSY flag is set. + * Wait until BUSY flag is reset : the key is prepared for decryption + * - Configure the algorithm and chaining (the DES/TDES in ECB/CBC, the + * AES in ECB/CBC/CTR) + * - Configure the direction (encryption/decryption). + * - Write the initialization vectors (in CBC or CTR modes only) + * + * 2. Flush the IN and OUT FIFOs using the CRYP_FIFOFlush() function + * + * + * Basic Processing mode (polling mode) + * ==================================== + * 1. Enable the cryptographic processor using CRYP_Cmd() function. + * + * 2. Write the first blocks in the input FIFO (2 to 8 words) using + * CRYP_DataIn() function. + * + * 3. Repeat the following sequence until the complete message has been + * processed: + * + * a) Wait for flag CRYP_FLAG_OFNE occurs (using CRYP_GetFlagStatus() + * function), then read the OUT-FIFO using CRYP_DataOut() function + * (1 block or until the FIFO is empty) + * + * b) Wait for flag CRYP_FLAG_IFNF occurs, (using CRYP_GetFlagStatus() + * function then write the IN FIFO using CRYP_DataIn() function + * (1 block or until the FIFO is full) + * + * 4. At the end of the processing, CRYP_FLAG_BUSY flag will be reset and + * both FIFOs are empty (CRYP_FLAG_IFEM is set and CRYP_FLAG_OFNE is + * reset). You can disable the peripheral using CRYP_Cmd() function. + * + * Interrupts Processing mode + * =========================== + * In this mode, Processing is done when the data are transferred by the + * CPU during interrupts. + * + * 1. Enable the interrupts CRYP_IT_INI and CRYP_IT_OUTI using + * CRYP_ITConfig() function. + * + * 2. Enable the cryptographic processor using CRYP_Cmd() function. + * + * 3. In the CRYP_IT_INI interrupt handler : load the input message into the + * IN FIFO using CRYP_DataIn() function . You can load 2 or 4 words at a + * time, or load data until the IN FIFO is full. When the last word of + * the message has been entered into the IN FIFO, disable the CRYP_IT_INI + * interrupt (using CRYP_ITConfig() function). + * + * 4. In the CRYP_IT_OUTI interrupt handler : read the output message from + * the OUT FIFO using CRYP_DataOut() function. You can read 1 block (2 or + * 4 words) at a time or read data until the FIFO is empty. + * When the last word has been read, INIM=0, BUSY=0 and both FIFOs are + * empty (CRYP_FLAG_IFEM is set and CRYP_FLAG_OFNE is reset). + * You can disable the CRYP_IT_OUTI interrupt (using CRYP_ITConfig() + * function) and you can disable the peripheral using CRYP_Cmd() function. + * + * DMA Processing mode + * ==================== + * In this mode, Processing is done when the DMA is used to transfer the + * data from/to the memory. + * + * 1. Configure the DMA controller to transfer the input data from the + * memory using DMA_Init() function. + * The transfer length is the length of the message. + * As message padding is not managed by the peripheral, the message + * length must be an entire number of blocks. The data are transferred + * in burst mode. The burst length is 4 words in the AES and 2 or 4 + * words in the DES/TDES. The DMA should be configured to set an + * interrupt on transfer completion of the output data to indicate that + * the processing is finished. + * Refer to DMA peripheral driver for more details. + * + * 2. Enable the cryptographic processor using CRYP_Cmd() function. + * Enable the DMA requests CRYP_DMAReq_DataIN and CRYP_DMAReq_DataOUT + * using CRYP_DMACmd() function. + * + * 3. All the transfers and processing are managed by the DMA and the + * cryptographic processor. The DMA transfer complete interrupt indicates + * that the processing is complete. Both FIFOs are normally empty and + * CRYP_FLAG_BUSY flag is reset. + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_cryp.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup CRYP + * @brief CRYP driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define FLAG_MASK ((uint8_t)0x20) +#define MAX_TIMEOUT ((uint16_t)0xFFFF) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup CRYP_Private_Functions + * @{ + */ + +/** @defgroup CRYP_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + This section provides functions allowing to + - Initialize the cryptographic Processor using CRYP_Init() function + - Encrypt or Decrypt + - mode : TDES-ECB, TDES-CBC, + DES-ECB, DES-CBC, + AES-ECB, AES-CBC, AES-CTR, AES-Key + - DataType : 32-bit data, 16-bit data, bit data or bit-string + - Key Size (only in AES modes) + - Configure the Encrypt or Decrypt Key using CRYP_KeyInit() function + - Configure the Initialization Vectors(IV) for CBC and CTR modes using + CRYP_IVInit() function. + - Flushes the IN and OUT FIFOs : using CRYP_FIFOFlush() function. + - Enable or disable the CRYP Processor using CRYP_Cmd() function + + +@endverbatim + * @{ + */ +/** + * @brief Deinitializes the CRYP peripheral registers to their default reset values + * @param None + * @retval None + */ +void CRYP_DeInit(void) +{ + /* Enable CRYP reset state */ + RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_CRYP, ENABLE); + + /* Release CRYP from reset state */ + RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_CRYP, DISABLE); +} + +/** + * @brief Initializes the CRYP peripheral according to the specified parameters + * in the CRYP_InitStruct. + * @param CRYP_InitStruct: pointer to a CRYP_InitTypeDef structure that contains + * the configuration information for the CRYP peripheral. + * @retval None + */ +void CRYP_Init(CRYP_InitTypeDef* CRYP_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_CRYP_ALGOMODE(CRYP_InitStruct->CRYP_AlgoMode)); + assert_param(IS_CRYP_DATATYPE(CRYP_InitStruct->CRYP_DataType)); + assert_param(IS_CRYP_ALGODIR(CRYP_InitStruct->CRYP_AlgoDir)); + + /* Select Algorithm mode*/ + CRYP->CR &= ~CRYP_CR_ALGOMODE; + CRYP->CR |= CRYP_InitStruct->CRYP_AlgoMode; + + /* Select dataType */ + CRYP->CR &= ~CRYP_CR_DATATYPE; + CRYP->CR |= CRYP_InitStruct->CRYP_DataType; + + /* select Key size (used only with AES algorithm) */ + if ((CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_ECB) || + (CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_CBC) || + (CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_CTR) || + (CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_Key)) + { + assert_param(IS_CRYP_KEYSIZE(CRYP_InitStruct->CRYP_KeySize)); + CRYP->CR &= ~CRYP_CR_KEYSIZE; + CRYP->CR |= CRYP_InitStruct->CRYP_KeySize; /* Key size and value must be + configured once the key has + been prepared */ + } + + /* Select data Direction */ + CRYP->CR &= ~CRYP_CR_ALGODIR; + CRYP->CR |= CRYP_InitStruct->CRYP_AlgoDir; +} + +/** + * @brief Fills each CRYP_InitStruct member with its default value. + * @param CRYP_InitStruct: pointer to a CRYP_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void CRYP_StructInit(CRYP_InitTypeDef* CRYP_InitStruct) +{ + /* Initialize the CRYP_AlgoDir member */ + CRYP_InitStruct->CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; + + /* initialize the CRYP_AlgoMode member */ + CRYP_InitStruct->CRYP_AlgoMode = CRYP_AlgoMode_TDES_ECB; + + /* initialize the CRYP_DataType member */ + CRYP_InitStruct->CRYP_DataType = CRYP_DataType_32b; + + /* Initialize the CRYP_KeySize member */ + CRYP_InitStruct->CRYP_KeySize = CRYP_KeySize_128b; +} + +/** + * @brief Initializes the CRYP Keys according to the specified parameters in + * the CRYP_KeyInitStruct. + * @param CRYP_KeyInitStruct: pointer to a CRYP_KeyInitTypeDef structure that + * contains the configuration information for the CRYP Keys. + * @retval None + */ +void CRYP_KeyInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct) +{ + /* Key Initialisation */ + CRYP->K0LR = CRYP_KeyInitStruct->CRYP_Key0Left; + CRYP->K0RR = CRYP_KeyInitStruct->CRYP_Key0Right; + CRYP->K1LR = CRYP_KeyInitStruct->CRYP_Key1Left; + CRYP->K1RR = CRYP_KeyInitStruct->CRYP_Key1Right; + CRYP->K2LR = CRYP_KeyInitStruct->CRYP_Key2Left; + CRYP->K2RR = CRYP_KeyInitStruct->CRYP_Key2Right; + CRYP->K3LR = CRYP_KeyInitStruct->CRYP_Key3Left; + CRYP->K3RR = CRYP_KeyInitStruct->CRYP_Key3Right; +} + +/** + * @brief Fills each CRYP_KeyInitStruct member with its default value. + * @param CRYP_KeyInitStruct: pointer to a CRYP_KeyInitTypeDef structure + * which will be initialized. + * @retval None + */ +void CRYP_KeyStructInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct) +{ + CRYP_KeyInitStruct->CRYP_Key0Left = 0; + CRYP_KeyInitStruct->CRYP_Key0Right = 0; + CRYP_KeyInitStruct->CRYP_Key1Left = 0; + CRYP_KeyInitStruct->CRYP_Key1Right = 0; + CRYP_KeyInitStruct->CRYP_Key2Left = 0; + CRYP_KeyInitStruct->CRYP_Key2Right = 0; + CRYP_KeyInitStruct->CRYP_Key3Left = 0; + CRYP_KeyInitStruct->CRYP_Key3Right = 0; +} +/** + * @brief Initializes the CRYP Initialization Vectors(IV) according to the + * specified parameters in the CRYP_IVInitStruct. + * @param CRYP_IVInitStruct: pointer to a CRYP_IVInitTypeDef structure that contains + * the configuration information for the CRYP Initialization Vectors(IV). + * @retval None + */ +void CRYP_IVInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct) +{ + CRYP->IV0LR = CRYP_IVInitStruct->CRYP_IV0Left; + CRYP->IV0RR = CRYP_IVInitStruct->CRYP_IV0Right; + CRYP->IV1LR = CRYP_IVInitStruct->CRYP_IV1Left; + CRYP->IV1RR = CRYP_IVInitStruct->CRYP_IV1Right; +} + +/** + * @brief Fills each CRYP_IVInitStruct member with its default value. + * @param CRYP_IVInitStruct: pointer to a CRYP_IVInitTypeDef Initialization + * Vectors(IV) structure which will be initialized. + * @retval None + */ +void CRYP_IVStructInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct) +{ + CRYP_IVInitStruct->CRYP_IV0Left = 0; + CRYP_IVInitStruct->CRYP_IV0Right = 0; + CRYP_IVInitStruct->CRYP_IV1Left = 0; + CRYP_IVInitStruct->CRYP_IV1Right = 0; +} + +/** + * @brief Flushes the IN and OUT FIFOs (that is read and write pointers of the + * FIFOs are reset) + * @note The FIFOs must be flushed only when BUSY flag is reset. + * @param None + * @retval None + */ +void CRYP_FIFOFlush(void) +{ + /* Reset the read and write pointers of the FIFOs */ + CRYP->CR |= CRYP_CR_FFLUSH; +} + +/** + * @brief Enables or disables the CRYP peripheral. + * @param NewState: new state of the CRYP peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CRYP_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Cryptographic processor */ + CRYP->CR |= CRYP_CR_CRYPEN; + } + else + { + /* Disable the Cryptographic processor */ + CRYP->CR &= ~CRYP_CR_CRYPEN; + } +} +/** + * @} + */ + +/** @defgroup CRYP_Group2 CRYP Data processing functions + * @brief CRYP Data processing functions + * +@verbatim + =============================================================================== + CRYP Data processing functions + =============================================================================== + This section provides functions allowing the encryption and decryption + operations: + - Enter data to be treated in the IN FIFO : using CRYP_DataIn() function. + - Get the data result from the OUT FIFO : using CRYP_DataOut() function. + +@endverbatim + * @{ + */ + +/** + * @brief Writes data in the Data Input register (DIN). + * @note After the DIN register has been read once or several times, + * the FIFO must be flushed (using CRYP_FIFOFlush() function). + * @param Data: data to write in Data Input register + * @retval None + */ +void CRYP_DataIn(uint32_t Data) +{ + CRYP->DR = Data; +} + +/** + * @brief Returns the last data entered into the output FIFO. + * @param None + * @retval Last data entered into the output FIFO. + */ +uint32_t CRYP_DataOut(void) +{ + return CRYP->DOUT; +} +/** + * @} + */ + +/** @defgroup CRYP_Group3 Context swapping functions + * @brief Context swapping functions + * +@verbatim + =============================================================================== + Context swapping functions + =============================================================================== + + This section provides functions allowing to save and store CRYP Context + + It is possible to interrupt an encryption/ decryption/ key generation process + to perform another processing with a higher priority, and to complete the + interrupted process later on, when the higher-priority task is complete. To do + so, the context of the interrupted task must be saved from the CRYP registers + to memory, and then be restored from memory to the CRYP registers. + + 1. To save the current context, use CRYP_SaveContext() function + 2. To restore the saved context, use CRYP_RestoreContext() function + + +@endverbatim + * @{ + */ + +/** + * @brief Saves the CRYP peripheral Context. + * @note This function stops DMA transfer before to save the context. After + * restoring the context, you have to enable the DMA again (if the DMA + * was previously used). + * @param CRYP_ContextSave: pointer to a CRYP_Context structure that contains + * the repository for current context. + * @param CRYP_KeyInitStruct: pointer to a CRYP_KeyInitTypeDef structure that + * contains the configuration information for the CRYP Keys. + * @retval None + */ +ErrorStatus CRYP_SaveContext(CRYP_Context* CRYP_ContextSave, + CRYP_KeyInitTypeDef* CRYP_KeyInitStruct) +{ + __IO uint32_t timeout = 0; + uint32_t ckeckmask = 0, bitstatus; + ErrorStatus status = ERROR; + + /* Stop DMA transfers on the IN FIFO by clearing the DIEN bit in the CRYP_DMACR */ + CRYP->DMACR &= ~(uint32_t)CRYP_DMACR_DIEN; + + /* Wait until both the IN and OUT FIFOs are empty + (IFEM=1 and OFNE=0 in the CRYP_SR register) and the + BUSY bit is cleared. */ + + if ((CRYP->CR & (uint32_t)(CRYP_CR_ALGOMODE_TDES_ECB | CRYP_CR_ALGOMODE_TDES_CBC)) != (uint32_t)0 )/* TDES */ + { + ckeckmask = CRYP_SR_IFEM | CRYP_SR_BUSY ; + } + else /* AES or DES */ + { + ckeckmask = CRYP_SR_IFEM | CRYP_SR_BUSY | CRYP_SR_OFNE; + } + + do + { + bitstatus = CRYP->SR & ckeckmask; + timeout++; + } + while ((timeout != MAX_TIMEOUT) && (bitstatus != CRYP_SR_IFEM)); + + if ((CRYP->SR & ckeckmask) != CRYP_SR_IFEM) + { + status = ERROR; + } + else + { + /* Stop DMA transfers on the OUT FIFO by + - writing the DOEN bit to 0 in the CRYP_DMACR register + - and clear the CRYPEN bit. */ + + CRYP->DMACR &= ~(uint32_t)CRYP_DMACR_DOEN; + CRYP->CR &= ~(uint32_t)CRYP_CR_CRYPEN; + + /* Save the current configuration (bits [9:2] in the CRYP_CR register) */ + CRYP_ContextSave->CR_bits9to2 = CRYP->CR & (CRYP_CR_KEYSIZE | + CRYP_CR_DATATYPE | + CRYP_CR_ALGOMODE | + CRYP_CR_ALGODIR); + + /* and, if not in ECB mode, the initialization vectors. */ + CRYP_ContextSave->CRYP_IV0LR = CRYP->IV0LR; + CRYP_ContextSave->CRYP_IV0RR = CRYP->IV0RR; + CRYP_ContextSave->CRYP_IV1LR = CRYP->IV1LR; + CRYP_ContextSave->CRYP_IV1RR = CRYP->IV1RR; + + /* save The key value */ + CRYP_ContextSave->CRYP_K0LR = CRYP_KeyInitStruct->CRYP_Key0Left; + CRYP_ContextSave->CRYP_K0RR = CRYP_KeyInitStruct->CRYP_Key0Right; + CRYP_ContextSave->CRYP_K1LR = CRYP_KeyInitStruct->CRYP_Key1Left; + CRYP_ContextSave->CRYP_K1RR = CRYP_KeyInitStruct->CRYP_Key1Right; + CRYP_ContextSave->CRYP_K2LR = CRYP_KeyInitStruct->CRYP_Key2Left; + CRYP_ContextSave->CRYP_K2RR = CRYP_KeyInitStruct->CRYP_Key2Right; + CRYP_ContextSave->CRYP_K3LR = CRYP_KeyInitStruct->CRYP_Key3Left; + CRYP_ContextSave->CRYP_K3RR = CRYP_KeyInitStruct->CRYP_Key3Right; + + /* When needed, save the DMA status (pointers for IN and OUT messages, + number of remaining bytes, etc.) */ + + status = SUCCESS; + } + + return status; +} + +/** + * @brief Restores the CRYP peripheral Context. + * @note Since teh DMA transfer is stopped in CRYP_SaveContext() function, + * after restoring the context, you have to enable the DMA again (if the + * DMA was previously used). + * @param CRYP_ContextRestore: pointer to a CRYP_Context structure that contains + * the repository for saved context. + * @note The data that were saved during context saving must be rewrited into + * the IN FIFO. + * @retval None + */ +void CRYP_RestoreContext(CRYP_Context* CRYP_ContextRestore) +{ + + /* Configure the processor with the saved configuration */ + CRYP->CR = CRYP_ContextRestore->CR_bits9to2; + + /* restore The key value */ + CRYP->K0LR = CRYP_ContextRestore->CRYP_K0LR; + CRYP->K0RR = CRYP_ContextRestore->CRYP_K0RR; + CRYP->K1LR = CRYP_ContextRestore->CRYP_K1LR; + CRYP->K1RR = CRYP_ContextRestore->CRYP_K1RR; + CRYP->K2LR = CRYP_ContextRestore->CRYP_K2LR; + CRYP->K2RR = CRYP_ContextRestore->CRYP_K2RR; + CRYP->K3LR = CRYP_ContextRestore->CRYP_K3LR; + CRYP->K3RR = CRYP_ContextRestore->CRYP_K3RR; + + /* and the initialization vectors. */ + CRYP->IV0LR = CRYP_ContextRestore->CRYP_IV0LR; + CRYP->IV0RR = CRYP_ContextRestore->CRYP_IV0RR; + CRYP->IV1LR = CRYP_ContextRestore->CRYP_IV1LR; + CRYP->IV1RR = CRYP_ContextRestore->CRYP_IV1RR; + + /* Enable the cryptographic processor */ + CRYP->CR |= CRYP_CR_CRYPEN; +} +/** + * @} + */ + +/** @defgroup CRYP_Group4 CRYP's DMA interface Configuration function + * @brief CRYP's DMA interface Configuration function + * +@verbatim + =============================================================================== + CRYP's DMA interface Configuration function + =============================================================================== + + This section provides functions allowing to configure the DMA interface for + CRYP data input and output transfer. + + When the DMA mode is enabled (using the CRYP_DMACmd() function), data can be + transferred: + - From memory to the CRYP IN FIFO using the DMA peripheral by enabling + the CRYP_DMAReq_DataIN request. + - From the CRYP OUT FIFO to the memory using the DMA peripheral by enabling + the CRYP_DMAReq_DataOUT request. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the CRYP DMA interface. + * @param CRYP_DMAReq: specifies the CRYP DMA transfer request to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg CRYP_DMAReq_DataOUT: DMA for outgoing(Tx) data transfer + * @arg CRYP_DMAReq_DataIN: DMA for incoming(Rx) data transfer + * @param NewState: new state of the selected CRYP DMA transfer request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CRYP_DMACmd(uint8_t CRYP_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CRYP_DMAREQ(CRYP_DMAReq)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected CRYP DMA request */ + CRYP->DMACR |= CRYP_DMAReq; + } + else + { + /* Disable the selected CRYP DMA request */ + CRYP->DMACR &= (uint8_t)~CRYP_DMAReq; + } +} +/** + * @} + */ + +/** @defgroup CRYP_Group5 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + + This section provides functions allowing to configure the CRYP Interrupts and + to get the status and Interrupts pending bits. + + The CRYP provides 2 Interrupts sources and 7 Flags: + + Flags : + ------- + + 1. CRYP_FLAG_IFEM : Set when Input FIFO is empty. + This Flag is cleared only by hardware. + + 2. CRYP_FLAG_IFNF : Set when Input FIFO is not full. + This Flag is cleared only by hardware. + + + 3. CRYP_FLAG_INRIS : Set when Input FIFO Raw interrupt is pending + it gives the raw interrupt state prior to masking + of the input FIFO service interrupt. + This Flag is cleared only by hardware. + + 4. CRYP_FLAG_OFNE : Set when Output FIFO not empty. + This Flag is cleared only by hardware. + + 5. CRYP_FLAG_OFFU : Set when Output FIFO is full. + This Flag is cleared only by hardware. + + 6. CRYP_FLAG_OUTRIS : Set when Output FIFO Raw interrupt is pending + it gives the raw interrupt state prior to masking + of the output FIFO service interrupt. + This Flag is cleared only by hardware. + + 7. CRYP_FLAG_BUSY : Set when the CRYP core is currently processing a + block of data or a key preparation (for AES + decryption). + This Flag is cleared only by hardware. + To clear it, the CRYP core must be disabled and the + last processing has completed. + + Interrupts : + ------------ + + 1. CRYP_IT_INI : The input FIFO service interrupt is asserted when there + are less than 4 words in the input FIFO. + This interrupt is associated to CRYP_FLAG_INRIS flag. + + @note This interrupt is cleared by performing write operations + to the input FIFO until it holds 4 or more words. The + input FIFO service interrupt INMIS is enabled with the + CRYP enable bit. Consequently, when CRYP is disabled, the + INMIS signal is low even if the input FIFO is empty. + + + + 2. CRYP_IT_OUTI : The output FIFO service interrupt is asserted when there + is one or more (32-bit word) data items in the output FIFO. + This interrupt is associated to CRYP_FLAG_OUTRIS flag. + + @note This interrupt is cleared by reading data from the output + FIFO until there is no valid (32-bit) word left (that is, + the interrupt follows the state of the OFNE (output FIFO + not empty) flag). + + + Managing the CRYP controller events : + ------------------------------------ + The user should identify which mode will be used in his application to manage + the CRYP controller events: Polling mode or Interrupt mode. + + 1. In the Polling Mode it is advised to use the following functions: + - CRYP_GetFlagStatus() : to check if flags events occur. + + @note The CRYPT flags do not need to be cleared since they are cleared as + soon as the associated event are reset. + + + 2. In the Interrupt Mode it is advised to use the following functions: + - CRYP_ITConfig() : to enable or disable the interrupt source. + - CRYP_GetITStatus() : to check if Interrupt occurs. + + @note The CRYPT interrupts have no pending bits, the interrupt is cleared as + soon as the associated event is reset. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified CRYP interrupts. + * @param CRYP_IT: specifies the CRYP interrupt source to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg CRYP_IT_INI: Input FIFO interrupt + * @arg CRYP_IT_OUTI: Output FIFO interrupt + * @param NewState: new state of the specified CRYP interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CRYP_ITConfig(uint8_t CRYP_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CRYP_CONFIG_IT(CRYP_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected CRYP interrupt */ + CRYP->IMSCR |= CRYP_IT; + } + else + { + /* Disable the selected CRYP interrupt */ + CRYP->IMSCR &= (uint8_t)~CRYP_IT; + } +} + +/** + * @brief Checks whether the specified CRYP interrupt has occurred or not. + * @note This function checks the status of the masked interrupt (i.e the + * interrupt should be previously enabled). + * @param CRYP_IT: specifies the CRYP (masked) interrupt source to check. + * This parameter can be one of the following values: + * @arg CRYP_IT_INI: Input FIFO interrupt + * @arg CRYP_IT_OUTI: Output FIFO interrupt + * @retval The new state of CRYP_IT (SET or RESET). + */ +ITStatus CRYP_GetITStatus(uint8_t CRYP_IT) +{ + ITStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_CRYP_GET_IT(CRYP_IT)); + + /* Check the status of the specified CRYP interrupt */ + if ((CRYP->MISR & CRYP_IT) != (uint8_t)RESET) + { + /* CRYP_IT is set */ + bitstatus = SET; + } + else + { + /* CRYP_IT is reset */ + bitstatus = RESET; + } + /* Return the CRYP_IT status */ + return bitstatus; +} + +/** + * @brief Checks whether the specified CRYP flag is set or not. + * @param CRYP_FLAG: specifies the CRYP flag to check. + * This parameter can be one of the following values: + * @arg CRYP_FLAG_IFEM: Input FIFO Empty flag. + * @arg CRYP_FLAG_IFNF: Input FIFO Not Full flag. + * @arg CRYP_FLAG_OFNE: Output FIFO Not Empty flag. + * @arg CRYP_FLAG_OFFU: Output FIFO Full flag. + * @arg CRYP_FLAG_BUSY: Busy flag. + * @arg CRYP_FLAG_OUTRIS: Output FIFO raw interrupt flag. + * @arg CRYP_FLAG_INRIS: Input FIFO raw interrupt flag. + * @retval The new state of CRYP_FLAG (SET or RESET). + */ +FlagStatus CRYP_GetFlagStatus(uint8_t CRYP_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t tempreg = 0; + + /* Check the parameters */ + assert_param(IS_CRYP_GET_FLAG(CRYP_FLAG)); + + /* check if the FLAG is in RISR register */ + if ((CRYP_FLAG & FLAG_MASK) != 0x00) + { + tempreg = CRYP->RISR; + } + else /* The FLAG is in SR register */ + { + tempreg = CRYP->SR; + } + + + /* Check the status of the specified CRYP flag */ + if ((tempreg & CRYP_FLAG ) != (uint8_t)RESET) + { + /* CRYP_FLAG is set */ + bitstatus = SET; + } + else + { + /* CRYP_FLAG is reset */ + bitstatus = RESET; + } + + /* Return the CRYP_FLAG status */ + return bitstatus; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_aes.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_aes.c new file mode 100644 index 0000000..2866809 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_aes.c @@ -0,0 +1,638 @@ +/** + ****************************************************************************** + * @file stm32f4xx_cryp_aes.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides high level functions to encrypt and decrypt an + * input message using AES in ECB/CBC/CTR modes. + * It uses the stm32f4xx_cryp.c/.h drivers to access the STM32F4xx CRYP + * peripheral. + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + * 1. Enable The CRYP controller clock using + * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); function. + * + * 2. Encrypt and decrypt using AES in ECB Mode using CRYP_AES_ECB() + * function. + * + * 3. Encrypt and decrypt using AES in CBC Mode using CRYP_AES_CBC() + * function. + * + * 4. Encrypt and decrypt using AES in CTR Mode using CRYP_AES_CTR() + * function. + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_cryp.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup CRYP + * @brief CRYP driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define AESBUSY_TIMEOUT ((uint32_t) 0x00010000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup CRYP_Private_Functions + * @{ + */ + +/** @defgroup CRYP_Group6 High Level AES functions + * @brief High Level AES functions + * +@verbatim + =============================================================================== + High Level AES functions + =============================================================================== + + +@endverbatim + * @{ + */ + +/** + * @brief Encrypt and decrypt using AES in ECB Mode + * @param Mode: encryption or decryption Mode. + * This parameter can be one of the following values: + * @arg MODE_ENCRYPT: Encryption + * @arg MODE_DECRYPT: Decryption + * @param Key: Key used for AES algorithm. + * @param Keysize: length of the Key, must be a 128, 192 or 256. + * @param Input: pointer to the Input buffer. + * @param Ilength: length of the Input buffer, must be a multiple of 16. + * @param Output: pointer to the returned buffer. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Operation done + * - ERROR: Operation failed + */ +ErrorStatus CRYP_AES_ECB(uint8_t Mode, uint8_t* Key, uint16_t Keysize, + uint8_t* Input, uint32_t Ilength, uint8_t* Output) +{ + CRYP_InitTypeDef AES_CRYP_InitStructure; + CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; + __IO uint32_t counter = 0; + uint32_t busystatus = 0; + ErrorStatus status = SUCCESS; + uint32_t keyaddr = (uint32_t)Key; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + uint32_t i = 0; + + /* Crypto structures initialisation*/ + CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); + + switch(Keysize) + { + case 128: + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr)); + break; + case 192: + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; + AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr)); + break; + case 256: + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; + AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr)); + break; + default: + break; + } + + /*------------------ AES Decryption ------------------*/ + if(Mode == MODE_DECRYPT) /* AES decryption */ + { + /* Flush IN/OUT FIFOs */ + CRYP_FIFOFlush(); + + /* Crypto Init for Key preparation for decryption process */ + AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; + AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key; + AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b; + CRYP_Init(&AES_CRYP_InitStructure); + + /* Key Initialisation */ + CRYP_KeyInit(&AES_CRYP_KeyInitStructure); + + /* Enable Crypto processor */ + CRYP_Cmd(ENABLE); + + /* wait until the Busy flag is RESET */ + do + { + busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY); + counter++; + }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET)); + + if (busystatus != RESET) + { + status = ERROR; + } + else + { + /* Crypto Init for decryption process */ + AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; + } + } + /*------------------ AES Encryption ------------------*/ + else /* AES encryption */ + { + + CRYP_KeyInit(&AES_CRYP_KeyInitStructure); + + /* Crypto Init for Encryption process */ + AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; + } + + AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB; + AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; + CRYP_Init(&AES_CRYP_InitStructure); + + /* Flush IN/OUT FIFOs */ + CRYP_FIFOFlush(); + + /* Enable Crypto processor */ + CRYP_Cmd(ENABLE); + + for(i=0; ((i
© COPYRIGHT 2011 STMicroelectronics
+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_cryp.h" + + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup CRYP + * @brief CRYP driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define DESBUSY_TIMEOUT ((uint32_t) 0x00010000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + + +/** @defgroup CRYP_Private_Functions + * @{ + */ + +/** @defgroup CRYP_Group8 High Level DES functions + * @brief High Level DES functions + * +@verbatim + =============================================================================== + High Level DES functions + =============================================================================== +@endverbatim + * @{ + */ + +/** + * @brief Encrypt and decrypt using DES in ECB Mode + * @param Mode: encryption or decryption Mode. + * This parameter can be one of the following values: + * @arg MODE_ENCRYPT: Encryption + * @arg MODE_DECRYPT: Decryption + * @param Key: Key used for DES algorithm. + * @param Ilength: length of the Input buffer, must be a multiple of 8. + * @param Input: pointer to the Input buffer. + * @param Output: pointer to the returned buffer. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Operation done + * - ERROR: Operation failed + */ +ErrorStatus CRYP_DES_ECB(uint8_t Mode, uint8_t Key[8], uint8_t *Input, + uint32_t Ilength, uint8_t *Output) +{ + CRYP_InitTypeDef DES_CRYP_InitStructure; + CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure; + __IO uint32_t counter = 0; + uint32_t busystatus = 0; + ErrorStatus status = SUCCESS; + uint32_t keyaddr = (uint32_t)Key; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + uint32_t i = 0; + + /* Crypto structures initialisation*/ + CRYP_KeyStructInit(&DES_CRYP_KeyInitStructure); + + /* Crypto Init for Encryption process */ + if( Mode == MODE_ENCRYPT ) /* DES encryption */ + { + DES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; + } + else/* if( Mode == MODE_DECRYPT )*/ /* DES decryption */ + { + DES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; + } + + DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_ECB; + DES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; + CRYP_Init(&DES_CRYP_InitStructure); + + /* Key Initialisation */ + DES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + DES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr)); + CRYP_KeyInit(& DES_CRYP_KeyInitStructure); + + /* Flush IN/OUT FIFO */ + CRYP_FIFOFlush(); + + /* Enable Crypto processor */ + CRYP_Cmd(ENABLE); + + for(i=0; ((i
© COPYRIGHT 2011 STMicroelectronics
+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_cryp.h" + + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup CRYP + * @brief CRYP driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define TDESBUSY_TIMEOUT ((uint32_t) 0x00010000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + + +/** @defgroup CRYP_Private_Functions + * @{ + */ + +/** @defgroup CRYP_Group7 High Level TDES functions + * @brief High Level TDES functions + * +@verbatim + =============================================================================== + High Level TDES functions + =============================================================================== + + +@endverbatim + * @{ + */ + +/** + * @brief Encrypt and decrypt using TDES in ECB Mode + * @param Mode: encryption or decryption Mode. + * This parameter can be one of the following values: + * @arg MODE_ENCRYPT: Encryption + * @arg MODE_DECRYPT: Decryption + * @param Key: Key used for TDES algorithm. + * @param Ilength: length of the Input buffer, must be a multiple of 8. + * @param Input: pointer to the Input buffer. + * @param Output: pointer to the returned buffer. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Operation done + * - ERROR: Operation failed + */ +ErrorStatus CRYP_TDES_ECB(uint8_t Mode, uint8_t Key[24], uint8_t *Input, + uint32_t Ilength, uint8_t *Output) +{ + CRYP_InitTypeDef TDES_CRYP_InitStructure; + CRYP_KeyInitTypeDef TDES_CRYP_KeyInitStructure; + __IO uint32_t counter = 0; + uint32_t busystatus = 0; + ErrorStatus status = SUCCESS; + uint32_t keyaddr = (uint32_t)Key; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + uint32_t i = 0; + + /* Crypto structures initialisation*/ + CRYP_KeyStructInit(&TDES_CRYP_KeyInitStructure); + + /* Crypto Init for Encryption process */ + if(Mode == MODE_ENCRYPT) /* TDES encryption */ + { + TDES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; + } + else /*if(Mode == MODE_DECRYPT)*/ /* TDES decryption */ + { + TDES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; + } + + TDES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_ECB; + TDES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; + CRYP_Init(&TDES_CRYP_InitStructure); + + /* Key Initialisation */ + TDES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + TDES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + TDES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + TDES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + TDES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + TDES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr)); + CRYP_KeyInit(& TDES_CRYP_KeyInitStructure); + + /* Flush IN/OUT FIFO */ + CRYP_FIFOFlush(); + + /* Enable Crypto processor */ + CRYP_Cmd(ENABLE); + + for(i=0; ((i
© COPYRIGHT 2011 STMicroelectronics
+ ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_dac.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup DAC + * @brief DAC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* CR register Mask */ +#define CR_CLEAR_MASK ((uint32_t)0x00000FFE) + +/* DAC Dual Channels SWTRIG masks */ +#define DUAL_SWTRIG_SET ((uint32_t)0x00000003) +#define DUAL_SWTRIG_RESET ((uint32_t)0xFFFFFFFC) + +/* DHR registers offsets */ +#define DHR12R1_OFFSET ((uint32_t)0x00000008) +#define DHR12R2_OFFSET ((uint32_t)0x00000014) +#define DHR12RD_OFFSET ((uint32_t)0x00000020) + +/* DOR register offset */ +#define DOR_OFFSET ((uint32_t)0x0000002C) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup DAC_Private_Functions + * @{ + */ + +/** @defgroup DAC_Group1 DAC channels configuration + * @brief DAC channels configuration: trigger, output buffer, data format + * +@verbatim + =============================================================================== + DAC channels configuration: trigger, output buffer, data format + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the DAC peripheral registers to their default reset values. + * @param None + * @retval None + */ +void DAC_DeInit(void) +{ + /* Enable DAC reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE); + /* Release DAC from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE); +} + +/** + * @brief Initializes the DAC peripheral according to the specified parameters + * in the DAC_InitStruct. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that contains + * the configuration information for the specified DAC channel. + * @retval None + */ +void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct) +{ + uint32_t tmpreg1 = 0, tmpreg2 = 0; + + /* Check the DAC parameters */ + assert_param(IS_DAC_TRIGGER(DAC_InitStruct->DAC_Trigger)); + assert_param(IS_DAC_GENERATE_WAVE(DAC_InitStruct->DAC_WaveGeneration)); + assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude)); + assert_param(IS_DAC_OUTPUT_BUFFER_STATE(DAC_InitStruct->DAC_OutputBuffer)); + +/*---------------------------- DAC CR Configuration --------------------------*/ + /* Get the DAC CR value */ + tmpreg1 = DAC->CR; + /* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */ + tmpreg1 &= ~(CR_CLEAR_MASK << DAC_Channel); + /* Configure for the selected DAC channel: buffer output, trigger, + wave generation, mask/amplitude for wave generation */ + /* Set TSELx and TENx bits according to DAC_Trigger value */ + /* Set WAVEx bits according to DAC_WaveGeneration value */ + /* Set MAMPx bits according to DAC_LFSRUnmask_TriangleAmplitude value */ + /* Set BOFFx bit according to DAC_OutputBuffer value */ + tmpreg2 = (DAC_InitStruct->DAC_Trigger | DAC_InitStruct->DAC_WaveGeneration | + DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude | \ + DAC_InitStruct->DAC_OutputBuffer); + /* Calculate CR register value depending on DAC_Channel */ + tmpreg1 |= tmpreg2 << DAC_Channel; + /* Write to DAC CR */ + DAC->CR = tmpreg1; +} + +/** + * @brief Fills each DAC_InitStruct member with its default value. + * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct) +{ +/*--------------- Reset DAC init structure parameters values -----------------*/ + /* Initialize the DAC_Trigger member */ + DAC_InitStruct->DAC_Trigger = DAC_Trigger_None; + /* Initialize the DAC_WaveGeneration member */ + DAC_InitStruct->DAC_WaveGeneration = DAC_WaveGeneration_None; + /* Initialize the DAC_LFSRUnmask_TriangleAmplitude member */ + DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; + /* Initialize the DAC_OutputBuffer member */ + DAC_InitStruct->DAC_OutputBuffer = DAC_OutputBuffer_Enable; +} + +/** + * @brief Enables or disables the specified DAC channel. + * @param DAC_Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param NewState: new state of the DAC channel. + * This parameter can be: ENABLE or DISABLE. + * @note When the DAC channel is enabled the trigger source can no more be modified. + * @retval None + */ +void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected DAC channel */ + DAC->CR |= (DAC_CR_EN1 << DAC_Channel); + } + else + { + /* Disable the selected DAC channel */ + DAC->CR &= (~(DAC_CR_EN1 << DAC_Channel)); + } +} + +/** + * @brief Enables or disables the selected DAC channel software trigger. + * @param DAC_Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param NewState: new state of the selected DAC channel software trigger. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable software trigger for the selected DAC channel */ + DAC->SWTRIGR |= (uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4); + } + else + { + /* Disable software trigger for the selected DAC channel */ + DAC->SWTRIGR &= ~((uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4)); + } +} + +/** + * @brief Enables or disables simultaneously the two DAC channels software triggers. + * @param NewState: new state of the DAC channels software triggers. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_DualSoftwareTriggerCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable software trigger for both DAC channels */ + DAC->SWTRIGR |= DUAL_SWTRIG_SET; + } + else + { + /* Disable software trigger for both DAC channels */ + DAC->SWTRIGR &= DUAL_SWTRIG_RESET; + } +} + +/** + * @brief Enables or disables the selected DAC channel wave generation. + * @param DAC_Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_Wave: specifies the wave type to enable or disable. + * This parameter can be one of the following values: + * @arg DAC_Wave_Noise: noise wave generation + * @arg DAC_Wave_Triangle: triangle wave generation + * @param NewState: new state of the selected DAC channel wave generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_WAVE(DAC_Wave)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected wave generation for the selected DAC channel */ + DAC->CR |= DAC_Wave << DAC_Channel; + } + else + { + /* Disable the selected wave generation for the selected DAC channel */ + DAC->CR &= ~(DAC_Wave << DAC_Channel); + } +} + +/** + * @brief Set the specified data holding register value for DAC channel1. + * @param DAC_Align: Specifies the data alignment for DAC channel1. + * This parameter can be one of the following values: + * @arg DAC_Align_8b_R: 8bit right data alignment selected + * @arg DAC_Align_12b_L: 12bit left data alignment selected + * @arg DAC_Align_12b_R: 12bit right data alignment selected + * @param Data: Data to be loaded in the selected data holding register. + * @retval None + */ +void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_ALIGN(DAC_Align)); + assert_param(IS_DAC_DATA(Data)); + + tmp = (uint32_t)DAC_BASE; + tmp += DHR12R1_OFFSET + DAC_Align; + + /* Set the DAC channel1 selected data holding register */ + *(__IO uint32_t *) tmp = Data; +} + +/** + * @brief Set the specified data holding register value for DAC channel2. + * @param DAC_Align: Specifies the data alignment for DAC channel2. + * This parameter can be one of the following values: + * @arg DAC_Align_8b_R: 8bit right data alignment selected + * @arg DAC_Align_12b_L: 12bit left data alignment selected + * @arg DAC_Align_12b_R: 12bit right data alignment selected + * @param Data: Data to be loaded in the selected data holding register. + * @retval None + */ +void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_ALIGN(DAC_Align)); + assert_param(IS_DAC_DATA(Data)); + + tmp = (uint32_t)DAC_BASE; + tmp += DHR12R2_OFFSET + DAC_Align; + + /* Set the DAC channel2 selected data holding register */ + *(__IO uint32_t *)tmp = Data; +} + +/** + * @brief Set the specified data holding register value for dual channel DAC. + * @param DAC_Align: Specifies the data alignment for dual channel DAC. + * This parameter can be one of the following values: + * @arg DAC_Align_8b_R: 8bit right data alignment selected + * @arg DAC_Align_12b_L: 12bit left data alignment selected + * @arg DAC_Align_12b_R: 12bit right data alignment selected + * @param Data2: Data for DAC Channel2 to be loaded in the selected data holding register. + * @param Data1: Data for DAC Channel1 to be loaded in the selected data holding register. + * @note In dual mode, a unique register access is required to write in both + * DAC channels at the same time. + * @retval None + */ +void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1) +{ + uint32_t data = 0, tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_ALIGN(DAC_Align)); + assert_param(IS_DAC_DATA(Data1)); + assert_param(IS_DAC_DATA(Data2)); + + /* Calculate and set dual DAC data holding register value */ + if (DAC_Align == DAC_Align_8b_R) + { + data = ((uint32_t)Data2 << 8) | Data1; + } + else + { + data = ((uint32_t)Data2 << 16) | Data1; + } + + tmp = (uint32_t)DAC_BASE; + tmp += DHR12RD_OFFSET + DAC_Align; + + /* Set the dual DAC selected data holding register */ + *(__IO uint32_t *)tmp = data; +} + +/** + * @brief Returns the last data output value of the selected DAC channel. + * @param DAC_Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @retval The selected DAC channel data output value. + */ +uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + + tmp = (uint32_t) DAC_BASE ; + tmp += DOR_OFFSET + ((uint32_t)DAC_Channel >> 2); + + /* Returns the DAC channel data output register value */ + return (uint16_t) (*(__IO uint32_t*) tmp); +} +/** + * @} + */ + +/** @defgroup DAC_Group2 DMA management functions + * @brief DMA management functions + * +@verbatim + =============================================================================== + DMA management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified DAC channel DMA request. + * @note When enabled DMA1 is generated when an external trigger (EXTI Line9, + * TIM2, TIM4, TIM5, TIM6, TIM7 or TIM8 but not a software trigger) occurs. + * @param DAC_Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param NewState: new state of the selected DAC channel DMA request. + * This parameter can be: ENABLE or DISABLE. + * @note The DAC channel1 is mapped on DMA1 Stream 5 channel7 which must be + * already configured. + * @note The DAC channel2 is mapped on DMA1 Stream 6 channel7 which must be + * already configured. + * @retval None + */ +void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected DAC channel DMA request */ + DAC->CR |= (DAC_CR_DMAEN1 << DAC_Channel); + } + else + { + /* Disable the selected DAC channel DMA request */ + DAC->CR &= (~(DAC_CR_DMAEN1 << DAC_Channel)); + } +} +/** + * @} + */ + +/** @defgroup DAC_Group3 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified DAC interrupts. + * @param DAC_Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_IT: specifies the DAC interrupt sources to be enabled or disabled. + * This parameter can be the following values: + * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask + * @note The DMA underrun occurs when a second external trigger arrives before the + * acknowledgement for the first external trigger is received (first request). + * @param NewState: new state of the specified DAC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_DAC_IT(DAC_IT)); + + if (NewState != DISABLE) + { + /* Enable the selected DAC interrupts */ + DAC->CR |= (DAC_IT << DAC_Channel); + } + else + { + /* Disable the selected DAC interrupts */ + DAC->CR &= (~(uint32_t)(DAC_IT << DAC_Channel)); + } +} + +/** + * @brief Checks whether the specified DAC flag is set or not. + * @param DAC_Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_FLAG: specifies the flag to check. + * This parameter can be only of the following value: + * @arg DAC_FLAG_DMAUDR: DMA underrun flag + * @note The DMA underrun occurs when a second external trigger arrives before the + * acknowledgement for the first external trigger is received (first request). + * @retval The new state of DAC_FLAG (SET or RESET). + */ +FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_FLAG(DAC_FLAG)); + + /* Check the status of the specified DAC flag */ + if ((DAC->SR & (DAC_FLAG << DAC_Channel)) != (uint8_t)RESET) + { + /* DAC_FLAG is set */ + bitstatus = SET; + } + else + { + /* DAC_FLAG is reset */ + bitstatus = RESET; + } + /* Return the DAC_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the DAC channel's pending flags. + * @param DAC_Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_FLAG: specifies the flag to clear. + * This parameter can be of the following value: + * @arg DAC_FLAG_DMAUDR: DMA underrun flag + * @note The DMA underrun occurs when a second external trigger arrives before the + * acknowledgement for the first external trigger is received (first request). + * @retval None + */ +void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_FLAG(DAC_FLAG)); + + /* Clear the selected DAC flags */ + DAC->SR = (DAC_FLAG << DAC_Channel); +} + +/** + * @brief Checks whether the specified DAC interrupt has occurred or not. + * @param DAC_Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_IT: specifies the DAC interrupt source to check. + * This parameter can be the following values: + * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask + * @note The DMA underrun occurs when a second external trigger arrives before the + * acknowledgement for the first external trigger is received (first request). + * @retval The new state of DAC_IT (SET or RESET). + */ +ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_IT(DAC_IT)); + + /* Get the DAC_IT enable bit status */ + enablestatus = (DAC->CR & (DAC_IT << DAC_Channel)) ; + + /* Check the status of the specified DAC interrupt */ + if (((DAC->SR & (DAC_IT << DAC_Channel)) != (uint32_t)RESET) && enablestatus) + { + /* DAC_IT is set */ + bitstatus = SET; + } + else + { + /* DAC_IT is reset */ + bitstatus = RESET; + } + /* Return the DAC_IT status */ + return bitstatus; +} + +/** + * @brief Clears the DAC channel's interrupt pending bits. + * @param DAC_Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_IT: specifies the DAC interrupt pending bit to clear. + * This parameter can be the following values: + * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask + * @note The DMA underrun occurs when a second external trigger arrives before the + * acknowledgement for the first external trigger is received (first request). + * @retval None + */ +void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_IT(DAC_IT)); + + /* Clear the selected DAC interrupt pending bits */ + DAC->SR = (DAC_IT << DAC_Channel); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dbgmcu.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dbgmcu.c new file mode 100644 index 0000000..b81dff4 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dbgmcu.c @@ -0,0 +1,174 @@ +/** + ****************************************************************************** + * @file stm32f4xx_dbgmcu.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides all the DBGMCU firmware functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_dbgmcu.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup DBGMCU + * @brief DBGMCU driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup DBGMCU_Private_Functions + * @{ + */ + +/** + * @brief Returns the device revision identifier. + * @param None + * @retval Device revision identifier + */ +uint32_t DBGMCU_GetREVID(void) +{ + return(DBGMCU->IDCODE >> 16); +} + +/** + * @brief Returns the device identifier. + * @param None + * @retval Device identifier + */ +uint32_t DBGMCU_GetDEVID(void) +{ + return(DBGMCU->IDCODE & IDCODE_DEVID_MASK); +} + +/** + * @brief Configures low power mode behavior when the MCU is in Debug mode. + * @param DBGMCU_Periph: specifies the low power mode. + * This parameter can be any combination of the following values: + * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode + * @arg DBGMCU_STOP: Keep debugger connection during STOP mode + * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode + * @param NewState: new state of the specified low power mode in Debug mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + DBGMCU->CR |= DBGMCU_Periph; + } + else + { + DBGMCU->CR &= ~DBGMCU_Periph; + } +} + +/** + * @brief Configures APB1 peripheral behavior when the MCU is in Debug mode. + * @param DBGMCU_Periph: specifies the APB1 peripheral. + * This parameter can be any combination of the following values: + * @arg DBGMCU_TIM2_STOP: TIM2 counter stopped when Core is halted + * @arg DBGMCU_TIM3_STOP: TIM3 counter stopped when Core is halted + * @arg DBGMCU_TIM4_STOP: TIM4 counter stopped when Core is halted + * @arg DBGMCU_TIM5_STOP: TIM5 counter stopped when Core is halted + * @arg DBGMCU_TIM6_STOP: TIM6 counter stopped when Core is halted + * @arg DBGMCU_TIM7_STOP: TIM7 counter stopped when Core is halted + * @arg DBGMCU_TIM12_STOP: TIM12 counter stopped when Core is halted + * @arg DBGMCU_TIM13_STOP: TIM13 counter stopped when Core is halted + * @arg DBGMCU_TIM14_STOP: TIM14 counter stopped when Core is halted + * @arg DBGMCU_RTC_STOP: RTC Calendar and Wakeup counter stopped when Core is halted. + * @arg DBGMCU_WWDG_STOP: Debug WWDG stopped when Core is halted + * @arg DBGMCU_IWDG_STOP: Debug IWDG stopped when Core is halted + * @arg DBGMCU_I2C1_SMBUS_TIMEOUT: I2C1 SMBUS timeout mode stopped when Core is halted + * @arg DBGMCU_I2C2_SMBUS_TIMEOUT: I2C2 SMBUS timeout mode stopped when Core is halted + * @arg DBGMCU_I2C3_SMBUS_TIMEOUT: I2C3 SMBUS timeout mode stopped when Core is halted + * @arg DBGMCU_CAN2_STOP: Debug CAN1 stopped when Core is halted + * @arg DBGMCU_CAN1_STOP: Debug CAN2 stopped when Core is halted + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DBGMCU_APB1PERIPH(DBGMCU_Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + DBGMCU->APB1FZ |= DBGMCU_Periph; + } + else + { + DBGMCU->APB1FZ &= ~DBGMCU_Periph; + } +} + +/** + * @brief Configures APB2 peripheral behavior when the MCU is in Debug mode. + * @param DBGMCU_Periph: specifies the APB2 peripheral. + * This parameter can be any combination of the following values: + * @arg DBGMCU_TIM1_STOP: TIM1 counter stopped when Core is halted + * @arg DBGMCU_TIM8_STOP: TIM8 counter stopped when Core is halted + * @arg DBGMCU_TIM9_STOP: TIM9 counter stopped when Core is halted + * @arg DBGMCU_TIM10_STOP: TIM10 counter stopped when Core is halted + * @arg DBGMCU_TIM11_STOP: TIM11 counter stopped when Core is halted + * @param NewState: new state of the specified peripheral in Debug mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DBGMCU_APB2PERIPH(DBGMCU_Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + DBGMCU->APB2FZ |= DBGMCU_Periph; + } + else + { + DBGMCU->APB2FZ &= ~DBGMCU_Periph; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dcmi.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dcmi.c new file mode 100644 index 0000000..3ffc36d --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dcmi.c @@ -0,0 +1,534 @@ +/** + ****************************************************************************** + * @file stm32f4xx_dcmi.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the DCMI peripheral: + * - Initialization and Configuration + * - Image capture functions + * - Interrupts and flags management + * + * @verbatim + * + * + * =================================================================== + * How to use this driver + * =================================================================== + * + * The sequence below describes how to use this driver to capture image + * from a camera module connected to the DCMI Interface. + * This sequence does not take into account the configuration of the + * camera module, which should be made before to configure and enable + * the DCMI to capture images. + * + * 1. Enable the clock for the DCMI and associated GPIOs using the following functions: + * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE); + * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); + * + * 2. DCMI pins configuration + * - Connect the involved DCMI pins to AF13 using the following function + * GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_DCMI); + * - Configure these DCMI pins in alternate function mode by calling the function + * GPIO_Init(); + * + * 3. Declare a DCMI_InitTypeDef structure, for example: + * DCMI_InitTypeDef DCMI_InitStructure; + * and fill the DCMI_InitStructure variable with the allowed values + * of the structure member. + * + * 4. Initialize the DCMI interface by calling the function + * DCMI_Init(&DCMI_InitStructure); + * + * 5. Configure the DMA2_Stream1 channel1 to transfer Data from DCMI DR + * register to the destination memory buffer. + * + * 6. Enable DCMI interface using the function + * DCMI_Cmd(ENABLE); + * + * 7. Start the image capture using the function + * DCMI_CaptureCmd(ENABLE); + * + * 8. At this stage the DCMI interface waits for the first start of frame, + * then a DMA request is generated continuously/once (depending on the + * mode used, Continuous/Snapshot) to transfer the received data into + * the destination memory. + * + * @note If you need to capture only a rectangular window from the received + * image, you have to use the DCMI_CROPConfig() function to configure + * the coordinates and size of the window to be captured, then enable + * the Crop feature using DCMI_CROPCmd(ENABLE); + * In this case, the Crop configuration should be made before to enable + * and start the DCMI interface. + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_dcmi.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup DCMI + * @brief DCMI driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup DCMI_Private_Functions + * @{ + */ + +/** @defgroup DCMI_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the DCMI registers to their default reset values. + * @param None + * @retval None + */ +void DCMI_DeInit(void) +{ + DCMI->CR = 0x0; + DCMI->IER = 0x0; + DCMI->ICR = 0x1F; + DCMI->ESCR = 0x0; + DCMI->ESUR = 0x0; + DCMI->CWSTRTR = 0x0; + DCMI->CWSIZER = 0x0; +} + +/** + * @brief Initializes the DCMI according to the specified parameters in the DCMI_InitStruct. + * @param DCMI_InitStruct: pointer to a DCMI_InitTypeDef structure that contains + * the configuration information for the DCMI. + * @retval None + */ +void DCMI_Init(DCMI_InitTypeDef* DCMI_InitStruct) +{ + uint32_t temp = 0x0; + + /* Check the parameters */ + assert_param(IS_DCMI_CAPTURE_MODE(DCMI_InitStruct->DCMI_CaptureMode)); + assert_param(IS_DCMI_SYNCHRO(DCMI_InitStruct->DCMI_SynchroMode)); + assert_param(IS_DCMI_PCKPOLARITY(DCMI_InitStruct->DCMI_PCKPolarity)); + assert_param(IS_DCMI_VSPOLARITY(DCMI_InitStruct->DCMI_VSPolarity)); + assert_param(IS_DCMI_HSPOLARITY(DCMI_InitStruct->DCMI_HSPolarity)); + assert_param(IS_DCMI_CAPTURE_RATE(DCMI_InitStruct->DCMI_CaptureRate)); + assert_param(IS_DCMI_EXTENDED_DATA(DCMI_InitStruct->DCMI_ExtendedDataMode)); + + /* The DCMI configuration registers should be programmed correctly before + enabling the CR_ENABLE Bit and the CR_CAPTURE Bit */ + DCMI->CR &= ~(DCMI_CR_ENABLE | DCMI_CR_CAPTURE); + + /* Reset the old DCMI configuration */ + temp = DCMI->CR; + + temp &= ~((uint32_t)DCMI_CR_CM | DCMI_CR_ESS | DCMI_CR_PCKPOL | + DCMI_CR_HSPOL | DCMI_CR_VSPOL | DCMI_CR_FCRC_0 | + DCMI_CR_FCRC_1 | DCMI_CR_EDM_0 | DCMI_CR_EDM_1); + + /* Sets the new configuration of the DCMI peripheral */ + temp |= ((uint32_t)DCMI_InitStruct->DCMI_CaptureMode | + DCMI_InitStruct->DCMI_SynchroMode | + DCMI_InitStruct->DCMI_PCKPolarity | + DCMI_InitStruct->DCMI_VSPolarity | + DCMI_InitStruct->DCMI_HSPolarity | + DCMI_InitStruct->DCMI_CaptureRate | + DCMI_InitStruct->DCMI_ExtendedDataMode); + + DCMI->CR = temp; +} + +/** + * @brief Fills each DCMI_InitStruct member with its default value. + * @param DCMI_InitStruct : pointer to a DCMI_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void DCMI_StructInit(DCMI_InitTypeDef* DCMI_InitStruct) +{ + /* Set the default configuration */ + DCMI_InitStruct->DCMI_CaptureMode = DCMI_CaptureMode_Continuous; + DCMI_InitStruct->DCMI_SynchroMode = DCMI_SynchroMode_Hardware; + DCMI_InitStruct->DCMI_PCKPolarity = DCMI_PCKPolarity_Falling; + DCMI_InitStruct->DCMI_VSPolarity = DCMI_VSPolarity_Low; + DCMI_InitStruct->DCMI_HSPolarity = DCMI_HSPolarity_Low; + DCMI_InitStruct->DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; + DCMI_InitStruct->DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b; +} + +/** + * @brief Initializes the DCMI peripheral CROP mode according to the specified + * parameters in the DCMI_CROPInitStruct. + * @note This function should be called before to enable and start the DCMI interface. + * @param DCMI_CROPInitStruct: pointer to a DCMI_CROPInitTypeDef structure that + * contains the configuration information for the DCMI peripheral CROP mode. + * @retval None + */ +void DCMI_CROPConfig(DCMI_CROPInitTypeDef* DCMI_CROPInitStruct) +{ + /* Sets the CROP window coordinates */ + DCMI->CWSTRTR = (uint32_t)((uint32_t)DCMI_CROPInitStruct->DCMI_HorizontalOffsetCount | + ((uint32_t)DCMI_CROPInitStruct->DCMI_VerticalStartLine << 16)); + + /* Sets the CROP window size */ + DCMI->CWSIZER = (uint32_t)(DCMI_CROPInitStruct->DCMI_CaptureCount | + ((uint32_t)DCMI_CROPInitStruct->DCMI_VerticalLineCount << 16)); +} + +/** + * @brief Enables or disables the DCMI Crop feature. + * @note This function should be called before to enable and start the DCMI interface. + * @param NewState: new state of the DCMI Crop feature. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DCMI_CROPCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DCMI Crop feature */ + DCMI->CR |= (uint32_t)DCMI_CR_CROP; + } + else + { + /* Disable the DCMI Crop feature */ + DCMI->CR &= ~(uint32_t)DCMI_CR_CROP; + } +} + +/** + * @brief Sets the embedded synchronization codes + * @param DCMI_CodesInitTypeDef: pointer to a DCMI_CodesInitTypeDef structure that + * contains the embedded synchronization codes for the DCMI peripheral. + * @retval None + */ +void DCMI_SetEmbeddedSynchroCodes(DCMI_CodesInitTypeDef* DCMI_CodesInitStruct) +{ + DCMI->ESCR = (uint32_t)(DCMI_CodesInitStruct->DCMI_FrameStartCode | + ((uint32_t)DCMI_CodesInitStruct->DCMI_LineStartCode << 8)| + ((uint32_t)DCMI_CodesInitStruct->DCMI_LineEndCode << 16)| + ((uint32_t)DCMI_CodesInitStruct->DCMI_FrameEndCode << 24)); +} + +/** + * @brief Enables or disables the DCMI JPEG format. + * @note The Crop and Embedded Synchronization features cannot be used in this mode. + * @param NewState: new state of the DCMI JPEG format. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DCMI_JPEGCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DCMI JPEG format */ + DCMI->CR |= (uint32_t)DCMI_CR_JPEG; + } + else + { + /* Disable the DCMI JPEG format */ + DCMI->CR &= ~(uint32_t)DCMI_CR_JPEG; + } +} +/** + * @} + */ + +/** @defgroup DCMI_Group2 Image capture functions + * @brief Image capture functions + * +@verbatim + =============================================================================== + Image capture functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the DCMI interface. + * @param NewState: new state of the DCMI interface. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DCMI_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DCMI by setting ENABLE bit */ + DCMI->CR |= (uint32_t)DCMI_CR_ENABLE; + } + else + { + /* Disable the DCMI by clearing ENABLE bit */ + DCMI->CR &= ~(uint32_t)DCMI_CR_ENABLE; + } +} + +/** + * @brief Enables or disables the DCMI Capture. + * @param NewState: new state of the DCMI capture. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DCMI_CaptureCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DCMI Capture */ + DCMI->CR |= (uint32_t)DCMI_CR_CAPTURE; + } + else + { + /* Disable the DCMI Capture */ + DCMI->CR &= ~(uint32_t)DCMI_CR_CAPTURE; + } +} + +/** + * @brief Reads the data stored in the DR register. + * @param None + * @retval Data register value + */ +uint32_t DCMI_ReadData(void) +{ + return DCMI->DR; +} +/** + * @} + */ + +/** @defgroup DCMI_Group3 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the DCMI interface interrupts. + * @param DCMI_IT: specifies the DCMI interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask + * @arg DCMI_IT_OVF: Overflow interrupt mask + * @arg DCMI_IT_ERR: Synchronization error interrupt mask + * @arg DCMI_IT_VSYNC: VSYNC interrupt mask + * @arg DCMI_IT_LINE: Line interrupt mask + * @param NewState: new state of the specified DCMI interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DCMI_ITConfig(uint16_t DCMI_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DCMI_CONFIG_IT(DCMI_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Interrupt sources */ + DCMI->IER |= DCMI_IT; + } + else + { + /* Disable the Interrupt sources */ + DCMI->IER &= (uint16_t)(~DCMI_IT); + } +} + +/** + * @brief Checks whether the DCMI interface flag is set or not. + * @param DCMI_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg DCMI_FLAG_FRAMERI: Frame capture complete Raw flag mask + * @arg DCMI_FLAG_OVFRI: Overflow Raw flag mask + * @arg DCMI_FLAG_ERRRI: Synchronization error Raw flag mask + * @arg DCMI_FLAG_VSYNCRI: VSYNC Raw flag mask + * @arg DCMI_FLAG_LINERI: Line Raw flag mask + * @arg DCMI_FLAG_FRAMEMI: Frame capture complete Masked flag mask + * @arg DCMI_FLAG_OVFMI: Overflow Masked flag mask + * @arg DCMI_FLAG_ERRMI: Synchronization error Masked flag mask + * @arg DCMI_FLAG_VSYNCMI: VSYNC Masked flag mask + * @arg DCMI_FLAG_LINEMI: Line Masked flag mask + * @arg DCMI_FLAG_HSYNC: HSYNC flag mask + * @arg DCMI_FLAG_VSYNC: VSYNC flag mask + * @arg DCMI_FLAG_FNE: Fifo not empty flag mask + * @retval The new state of DCMI_FLAG (SET or RESET). + */ +FlagStatus DCMI_GetFlagStatus(uint16_t DCMI_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t dcmireg, tempreg = 0; + + /* Check the parameters */ + assert_param(IS_DCMI_GET_FLAG(DCMI_FLAG)); + + /* Get the DCMI register index */ + dcmireg = (((uint16_t)DCMI_FLAG) >> 12); + + if (dcmireg == 0x01) /* The FLAG is in RISR register */ + { + tempreg= DCMI->RISR; + } + else if (dcmireg == 0x02) /* The FLAG is in SR register */ + { + tempreg = DCMI->SR; + } + else /* The FLAG is in MISR register */ + { + tempreg = DCMI->MISR; + } + + if ((tempreg & DCMI_FLAG) != (uint16_t)RESET ) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the DCMI_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the DCMI's pending flags. + * @param DCMI_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DCMI_FLAG_FRAMERI: Frame capture complete Raw flag mask + * @arg DCMI_FLAG_OVFRI: Overflow Raw flag mask + * @arg DCMI_FLAG_ERRRI: Synchronization error Raw flag mask + * @arg DCMI_FLAG_VSYNCRI: VSYNC Raw flag mask + * @arg DCMI_FLAG_LINERI: Line Raw flag mask + * @retval None + */ +void DCMI_ClearFlag(uint16_t DCMI_FLAG) +{ + /* Check the parameters */ + assert_param(IS_DCMI_CLEAR_FLAG(DCMI_FLAG)); + + /* Clear the flag by writing in the ICR register 1 in the corresponding + Flag position*/ + + DCMI->ICR = DCMI_FLAG; +} + +/** + * @brief Checks whether the DCMI interrupt has occurred or not. + * @param DCMI_IT: specifies the DCMI interrupt source to check. + * This parameter can be one of the following values: + * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask + * @arg DCMI_IT_OVF: Overflow interrupt mask + * @arg DCMI_IT_ERR: Synchronization error interrupt mask + * @arg DCMI_IT_VSYNC: VSYNC interrupt mask + * @arg DCMI_IT_LINE: Line interrupt mask + * @retval The new state of DCMI_IT (SET or RESET). + */ +ITStatus DCMI_GetITStatus(uint16_t DCMI_IT) +{ + ITStatus bitstatus = RESET; + uint32_t itstatus = 0; + + /* Check the parameters */ + assert_param(IS_DCMI_GET_IT(DCMI_IT)); + + itstatus = DCMI->MISR & DCMI_IT; /* Only masked interrupts are checked */ + + if ((itstatus != (uint16_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the DCMI's interrupt pending bits. + * @param DCMI_IT: specifies the DCMI interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask + * @arg DCMI_IT_OVF: Overflow interrupt mask + * @arg DCMI_IT_ERR: Synchronization error interrupt mask + * @arg DCMI_IT_VSYNC: VSYNC interrupt mask + * @arg DCMI_IT_LINE: Line interrupt mask + * @retval None + */ +void DCMI_ClearITPendingBit(uint16_t DCMI_IT) +{ + /* Clear the interrupt pending Bit by writing in the ICR register 1 in the + corresponding pending Bit position*/ + + DCMI->ICR = DCMI_IT; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.c new file mode 100644 index 0000000..c2868cf --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.c @@ -0,0 +1,1283 @@ +/** + ****************************************************************************** + * @file stm32f4xx_dma.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Direct Memory Access controller (DMA): + * - Initialization and Configuration + * - Data Counter + * - Double Buffer mode configuration and command + * - Interrupts and flags management + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + * 1. Enable The DMA controller clock using RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA1, ENABLE) + * function for DMA1 or using RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA2, ENABLE) + * function for DMA2. + * + * 2. Enable and configure the peripheral to be connected to the DMA Stream + * (except for internal SRAM / FLASH memories: no initialization is + * necessary). + * + * 3. For a given Stream, program the required configuration through following parameters: + * Source and Destination addresses, Transfer Direction, Transfer size, Source and Destination + * data formats, Circular or Normal mode, Stream Priority level, Source and Destination + * Incrementation mode, FIFO mode and its Threshold (if needed), Burst mode for Source and/or + * Destination (if needed) using the DMA_Init() function. + * To avoid filling un-nesecessary fields, you can call DMA_StructInit() function + * to initialize a given structure with default values (reset values), the modify + * only necessary fields (ie. Source and Destination addresses, Transfer size and Data Formats). + * + * 4. Enable the NVIC and the corresponding interrupt(s) using the function + * DMA_ITConfig() if you need to use DMA interrupts. + * + * 5. Optionally, if the Circular mode is enabled, you can use the Double buffer mode by configuring + * the second Memory address and the first Memory to be used through the function + * DMA_DoubleBufferModeConfig(). Then enable the Double buffer mode through the function + * DMA_DoubleBufferModeCmd(). These operations must be done before step 6. + * + * 6. Enable the DMA stream using the DMA_Cmd() function. + * + * 7. Activate the needed Stream Request using PPP_DMACmd() function for + * any PPP peripheral except internal SRAM and FLASH (ie. SPI, USART ...) + * The function allowing this operation is provided in each PPP peripheral + * driver (ie. SPI_DMACmd for SPI peripheral). + * Once the Stream is enabled, it is not possible to modify its configuration + * unless the stream is stopped and disabled. + * After enabling the Stream, it is advised to monitor the EN bit status using + * the function DMA_GetCmdStatus(). In case of configuration errors or bus errors + * this bit will remain reset and all transfers on this Stream will remain on hold. + * + * 8. Optionally, you can configure the number of data to be transferred + * when the Stream is disabled (ie. after each Transfer Complete event + * or when a Transfer Error occurs) using the function DMA_SetCurrDataCounter(). + * And you can get the number of remaining data to be transferred using + * the function DMA_GetCurrDataCounter() at run time (when the DMA Stream is + * enabled and running). + * + * 9. To control DMA events you can use one of the following + * two methods: + * a- Check on DMA Stream flags using the function DMA_GetFlagStatus(). + * b- Use DMA interrupts through the function DMA_ITConfig() at initialization + * phase and DMA_GetITStatus() function into interrupt routines in + * communication phase. + * After checking on a flag you should clear it using DMA_ClearFlag() + * function. And after checking on an interrupt event you should + * clear it using DMA_ClearITPendingBit() function. + * + * 10. Optionally, if Circular mode and Double Buffer mode are enabled, you can modify + * the Memory Addresses using the function DMA_MemoryTargetConfig(). Make sure that + * the Memory Address to be modified is not the one currently in use by DMA Stream. + * This condition can be monitored using the function DMA_GetCurrentMemoryTarget(). + * + * 11. Optionally, Pause-Resume operations may be performed: + * The DMA_Cmd() function may be used to perform Pause-Resume operation. When a + * transfer is ongoing, calling this function to disable the Stream will cause the + * transfer to be paused. All configuration registers and the number of remaining + * data will be preserved. When calling again this function to re-enable the Stream, + * the transfer will be resumed from the point where it was paused. + * + * @note Memory-to-Memory transfer is possible by setting the address of the memory into + * the Peripheral registers. In this mode, Circular mode and Double Buffer mode + * are not allowed. + * + * @note The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is + * possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set + * Half-Word data size for the peripheral to access its data register and set Word data size + * for the Memory to gain in access time. Each two Half-words will be packed and written in + * a single access to a Word in the Memory). + * + * @note When FIFO is disabled, it is not allowed to configure different Data Sizes for Source + * and Destination. In this case the Peripheral Data Size will be applied to both Source + * and Destination. + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_dma.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup DMA + * @brief DMA driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* Masks Definition */ +#define TRANSFER_IT_ENABLE_MASK (uint32_t)(DMA_SxCR_TCIE | DMA_SxCR_HTIE | \ + DMA_SxCR_TEIE | DMA_SxCR_DMEIE) + +#define DMA_Stream0_IT_MASK (uint32_t)(DMA_LISR_FEIF0 | DMA_LISR_DMEIF0 | \ + DMA_LISR_TEIF0 | DMA_LISR_HTIF0 | \ + DMA_LISR_TCIF0) + +#define DMA_Stream1_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK << 6) +#define DMA_Stream2_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK << 16) +#define DMA_Stream3_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK << 22) +#define DMA_Stream4_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK | (uint32_t)0x20000000) +#define DMA_Stream5_IT_MASK (uint32_t)(DMA_Stream1_IT_MASK | (uint32_t)0x20000000) +#define DMA_Stream6_IT_MASK (uint32_t)(DMA_Stream2_IT_MASK | (uint32_t)0x20000000) +#define DMA_Stream7_IT_MASK (uint32_t)(DMA_Stream3_IT_MASK | (uint32_t)0x20000000) +#define TRANSFER_IT_MASK (uint32_t)0x0F3C0F3C +#define HIGH_ISR_MASK (uint32_t)0x20000000 +#define RESERVED_MASK (uint32_t)0x0F7D0F7D + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + + +/** @defgroup DMA_Private_Functions + * @{ + */ + +/** @defgroup DMA_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + + This subsection provides functions allowing to initialize the DMA Stream source + and destination addresses, incrementation and data sizes, transfer direction, + buffer size, circular/normal mode selection, memory-to-memory mode selection + and Stream priority value. + + The DMA_Init() function follows the DMA configuration procedures as described in + reference manual (RM0090) except the first point: waiting on EN bit to be reset. + This condition should be checked by user application using the function DMA_GetCmdStatus() + before calling the DMA_Init() function. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitialize the DMAy Streamx registers to their default reset values. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @retval None + */ +void DMA_DeInit(DMA_Stream_TypeDef* DMAy_Streamx) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + + /* Disable the selected DMAy Streamx */ + DMAy_Streamx->CR &= ~((uint32_t)DMA_SxCR_EN); + + /* Reset DMAy Streamx control register */ + DMAy_Streamx->CR = 0; + + /* Reset DMAy Streamx Number of Data to Transfer register */ + DMAy_Streamx->NDTR = 0; + + /* Reset DMAy Streamx peripheral address register */ + DMAy_Streamx->PAR = 0; + + /* Reset DMAy Streamx memory 0 address register */ + DMAy_Streamx->M0AR = 0; + + /* Reset DMAy Streamx memory 1 address register */ + DMAy_Streamx->M1AR = 0; + + /* Reset DMAy Streamx FIFO control register */ + DMAy_Streamx->FCR = (uint32_t)0x00000021; + + /* Reset interrupt pending bits for the selected stream */ + if (DMAy_Streamx == DMA1_Stream0) + { + /* Reset interrupt pending bits for DMA1 Stream0 */ + DMA1->LIFCR = DMA_Stream0_IT_MASK; + } + else if (DMAy_Streamx == DMA1_Stream1) + { + /* Reset interrupt pending bits for DMA1 Stream1 */ + DMA1->LIFCR = DMA_Stream1_IT_MASK; + } + else if (DMAy_Streamx == DMA1_Stream2) + { + /* Reset interrupt pending bits for DMA1 Stream2 */ + DMA1->LIFCR = DMA_Stream2_IT_MASK; + } + else if (DMAy_Streamx == DMA1_Stream3) + { + /* Reset interrupt pending bits for DMA1 Stream3 */ + DMA1->LIFCR = DMA_Stream3_IT_MASK; + } + else if (DMAy_Streamx == DMA1_Stream4) + { + /* Reset interrupt pending bits for DMA1 Stream4 */ + DMA1->HIFCR = DMA_Stream4_IT_MASK; + } + else if (DMAy_Streamx == DMA1_Stream5) + { + /* Reset interrupt pending bits for DMA1 Stream5 */ + DMA1->HIFCR = DMA_Stream5_IT_MASK; + } + else if (DMAy_Streamx == DMA1_Stream6) + { + /* Reset interrupt pending bits for DMA1 Stream6 */ + DMA1->HIFCR = (uint32_t)DMA_Stream6_IT_MASK; + } + else if (DMAy_Streamx == DMA1_Stream7) + { + /* Reset interrupt pending bits for DMA1 Stream7 */ + DMA1->HIFCR = DMA_Stream7_IT_MASK; + } + else if (DMAy_Streamx == DMA2_Stream0) + { + /* Reset interrupt pending bits for DMA2 Stream0 */ + DMA2->LIFCR = DMA_Stream0_IT_MASK; + } + else if (DMAy_Streamx == DMA2_Stream1) + { + /* Reset interrupt pending bits for DMA2 Stream1 */ + DMA2->LIFCR = DMA_Stream1_IT_MASK; + } + else if (DMAy_Streamx == DMA2_Stream2) + { + /* Reset interrupt pending bits for DMA2 Stream2 */ + DMA2->LIFCR = DMA_Stream2_IT_MASK; + } + else if (DMAy_Streamx == DMA2_Stream3) + { + /* Reset interrupt pending bits for DMA2 Stream3 */ + DMA2->LIFCR = DMA_Stream3_IT_MASK; + } + else if (DMAy_Streamx == DMA2_Stream4) + { + /* Reset interrupt pending bits for DMA2 Stream4 */ + DMA2->HIFCR = DMA_Stream4_IT_MASK; + } + else if (DMAy_Streamx == DMA2_Stream5) + { + /* Reset interrupt pending bits for DMA2 Stream5 */ + DMA2->HIFCR = DMA_Stream5_IT_MASK; + } + else if (DMAy_Streamx == DMA2_Stream6) + { + /* Reset interrupt pending bits for DMA2 Stream6 */ + DMA2->HIFCR = DMA_Stream6_IT_MASK; + } + else + { + if (DMAy_Streamx == DMA2_Stream7) + { + /* Reset interrupt pending bits for DMA2 Stream7 */ + DMA2->HIFCR = DMA_Stream7_IT_MASK; + } + } +} + +/** + * @brief Initializes the DMAy Streamx according to the specified parameters in + * the DMA_InitStruct structure. + * @note Before calling this function, it is recommended to check that the Stream + * is actually disabled using the function DMA_GetCmdStatus(). + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @retval None + */ +void DMA_Init(DMA_Stream_TypeDef* DMAy_Streamx, DMA_InitTypeDef* DMA_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_DMA_CHANNEL(DMA_InitStruct->DMA_Channel)); + assert_param(IS_DMA_DIRECTION(DMA_InitStruct->DMA_DIR)); + assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize)); + assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc)); + assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc)); + assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize)); + assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize)); + assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode)); + assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority)); + assert_param(IS_DMA_FIFO_MODE_STATE(DMA_InitStruct->DMA_FIFOMode)); + assert_param(IS_DMA_FIFO_THRESHOLD(DMA_InitStruct->DMA_FIFOThreshold)); + assert_param(IS_DMA_MEMORY_BURST(DMA_InitStruct->DMA_MemoryBurst)); + assert_param(IS_DMA_PERIPHERAL_BURST(DMA_InitStruct->DMA_PeripheralBurst)); + + /*------------------------- DMAy Streamx CR Configuration ------------------*/ + /* Get the DMAy_Streamx CR value */ + tmpreg = DMAy_Streamx->CR; + + /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */ + tmpreg &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \ + DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \ + DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \ + DMA_SxCR_DIR)); + + /* Configure DMAy Streamx: */ + /* Set CHSEL bits according to DMA_CHSEL value */ + /* Set DIR bits according to DMA_DIR value */ + /* Set PINC bit according to DMA_PeripheralInc value */ + /* Set MINC bit according to DMA_MemoryInc value */ + /* Set PSIZE bits according to DMA_PeripheralDataSize value */ + /* Set MSIZE bits according to DMA_MemoryDataSize value */ + /* Set CIRC bit according to DMA_Mode value */ + /* Set PL bits according to DMA_Priority value */ + /* Set MBURST bits according to DMA_MemoryBurst value */ + /* Set PBURST bits according to DMA_PeripheralBurst value */ + tmpreg |= DMA_InitStruct->DMA_Channel | DMA_InitStruct->DMA_DIR | + DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc | + DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize | + DMA_InitStruct->DMA_Mode | DMA_InitStruct->DMA_Priority | + DMA_InitStruct->DMA_MemoryBurst | DMA_InitStruct->DMA_PeripheralBurst; + + /* Write to DMAy Streamx CR register */ + DMAy_Streamx->CR = tmpreg; + + /*------------------------- DMAy Streamx FCR Configuration -----------------*/ + /* Get the DMAy_Streamx FCR value */ + tmpreg = DMAy_Streamx->FCR; + + /* Clear DMDIS and FTH bits */ + tmpreg &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); + + /* Configure DMAy Streamx FIFO: + Set DMDIS bits according to DMA_FIFOMode value + Set FTH bits according to DMA_FIFOThreshold value */ + tmpreg |= DMA_InitStruct->DMA_FIFOMode | DMA_InitStruct->DMA_FIFOThreshold; + + /* Write to DMAy Streamx CR */ + DMAy_Streamx->FCR = tmpreg; + + /*------------------------- DMAy Streamx NDTR Configuration ----------------*/ + /* Write to DMAy Streamx NDTR register */ + DMAy_Streamx->NDTR = DMA_InitStruct->DMA_BufferSize; + + /*------------------------- DMAy Streamx PAR Configuration -----------------*/ + /* Write to DMAy Streamx PAR */ + DMAy_Streamx->PAR = DMA_InitStruct->DMA_PeripheralBaseAddr; + + /*------------------------- DMAy Streamx M0AR Configuration ----------------*/ + /* Write to DMAy Streamx M0AR */ + DMAy_Streamx->M0AR = DMA_InitStruct->DMA_Memory0BaseAddr; +} + +/** + * @brief Fills each DMA_InitStruct member with its default value. + * @param DMA_InitStruct : pointer to a DMA_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct) +{ + /*-------------- Reset DMA init structure parameters values ----------------*/ + /* Initialize the DMA_Channel member */ + DMA_InitStruct->DMA_Channel = 0; + + /* Initialize the DMA_PeripheralBaseAddr member */ + DMA_InitStruct->DMA_PeripheralBaseAddr = 0; + + /* Initialize the DMA_Memory0BaseAddr member */ + DMA_InitStruct->DMA_Memory0BaseAddr = 0; + + /* Initialize the DMA_DIR member */ + DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralToMemory; + + /* Initialize the DMA_BufferSize member */ + DMA_InitStruct->DMA_BufferSize = 0; + + /* Initialize the DMA_PeripheralInc member */ + DMA_InitStruct->DMA_PeripheralInc = DMA_PeripheralInc_Disable; + + /* Initialize the DMA_MemoryInc member */ + DMA_InitStruct->DMA_MemoryInc = DMA_MemoryInc_Disable; + + /* Initialize the DMA_PeripheralDataSize member */ + DMA_InitStruct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + + /* Initialize the DMA_MemoryDataSize member */ + DMA_InitStruct->DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + + /* Initialize the DMA_Mode member */ + DMA_InitStruct->DMA_Mode = DMA_Mode_Normal; + + /* Initialize the DMA_Priority member */ + DMA_InitStruct->DMA_Priority = DMA_Priority_Low; + + /* Initialize the DMA_FIFOMode member */ + DMA_InitStruct->DMA_FIFOMode = DMA_FIFOMode_Disable; + + /* Initialize the DMA_FIFOThreshold member */ + DMA_InitStruct->DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + + /* Initialize the DMA_MemoryBurst member */ + DMA_InitStruct->DMA_MemoryBurst = DMA_MemoryBurst_Single; + + /* Initialize the DMA_PeripheralBurst member */ + DMA_InitStruct->DMA_PeripheralBurst = DMA_PeripheralBurst_Single; +} + +/** + * @brief Enables or disables the specified DMAy Streamx. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param NewState: new state of the DMAy Streamx. + * This parameter can be: ENABLE or DISABLE. + * + * @note This function may be used to perform Pause-Resume operation. When a + * transfer is ongoing, calling this function to disable the Stream will + * cause the transfer to be paused. All configuration registers and the + * number of remaining data will be preserved. When calling again this + * function to re-enable the Stream, the transfer will be resumed from + * the point where it was paused. + * + * @note After configuring the DMA Stream (DMA_Init() function) and enabling the + * stream, it is recommended to check (or wait until) the DMA Stream is + * effectively enabled. A Stream may remain disabled if a configuration + * parameter is wrong. + * After disabling a DMA Stream, it is also recommended to check (or wait + * until) the DMA Stream is effectively disabled. If a Stream is disabled + * while a data transfer is ongoing, the current data will be transferred + * and the Stream will be effectively disabled only after the transfer of + * this single data is finished. + * + * @retval None + */ +void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected DMAy Streamx by setting EN bit */ + DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_EN; + } + else + { + /* Disable the selected DMAy Streamx by clearing EN bit */ + DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_EN; + } +} + +/** + * @brief Configures, when the PINC (Peripheral Increment address mode) bit is + * set, if the peripheral address should be incremented with the data + * size (configured with PSIZE bits) or by a fixed offset equal to 4 + * (32-bit aligned addresses). + * + * @note This function has no effect if the Peripheral Increment mode is disabled. + * + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param DMA_Pincos: specifies the Peripheral increment offset size. + * This parameter can be one of the following values: + * @arg DMA_PINCOS_Psize: Peripheral address increment is done + * accordingly to PSIZE parameter. + * @arg DMA_PINCOS_WordAligned: Peripheral address increment offset is + * fixed to 4 (32-bit aligned addresses). + * @retval None + */ +void DMA_PeriphIncOffsetSizeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_Pincos) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_DMA_PINCOS_SIZE(DMA_Pincos)); + + /* Check the needed Peripheral increment offset */ + if(DMA_Pincos != DMA_PINCOS_Psize) + { + /* Configure DMA_SxCR_PINCOS bit with the input parameter */ + DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_PINCOS; + } + else + { + /* Clear the PINCOS bit: Peripheral address incremented according to PSIZE */ + DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_PINCOS; + } +} + +/** + * @brief Configures, when the DMAy Streamx is disabled, the flow controller for + * the next transactions (Peripheral or Memory). + * + * @note Before enabling this feature, check if the used peripheral supports + * the Flow Controller mode or not. + * + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param DMA_FlowCtrl: specifies the DMA flow controller. + * This parameter can be one of the following values: + * @arg DMA_FlowCtrl_Memory: DMAy_Streamx transactions flow controller is + * the DMA controller. + * @arg DMA_FlowCtrl_Peripheral: DMAy_Streamx transactions flow controller + * is the peripheral. + * @retval None + */ +void DMA_FlowControllerConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FlowCtrl) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_DMA_FLOW_CTRL(DMA_FlowCtrl)); + + /* Check the needed flow controller */ + if(DMA_FlowCtrl != DMA_FlowCtrl_Memory) + { + /* Configure DMA_SxCR_PFCTRL bit with the input parameter */ + DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_PFCTRL; + } + else + { + /* Clear the PFCTRL bit: Memory is the flow controller */ + DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_PFCTRL; + } +} +/** + * @} + */ + +/** @defgroup DMA_Group2 Data Counter functions + * @brief Data Counter functions + * +@verbatim + =============================================================================== + Data Counter functions + =============================================================================== + + This subsection provides function allowing to configure and read the buffer size + (number of data to be transferred). + + The DMA data counter can be written only when the DMA Stream is disabled + (ie. after transfer complete event). + + The following function can be used to write the Stream data counter value: + - void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter); + +@note It is advised to use this function rather than DMA_Init() in situations where + only the Data buffer needs to be reloaded. + +@note If the Source and Destination Data Sizes are different, then the value written in + data counter, expressing the number of transfers, is relative to the number of + transfers from the Peripheral point of view. + ie. If Memory data size is Word, Peripheral data size is Half-Words, then the value + to be configured in the data counter is the number of Half-Words to be transferred + from/to the peripheral. + + The DMA data counter can be read to indicate the number of remaining transfers for + the relative DMA Stream. This counter is decremented at the end of each data + transfer and when the transfer is complete: + - If Normal mode is selected: the counter is set to 0. + - If Circular mode is selected: the counter is reloaded with the initial value + (configured before enabling the DMA Stream) + + The following function can be used to read the Stream data counter value: + - uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx); + +@endverbatim + * @{ + */ + +/** + * @brief Writes the number of data units to be transferred on the DMAy Streamx. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param Counter: Number of data units to be transferred (from 0 to 65535) + * Number of data items depends only on the Peripheral data format. + * + * @note If Peripheral data format is Bytes: number of data units is equal + * to total number of bytes to be transferred. + * + * @note If Peripheral data format is Half-Word: number of data units is + * equal to total number of bytes to be transferred / 2. + * + * @note If Peripheral data format is Word: number of data units is equal + * to total number of bytes to be transferred / 4. + * + * @note In Memory-to-Memory transfer mode, the memory buffer pointed by + * DMAy_SxPAR register is considered as Peripheral. + * + * @retval The number of remaining data units in the current DMAy Streamx transfer. + */ +void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + + /* Write the number of data units to be transferred */ + DMAy_Streamx->NDTR = (uint16_t)Counter; +} + +/** + * @brief Returns the number of remaining data units in the current DMAy Streamx transfer. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @retval The number of remaining data units in the current DMAy Streamx transfer. + */ +uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + + /* Return the number of remaining data units for DMAy Streamx */ + return ((uint16_t)(DMAy_Streamx->NDTR)); +} +/** + * @} + */ + +/** @defgroup DMA_Group3 Double Buffer mode functions + * @brief Double Buffer mode functions + * +@verbatim + =============================================================================== + Double Buffer mode functions + =============================================================================== + + This subsection provides function allowing to configure and control the double + buffer mode parameters. + + The Double Buffer mode can be used only when Circular mode is enabled. + The Double Buffer mode cannot be used when transferring data from Memory to Memory. + + The Double Buffer mode allows to set two different Memory addresses from/to which + the DMA controller will access alternatively (after completing transfer to/from target + memory 0, it will start transfer to/from target memory 1). + This allows to reduce software overhead for double buffering and reduce the CPU + access time. + + Two functions must be called before calling the DMA_Init() function: + - void DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t Memory1BaseAddr, + uint32_t DMA_CurrentMemory); + - void DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState); + + DMA_DoubleBufferModeConfig() is called to configure the Memory 1 base address and the first + Memory target from/to which the transfer will start after enabling the DMA Stream. + Then DMA_DoubleBufferModeCmd() must be called to enable the Double Buffer mode (or disable + it when it should not be used). + + + Two functions can be called dynamically when the transfer is ongoing (or when the DMA Stream is + stopped) to modify on of the target Memories addresses or to check wich Memory target is currently + used: + - void DMA_MemoryTargetConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t MemoryBaseAddr, + uint32_t DMA_MemoryTarget); + - uint32_t DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx); + + DMA_MemoryTargetConfig() can be called to modify the base address of one of the two target Memories. + The Memory of which the base address will be modified must not be currently be used by the DMA Stream + (ie. if the DMA Stream is currently transferring from Memory 1 then you can only modify base address + of target Memory 0 and vice versa). + To check this condition, it is recommended to use the function DMA_GetCurrentMemoryTarget() which + returns the index of the Memory target currently in use by the DMA Stream. + +@endverbatim + * @{ + */ + +/** + * @brief Configures, when the DMAy Streamx is disabled, the double buffer mode + * and the current memory target. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param Memory1BaseAddr: the base address of the second buffer (Memory 1) + * @param DMA_CurrentMemory: specifies which memory will be first buffer for + * the transactions when the Stream will be enabled. + * This parameter can be one of the following values: + * @arg DMA_Memory_0: Memory 0 is the current buffer. + * @arg DMA_Memory_1: Memory 1 is the current buffer. + * + * @note Memory0BaseAddr is set by the DMA structure configuration in DMA_Init(). + * + * @retval None + */ +void DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t Memory1BaseAddr, + uint32_t DMA_CurrentMemory) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_DMA_CURRENT_MEM(DMA_CurrentMemory)); + + if (DMA_CurrentMemory != DMA_Memory_0) + { + /* Set Memory 1 as current memory address */ + DMAy_Streamx->CR |= (uint32_t)(DMA_SxCR_CT); + } + else + { + /* Set Memory 0 as current memory address */ + DMAy_Streamx->CR &= ~(uint32_t)(DMA_SxCR_CT); + } + + /* Write to DMAy Streamx M1AR */ + DMAy_Streamx->M1AR = Memory1BaseAddr; +} + +/** + * @brief Enables or disables the double buffer mode for the selected DMA stream. + * @note This function can be called only when the DMA Stream is disabled. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param NewState: new state of the DMAy Streamx double buffer mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Configure the Double Buffer mode */ + if (NewState != DISABLE) + { + /* Enable the Double buffer mode */ + DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_DBM; + } + else + { + /* Disable the Double buffer mode */ + DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_DBM; + } +} + +/** + * @brief Configures the Memory address for the next buffer transfer in double + * buffer mode (for dynamic use). This function can be called when the + * DMA Stream is enabled and when the transfer is ongoing. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param MemoryBaseAddr: The base address of the target memory buffer + * @param DMA_MemoryTarget: Next memory target to be used. + * This parameter can be one of the following values: + * @arg DMA_Memory_0: To use the memory address 0 + * @arg DMA_Memory_1: To use the memory address 1 + * + * @note It is not allowed to modify the Base Address of a target Memory when + * this target is involved in the current transfer. ie. If the DMA Stream + * is currently transferring to/from Memory 1, then it not possible to + * modify Base address of Memory 1, but it is possible to modify Base + * address of Memory 0. + * To know which Memory is currently used, you can use the function + * DMA_GetCurrentMemoryTarget(). + * + * @retval None + */ +void DMA_MemoryTargetConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t MemoryBaseAddr, + uint32_t DMA_MemoryTarget) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_DMA_CURRENT_MEM(DMA_MemoryTarget)); + + /* Check the Memory target to be configured */ + if (DMA_MemoryTarget != DMA_Memory_0) + { + /* Write to DMAy Streamx M1AR */ + DMAy_Streamx->M1AR = MemoryBaseAddr; + } + else + { + /* Write to DMAy Streamx M0AR */ + DMAy_Streamx->M0AR = MemoryBaseAddr; + } +} + +/** + * @brief Returns the current memory target used by double buffer transfer. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @retval The memory target number: 0 for Memory0 or 1 for Memory1. + */ +uint32_t DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + + /* Get the current memory target */ + if ((DMAy_Streamx->CR & DMA_SxCR_CT) != 0) + { + /* Current memory buffer used is Memory 1 */ + tmp = 1; + } + else + { + /* Current memory buffer used is Memory 0 */ + tmp = 0; + } + return tmp; +} +/** + * @} + */ + +/** @defgroup DMA_Group4 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + + This subsection provides functions allowing to + - Check the DMA enable status + - Check the FIFO status + - Configure the DMA Interrupts sources and check or clear the flags or pending bits status. + + 1. DMA Enable status: + After configuring the DMA Stream (DMA_Init() function) and enabling the stream, + it is recommended to check (or wait until) the DMA Stream is effectively enabled. + A Stream may remain disabled if a configuration parameter is wrong. + After disabling a DMA Stream, it is also recommended to check (or wait until) the DMA + Stream is effectively disabled. If a Stream is disabled while a data transfer is ongoing, + the current data will be transferred and the Stream will be effectively disabled only after + this data transfer completion. + To monitor this state it is possible to use the following function: + - FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx); + + 2. FIFO Status: + It is possible to monitor the FIFO status when a transfer is ongoing using the following + function: + - uint32_t DMA_GetFIFOStatus(DMA_Stream_TypeDef* DMAy_Streamx); + + 3. DMA Interrupts and Flags: + The user should identify which mode will be used in his application to manage the + DMA controller events: Polling mode or Interrupt mode. + + Polling Mode + ============= + Each DMA stream can be managed through 4 event Flags: + (x : DMA Stream number ) + 1. DMA_FLAG_FEIFx : to indicate that a FIFO Mode Transfer Error event occurred. + 2. DMA_FLAG_DMEIFx : to indicate that a Direct Mode Transfer Error event occurred. + 3. DMA_FLAG_TEIFx : to indicate that a Transfer Error event occurred. + 4. DMA_FLAG_HTIFx : to indicate that a Half-Transfer Complete event occurred. + 5. DMA_FLAG_TCIFx : to indicate that a Transfer Complete event occurred . + + In this Mode it is advised to use the following functions: + - FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG); + - void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG); + + Interrupt Mode + =============== + Each DMA Stream can be managed through 4 Interrupts: + + Interrupt Source + ---------------- + 1. DMA_IT_FEIFx : specifies the interrupt source for the FIFO Mode Transfer Error event. + 2. DMA_IT_DMEIFx : specifies the interrupt source for the Direct Mode Transfer Error event. + 3. DMA_IT_TEIFx : specifies the interrupt source for the Transfer Error event. + 4. DMA_IT_HTIFx : specifies the interrupt source for the Half-Transfer Complete event. + 5. DMA_IT_TCIFx : specifies the interrupt source for the a Transfer Complete event. + + In this Mode it is advised to use the following functions: + - void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState); + - ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT); + - void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT); + +@endverbatim + * @{ + */ + +/** + * @brief Returns the status of EN bit for the specified DMAy Streamx. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * + * @note After configuring the DMA Stream (DMA_Init() function) and enabling + * the stream, it is recommended to check (or wait until) the DMA Stream + * is effectively enabled. A Stream may remain disabled if a configuration + * parameter is wrong. + * After disabling a DMA Stream, it is also recommended to check (or wait + * until) the DMA Stream is effectively disabled. If a Stream is disabled + * while a data transfer is ongoing, the current data will be transferred + * and the Stream will be effectively disabled only after the transfer + * of this single data is finished. + * + * @retval Current state of the DMAy Streamx (ENABLE or DISABLE). + */ +FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx) +{ + FunctionalState state = DISABLE; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + + if ((DMAy_Streamx->CR & (uint32_t)DMA_SxCR_EN) != 0) + { + /* The selected DMAy Streamx EN bit is set (DMA is still transferring) */ + state = ENABLE; + } + else + { + /* The selected DMAy Streamx EN bit is cleared (DMA is disabled and + all transfers are complete) */ + state = DISABLE; + } + return state; +} + +/** + * @brief Returns the current DMAy Streamx FIFO filled level. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @retval The FIFO filling state. + * - DMA_FIFOStatus_Less1QuarterFull: when FIFO is less than 1 quarter-full + * and not empty. + * - DMA_FIFOStatus_1QuarterFull: if more than 1 quarter-full. + * - DMA_FIFOStatus_HalfFull: if more than 1 half-full. + * - DMA_FIFOStatus_3QuartersFull: if more than 3 quarters-full. + * - DMA_FIFOStatus_Empty: when FIFO is empty + * - DMA_FIFOStatus_Full: when FIFO is full + */ +uint32_t DMA_GetFIFOStatus(DMA_Stream_TypeDef* DMAy_Streamx) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + + /* Get the FIFO level bits */ + tmpreg = (uint32_t)((DMAy_Streamx->FCR & DMA_SxFCR_FS)); + + return tmpreg; +} + +/** + * @brief Checks whether the specified DMAy Streamx flag is set or not. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param DMA_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg DMA_FLAG_TCIFx: Streamx transfer complete flag + * @arg DMA_FLAG_HTIFx: Streamx half transfer complete flag + * @arg DMA_FLAG_TEIFx: Streamx transfer error flag + * @arg DMA_FLAG_DMEIFx: Streamx direct mode error flag + * @arg DMA_FLAG_FEIFx: Streamx FIFO error flag + * Where x can be 0 to 7 to select the DMA Stream. + * @retval The new state of DMA_FLAG (SET or RESET). + */ +FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG) +{ + FlagStatus bitstatus = RESET; + DMA_TypeDef* DMAy; + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_DMA_GET_FLAG(DMA_FLAG)); + + /* Determine the DMA to which belongs the stream */ + if (DMAy_Streamx < DMA2_Stream0) + { + /* DMAy_Streamx belongs to DMA1 */ + DMAy = DMA1; + } + else + { + /* DMAy_Streamx belongs to DMA2 */ + DMAy = DMA2; + } + + /* Check if the flag is in HISR or LISR */ + if ((DMA_FLAG & HIGH_ISR_MASK) != (uint32_t)RESET) + { + /* Get DMAy HISR register value */ + tmpreg = DMAy->HISR; + } + else + { + /* Get DMAy LISR register value */ + tmpreg = DMAy->LISR; + } + + /* Mask the reserved bits */ + tmpreg &= (uint32_t)RESERVED_MASK; + + /* Check the status of the specified DMA flag */ + if ((tmpreg & DMA_FLAG) != (uint32_t)RESET) + { + /* DMA_FLAG is set */ + bitstatus = SET; + } + else + { + /* DMA_FLAG is reset */ + bitstatus = RESET; + } + + /* Return the DMA_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the DMAy Streamx's pending flags. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param DMA_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCIFx: Streamx transfer complete flag + * @arg DMA_FLAG_HTIFx: Streamx half transfer complete flag + * @arg DMA_FLAG_TEIFx: Streamx transfer error flag + * @arg DMA_FLAG_DMEIFx: Streamx direct mode error flag + * @arg DMA_FLAG_FEIFx: Streamx FIFO error flag + * Where x can be 0 to 7 to select the DMA Stream. + * @retval None + */ +void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG) +{ + DMA_TypeDef* DMAy; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_DMA_CLEAR_FLAG(DMA_FLAG)); + + /* Determine the DMA to which belongs the stream */ + if (DMAy_Streamx < DMA2_Stream0) + { + /* DMAy_Streamx belongs to DMA1 */ + DMAy = DMA1; + } + else + { + /* DMAy_Streamx belongs to DMA2 */ + DMAy = DMA2; + } + + /* Check if LIFCR or HIFCR register is targeted */ + if ((DMA_FLAG & HIGH_ISR_MASK) != (uint32_t)RESET) + { + /* Set DMAy HIFCR register clear flag bits */ + DMAy->HIFCR = (uint32_t)(DMA_FLAG & RESERVED_MASK); + } + else + { + /* Set DMAy LIFCR register clear flag bits */ + DMAy->LIFCR = (uint32_t)(DMA_FLAG & RESERVED_MASK); + } +} + +/** + * @brief Enables or disables the specified DMAy Streamx interrupts. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param DMA_IT: specifies the DMA interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask + * @arg DMA_IT_HT: Half transfer complete interrupt mask + * @arg DMA_IT_TE: Transfer error interrupt mask + * @arg DMA_IT_FE: FIFO error interrupt mask + * @param NewState: new state of the specified DMA interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_DMA_CONFIG_IT(DMA_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Check if the DMA_IT parameter contains a FIFO interrupt */ + if ((DMA_IT & DMA_IT_FE) != 0) + { + if (NewState != DISABLE) + { + /* Enable the selected DMA FIFO interrupts */ + DMAy_Streamx->FCR |= (uint32_t)DMA_IT_FE; + } + else + { + /* Disable the selected DMA FIFO interrupts */ + DMAy_Streamx->FCR &= ~(uint32_t)DMA_IT_FE; + } + } + + /* Check if the DMA_IT parameter contains a Transfer interrupt */ + if (DMA_IT != DMA_IT_FE) + { + if (NewState != DISABLE) + { + /* Enable the selected DMA transfer interrupts */ + DMAy_Streamx->CR |= (uint32_t)(DMA_IT & TRANSFER_IT_ENABLE_MASK); + } + else + { + /* Disable the selected DMA transfer interrupts */ + DMAy_Streamx->CR &= ~(uint32_t)(DMA_IT & TRANSFER_IT_ENABLE_MASK); + } + } +} + +/** + * @brief Checks whether the specified DMAy Streamx interrupt has occurred or not. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param DMA_IT: specifies the DMA interrupt source to check. + * This parameter can be one of the following values: + * @arg DMA_IT_TCIFx: Streamx transfer complete interrupt + * @arg DMA_IT_HTIFx: Streamx half transfer complete interrupt + * @arg DMA_IT_TEIFx: Streamx transfer error interrupt + * @arg DMA_IT_DMEIFx: Streamx direct mode error interrupt + * @arg DMA_IT_FEIFx: Streamx FIFO error interrupt + * Where x can be 0 to 7 to select the DMA Stream. + * @retval The new state of DMA_IT (SET or RESET). + */ +ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT) +{ + ITStatus bitstatus = RESET; + DMA_TypeDef* DMAy; + uint32_t tmpreg = 0, enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_DMA_GET_IT(DMA_IT)); + + /* Determine the DMA to which belongs the stream */ + if (DMAy_Streamx < DMA2_Stream0) + { + /* DMAy_Streamx belongs to DMA1 */ + DMAy = DMA1; + } + else + { + /* DMAy_Streamx belongs to DMA2 */ + DMAy = DMA2; + } + + /* Check if the interrupt enable bit is in the CR or FCR register */ + if ((DMA_IT & TRANSFER_IT_MASK) != (uint32_t)RESET) + { + /* Get the interrupt enable position mask in CR register */ + tmpreg = (uint32_t)((DMA_IT >> 11) & TRANSFER_IT_ENABLE_MASK); + + /* Check the enable bit in CR register */ + enablestatus = (uint32_t)(DMAy_Streamx->CR & tmpreg); + } + else + { + /* Check the enable bit in FCR register */ + enablestatus = (uint32_t)(DMAy_Streamx->FCR & DMA_IT_FE); + } + + /* Check if the interrupt pending flag is in LISR or HISR */ + if ((DMA_IT & HIGH_ISR_MASK) != (uint32_t)RESET) + { + /* Get DMAy HISR register value */ + tmpreg = DMAy->HISR ; + } + else + { + /* Get DMAy LISR register value */ + tmpreg = DMAy->LISR ; + } + + /* mask all reserved bits */ + tmpreg &= (uint32_t)RESERVED_MASK; + + /* Check the status of the specified DMA interrupt */ + if (((tmpreg & DMA_IT) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET)) + { + /* DMA_IT is set */ + bitstatus = SET; + } + else + { + /* DMA_IT is reset */ + bitstatus = RESET; + } + + /* Return the DMA_IT status */ + return bitstatus; +} + +/** + * @brief Clears the DMAy Streamx's interrupt pending bits. + * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 + * to 7 to select the DMA Stream. + * @param DMA_IT: specifies the DMA interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TCIFx: Streamx transfer complete interrupt + * @arg DMA_IT_HTIFx: Streamx half transfer complete interrupt + * @arg DMA_IT_TEIFx: Streamx transfer error interrupt + * @arg DMA_IT_DMEIFx: Streamx direct mode error interrupt + * @arg DMA_IT_FEIFx: Streamx FIFO error interrupt + * Where x can be 0 to 7 to select the DMA Stream. + * @retval None + */ +void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT) +{ + DMA_TypeDef* DMAy; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); + assert_param(IS_DMA_CLEAR_IT(DMA_IT)); + + /* Determine the DMA to which belongs the stream */ + if (DMAy_Streamx < DMA2_Stream0) + { + /* DMAy_Streamx belongs to DMA1 */ + DMAy = DMA1; + } + else + { + /* DMAy_Streamx belongs to DMA2 */ + DMAy = DMA2; + } + + /* Check if LIFCR or HIFCR register is targeted */ + if ((DMA_IT & HIGH_ISR_MASK) != (uint32_t)RESET) + { + /* Set DMAy HIFCR register clear interrupt bits */ + DMAy->HIFCR = (uint32_t)(DMA_IT & RESERVED_MASK); + } + else + { + /* Set DMAy LIFCR register clear interrupt bits */ + DMAy->LIFCR = (uint32_t)(DMA_IT & RESERVED_MASK); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c new file mode 100644 index 0000000..f1cf7c9 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c @@ -0,0 +1,306 @@ +/** + ****************************************************************************** + * @file stm32f4xx_exti.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the EXTI peripheral: + * - Initialization and Configuration + * - Interrupts and flags management + * + * @verbatim + * + * =================================================================== + * EXTI features + * =================================================================== + * + * External interrupt/event lines are mapped as following: + * 1- All available GPIO pins are connected to the 16 external + * interrupt/event lines from EXTI0 to EXTI15. + * 2- EXTI line 16 is connected to the PVD Output + * 3- EXTI line 17 is connected to the RTC Alarm event + * 4- EXTI line 18 is connected to the USB OTG FS Wakeup from suspend event + * 5- EXTI line 19 is connected to the Ethernet Wakeup event + * 6- EXTI line 20 is connected to the USB OTG HS (configured in FS) Wakeup event + * 7- EXTI line 21 is connected to the RTC Tamper and Time Stamp events + * 8- EXTI line 22 is connected to the RTC Wakeup event + * + * =================================================================== + * How to use this driver + * =================================================================== + * + * In order to use an I/O pin as an external interrupt source, follow + * steps below: + * 1- Configure the I/O in input mode using GPIO_Init() + * 2- Select the input source pin for the EXTI line using SYSCFG_EXTILineConfig() + * 3- Select the mode(interrupt, event) and configure the trigger + * selection (Rising, falling or both) using EXTI_Init() + * 4- Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init() + * + * @note SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx + * registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_exti.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup EXTI + * @brief EXTI driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +#define EXTI_LINENONE ((uint32_t)0x00000) /* No interrupt selected */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup EXTI_Private_Functions + * @{ + */ + +/** @defgroup EXTI_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the EXTI peripheral registers to their default reset values. + * @param None + * @retval None + */ +void EXTI_DeInit(void) +{ + EXTI->IMR = 0x00000000; + EXTI->EMR = 0x00000000; + EXTI->RTSR = 0x00000000; + EXTI->FTSR = 0x00000000; + EXTI->PR = 0x007FFFFF; +} + +/** + * @brief Initializes the EXTI peripheral according to the specified + * parameters in the EXTI_InitStruct. + * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure + * that contains the configuration information for the EXTI peripheral. + * @retval None + */ +void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode)); + assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger)); + assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line)); + assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd)); + + tmp = (uint32_t)EXTI_BASE; + + if (EXTI_InitStruct->EXTI_LineCmd != DISABLE) + { + /* Clear EXTI line configuration */ + EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line; + EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line; + + tmp += EXTI_InitStruct->EXTI_Mode; + + *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; + + /* Clear Rising Falling edge configuration */ + EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line; + EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line; + + /* Select the trigger for the selected external interrupts */ + if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling) + { + /* Rising Falling edge */ + EXTI->RTSR |= EXTI_InitStruct->EXTI_Line; + EXTI->FTSR |= EXTI_InitStruct->EXTI_Line; + } + else + { + tmp = (uint32_t)EXTI_BASE; + tmp += EXTI_InitStruct->EXTI_Trigger; + + *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; + } + } + else + { + tmp += EXTI_InitStruct->EXTI_Mode; + + /* Disable the selected external lines */ + *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line; + } +} + +/** + * @brief Fills each EXTI_InitStruct member with its reset value. + * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct) +{ + EXTI_InitStruct->EXTI_Line = EXTI_LINENONE; + EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling; + EXTI_InitStruct->EXTI_LineCmd = DISABLE; +} + +/** + * @brief Generates a Software interrupt on selected EXTI line. + * @param EXTI_Line: specifies the EXTI line on which the software interrupt + * will be generated. + * This parameter can be any combination of EXTI_Linex where x can be (0..22) + * @retval None + */ +void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_EXTI_LINE(EXTI_Line)); + + EXTI->SWIER |= EXTI_Line; +} + +/** + * @} + */ + +/** @defgroup EXTI_Group2 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Checks whether the specified EXTI line flag is set or not. + * @param EXTI_Line: specifies the EXTI line flag to check. + * This parameter can be EXTI_Linex where x can be(0..22) + * @retval The new state of EXTI_Line (SET or RESET). + */ +FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_GET_EXTI_LINE(EXTI_Line)); + + if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the EXTI's line pending flags. + * @param EXTI_Line: specifies the EXTI lines flags to clear. + * This parameter can be any combination of EXTI_Linex where x can be (0..22) + * @retval None + */ +void EXTI_ClearFlag(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_EXTI_LINE(EXTI_Line)); + + EXTI->PR = EXTI_Line; +} + +/** + * @brief Checks whether the specified EXTI line is asserted or not. + * @param EXTI_Line: specifies the EXTI line to check. + * This parameter can be EXTI_Linex where x can be(0..22) + * @retval The new state of EXTI_Line (SET or RESET). + */ +ITStatus EXTI_GetITStatus(uint32_t EXTI_Line) +{ + ITStatus bitstatus = RESET; + uint32_t enablestatus = 0; + /* Check the parameters */ + assert_param(IS_GET_EXTI_LINE(EXTI_Line)); + + enablestatus = EXTI->IMR & EXTI_Line; + if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the EXTI's line pending bits. + * @param EXTI_Line: specifies the EXTI lines to clear. + * This parameter can be any combination of EXTI_Linex where x can be (0..22) + * @retval None + */ +void EXTI_ClearITPendingBit(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_EXTI_LINE(EXTI_Line)); + + EXTI->PR = EXTI_Line; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_flash.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_flash.c new file mode 100644 index 0000000..280b1d3 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_flash.c @@ -0,0 +1,1056 @@ +/** + ****************************************************************************** + * @file stm32f4xx_flash.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the FLASH peripheral: + * - FLASH Interface configuration + * - FLASH Memory Programming + * - Option Bytes Programming + * - Interrupts and flags management + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + * + * This driver provides functions to configure and program the FLASH + * memory of all STM32F4xx devices. + * These functions are split in 4 groups: + * + * 1. FLASH Interface configuration functions: this group includes the + * management of the following features: + * - Set the latency + * - Enable/Disable the prefetch buffer + * - Enable/Disable the Instruction cache and the Data cache + * - Reset the Instruction cache and the Data cache + * + * 2. FLASH Memory Programming functions: this group includes all needed + * functions to erase and program the main memory: + * - Lock and Unlock the FLASH interface + * - Erase function: Erase sector, erase all sectors + * - Program functions: byte, half word, word and double word + * + * 3. Option Bytes Programming functions: this group includes all needed + * functions to manage the Option Bytes: + * - Set/Reset the write protection + * - Set the Read protection Level + * - Set the BOR level + * - Program the user Option Bytes + * - Launch the Option Bytes loader + * + * 4. Interrupts and flags management functions: this group + * includes all needed functions to: + * - Enable/Disable the FLASH interrupt sources + * - Get flags status + * - Clear flags + * - Get FLASH operation status + * - Wait for last FLASH operation + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_flash.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup FLASH + * @brief FLASH driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define SECTOR_MASK ((uint32_t)0xFFFFFF07) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup FLASH_Private_Functions + * @{ + */ + +/** @defgroup FLASH_Group1 FLASH Interface configuration functions + * @brief FLASH Interface configuration functions + * + +@verbatim + =============================================================================== + FLASH Interface configuration functions + =============================================================================== + + This group includes the following functions: + - void FLASH_SetLatency(uint32_t FLASH_Latency) + To correctly read data from FLASH memory, the number of wait states (LATENCY) + must be correctly programmed according to the frequency of the CPU clock + (HCLK) and the supply voltage of the device. + +-------------------------------------------------------------------------------------+ + | Latency | HCLK clock frequency (MHz) | + | |---------------------------------------------------------------------| + | | voltage range | voltage range | voltage range | voltage range | + | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V | + |---------------|----------------|----------------|-----------------|-----------------| + |0WS(1CPU cycle)|0 < HCLK <= 30 |0 < HCLK <= 24 |0 < HCLK <= 18 |0 < HCLK <= 16 | + |---------------|----------------|----------------|-----------------|-----------------| + |1WS(2CPU cycle)|30 < HCLK <= 60 |24 < HCLK <= 48 |18 < HCLK <= 36 |16 < HCLK <= 32 | + |---------------|----------------|----------------|-----------------|-----------------| + |2WS(3CPU cycle)|60 < HCLK <= 90 |48 < HCLK <= 72 |36 < HCLK <= 54 |32 < HCLK <= 48 | + |---------------|----------------|----------------|-----------------|-----------------| + |3WS(4CPU cycle)|90 < HCLK <= 120|72 < HCLK <= 96 |54 < HCLK <= 72 |48 < HCLK <= 64 | + |---------------|----------------|----------------|-----------------|-----------------| + |4WS(5CPU cycle)|120< HCLK <= 150|96 < HCLK <= 120|72 < HCLK <= 90 |64 < HCLK <= 80 | + |---------------|----------------|----------------|-----------------|-----------------| + |5WS(6CPU cycle)|120< HCLK <= 168|120< HCLK <= 144|90 < HCLK <= 108 |80 < HCLK <= 96 | + |---------------|----------------|----------------|-----------------|-----------------| + |6WS(7CPU cycle)| NA |144< HCLK <= 168|108 < HCLK <= 120|96 < HCLK <= 112 | + |---------------|----------------|----------------|-----------------|-----------------| + |7WS(8CPU cycle)| NA | NA |120 < HCLK <= 138|112 < HCLK <= 120| + |***************|****************|****************|*****************|*****************|*****************************+ + | | voltage range | voltage range | voltage range | voltage range | voltage range 2.7 V - 3.6 V | + | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V | with External Vpp = 9V | + |---------------|----------------|----------------|-----------------|-----------------|-----------------------------| + |Max Parallelism| x32 | x16 | x8 | x64 | + |---------------|----------------|----------------|-----------------|-----------------|-----------------------------| + |PSIZE[1:0] | 10 | 01 | 00 | 11 | + +-------------------------------------------------------------------------------------------------------------------+ + @note When VOS bit (in PWR_CR register) is reset to '0, the maximum value of HCLK is 144 MHz. + You can use PWR_MainRegulatorModeConfig() function to set or reset this bit. + + - void FLASH_PrefetchBufferCmd(FunctionalState NewState) + - void FLASH_InstructionCacheCmd(FunctionalState NewState) + - void FLASH_DataCacheCmd(FunctionalState NewState) + - void FLASH_InstructionCacheReset(void) + - void FLASH_DataCacheReset(void) + + The unlock sequence is not needed for these functions. + +@endverbatim + * @{ + */ + +/** + * @brief Sets the code latency value. + * @param FLASH_Latency: specifies the FLASH Latency value. + * This parameter can be one of the following values: + * @arg FLASH_Latency_0: FLASH Zero Latency cycle + * @arg FLASH_Latency_1: FLASH One Latency cycle + * @arg FLASH_Latency_2: FLASH Two Latency cycles + * @arg FLASH_Latency_3: FLASH Three Latency cycles + * @arg FLASH_Latency_4: FLASH Four Latency cycles + * @arg FLASH_Latency_5: FLASH Five Latency cycles + * @arg FLASH_Latency_6: FLASH Six Latency cycles + * @arg FLASH_Latency_7: FLASH Seven Latency cycles + * @retval None + */ +void FLASH_SetLatency(uint32_t FLASH_Latency) +{ + /* Check the parameters */ + assert_param(IS_FLASH_LATENCY(FLASH_Latency)); + + /* Perform Byte access to FLASH_ACR[8:0] to set the Latency value */ + *(__IO uint8_t *)ACR_BYTE0_ADDRESS = (uint8_t)FLASH_Latency; +} + +/** + * @brief Enables or disables the Prefetch Buffer. + * @param NewState: new state of the Prefetch Buffer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FLASH_PrefetchBufferCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Enable or disable the Prefetch Buffer */ + if(NewState != DISABLE) + { + FLASH->ACR |= FLASH_ACR_PRFTEN; + } + else + { + FLASH->ACR &= (~FLASH_ACR_PRFTEN); + } +} + +/** + * @brief Enables or disables the Instruction Cache feature. + * @param NewState: new state of the Instruction Cache. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FLASH_InstructionCacheCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState != DISABLE) + { + FLASH->ACR |= FLASH_ACR_ICEN; + } + else + { + FLASH->ACR &= (~FLASH_ACR_ICEN); + } +} + +/** + * @brief Enables or disables the Data Cache feature. + * @param NewState: new state of the Data Cache. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FLASH_DataCacheCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState != DISABLE) + { + FLASH->ACR |= FLASH_ACR_DCEN; + } + else + { + FLASH->ACR &= (~FLASH_ACR_DCEN); + } +} + +/** + * @brief Resets the Instruction Cache. + * @note This function must be used only when the Instruction Cache is disabled. + * @param None + * @retval None + */ +void FLASH_InstructionCacheReset(void) +{ + FLASH->ACR |= FLASH_ACR_ICRST; +} + +/** + * @brief Resets the Data Cache. + * @note This function must be used only when the Data Cache is disabled. + * @param None + * @retval None + */ +void FLASH_DataCacheReset(void) +{ + FLASH->ACR |= FLASH_ACR_DCRST; +} + +/** + * @} + */ + +/** @defgroup FLASH_Group2 FLASH Memory Programming functions + * @brief FLASH Memory Programming functions + * +@verbatim + =============================================================================== + FLASH Memory Programming functions + =============================================================================== + + This group includes the following functions: + - void FLASH_Unlock(void) + - void FLASH_Lock(void) + - FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange) + - FLASH_Status FLASH_EraseAllSectors(uint8_t VoltageRange) + - FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data) + - FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data) + - FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) + - FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data) + + Any operation of erase or program should follow these steps: + 1. Call the FLASH_Unlock() function to enable the FLASH control register access + + 2. Call the desired function to erase sector(s) or program data + + 3. Call the FLASH_Lock() function to disable the FLASH control register access + (recommended to protect the FLASH memory against possible unwanted operation) + +@endverbatim + * @{ + */ + +/** + * @brief Unlocks the FLASH control register access + * @param None + * @retval None + */ +void FLASH_Unlock(void) +{ + if((FLASH->CR & FLASH_CR_LOCK) != RESET) + { + /* Authorize the FLASH Registers access */ + FLASH->KEYR = FLASH_KEY1; + FLASH->KEYR = FLASH_KEY2; + } +} + +/** + * @brief Locks the FLASH control register access + * @param None + * @retval None + */ +void FLASH_Lock(void) +{ + /* Set the LOCK Bit to lock the FLASH Registers access */ + FLASH->CR |= FLASH_CR_LOCK; +} + +/** + * @brief Erases a specified FLASH Sector. + * + * @param FLASH_Sector: The Sector number to be erased. + * This parameter can be a value between FLASH_Sector_0 and FLASH_Sector_11 + * + * @param VoltageRange: The device voltage range which defines the erase parallelism. + * This parameter can be one of the following values: + * @arg VoltageRange_1: when the device voltage range is 1.8V to 2.1V, + * the operation will be done by byte (8-bit) + * @arg VoltageRange_2: when the device voltage range is 2.1V to 2.7V, + * the operation will be done by half word (16-bit) + * @arg VoltageRange_3: when the device voltage range is 2.7V to 3.6V, + * the operation will be done by word (32-bit) + * @arg VoltageRange_4: when the device voltage range is 2.7V to 3.6V + External Vpp, + * the operation will be done by double word (64-bit) + * + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, + * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. + */ +FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange) +{ + uint32_t tmp_psize = 0x0; + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_SECTOR(FLASH_Sector)); + assert_param(IS_VOLTAGERANGE(VoltageRange)); + + if(VoltageRange == VoltageRange_1) + { + tmp_psize = FLASH_PSIZE_BYTE; + } + else if(VoltageRange == VoltageRange_2) + { + tmp_psize = FLASH_PSIZE_HALF_WORD; + } + else if(VoltageRange == VoltageRange_3) + { + tmp_psize = FLASH_PSIZE_WORD; + } + else + { + tmp_psize = FLASH_PSIZE_DOUBLE_WORD; + } + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase the sector */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= tmp_psize; + FLASH->CR &= SECTOR_MASK; + FLASH->CR |= FLASH_CR_SER | FLASH_Sector; + FLASH->CR |= FLASH_CR_STRT; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + /* if the erase operation is completed, disable the SER Bit */ + FLASH->CR &= (~FLASH_CR_SER); + FLASH->CR &= SECTOR_MASK; + } + /* Return the Erase Status */ + return status; +} + +/** + * @brief Erases all FLASH Sectors. + * + * @param VoltageRange: The device voltage range which defines the erase parallelism. + * This parameter can be one of the following values: + * @arg VoltageRange_1: when the device voltage range is 1.8V to 2.1V, + * the operation will be done by byte (8-bit) + * @arg VoltageRange_2: when the device voltage range is 2.1V to 2.7V, + * the operation will be done by half word (16-bit) + * @arg VoltageRange_3: when the device voltage range is 2.7V to 3.6V, + * the operation will be done by word (32-bit) + * @arg VoltageRange_4: when the device voltage range is 2.7V to 3.6V + External Vpp, + * the operation will be done by double word (64-bit) + * + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, + * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. + */ +FLASH_Status FLASH_EraseAllSectors(uint8_t VoltageRange) +{ + uint32_t tmp_psize = 0x0; + FLASH_Status status = FLASH_COMPLETE; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + assert_param(IS_VOLTAGERANGE(VoltageRange)); + + if(VoltageRange == VoltageRange_1) + { + tmp_psize = FLASH_PSIZE_BYTE; + } + else if(VoltageRange == VoltageRange_2) + { + tmp_psize = FLASH_PSIZE_HALF_WORD; + } + else if(VoltageRange == VoltageRange_3) + { + tmp_psize = FLASH_PSIZE_WORD; + } + else + { + tmp_psize = FLASH_PSIZE_DOUBLE_WORD; + } + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase all sectors */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= tmp_psize; + FLASH->CR |= FLASH_CR_MER; + FLASH->CR |= FLASH_CR_STRT; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + /* if the erase operation is completed, disable the MER Bit */ + FLASH->CR &= (~FLASH_CR_MER); + + } + /* Return the Erase Status */ + return status; +} + +/** + * @brief Programs a double word (64-bit) at a specified address. + * @note This function must be used when the device voltage range is from + * 2.7V to 3.6V and an External Vpp is present. + * @param Address: specifies the address to be programmed. + * @param Data: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, + * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. + */ +FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new data */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD; + FLASH->CR |= FLASH_CR_PG; + + *(__IO uint64_t*)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + /* if the program operation is completed, disable the PG Bit */ + FLASH->CR &= (~FLASH_CR_PG); + } + /* Return the Program Status */ + return status; +} + +/** + * @brief Programs a word (32-bit) at a specified address. + * @param Address: specifies the address to be programmed. + * This parameter can be any address in Program memory zone or in OTP zone. + * @note This function must be used when the device voltage range is from 2.7V to 3.6V. + * @param Data: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, + * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. + */ +FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new data */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= FLASH_PSIZE_WORD; + FLASH->CR |= FLASH_CR_PG; + + *(__IO uint32_t*)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + /* if the program operation is completed, disable the PG Bit */ + FLASH->CR &= (~FLASH_CR_PG); + } + /* Return the Program Status */ + return status; +} + +/** + * @brief Programs a half word (16-bit) at a specified address. + * @note This function must be used when the device voltage range is from 2.1V to 3.6V. + * @param Address: specifies the address to be programmed. + * This parameter can be any address in Program memory zone or in OTP zone. + * @param Data: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, + * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. + */ +FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new data */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= FLASH_PSIZE_HALF_WORD; + FLASH->CR |= FLASH_CR_PG; + + *(__IO uint16_t*)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + /* if the program operation is completed, disable the PG Bit */ + FLASH->CR &= (~FLASH_CR_PG); + } + /* Return the Program Status */ + return status; +} + +/** + * @brief Programs a byte (8-bit) at a specified address. + * @note This function can be used within all the device supply voltage ranges. + * @param Address: specifies the address to be programmed. + * This parameter can be any address in Program memory zone or in OTP zone. + * @param Data: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, + * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. + */ +FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new data */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= FLASH_PSIZE_BYTE; + FLASH->CR |= FLASH_CR_PG; + + *(__IO uint8_t*)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + /* if the program operation is completed, disable the PG Bit */ + FLASH->CR &= (~FLASH_CR_PG); + } + + /* Return the Program Status */ + return status; +} + +/** + * @} + */ + +/** @defgroup FLASH_Group3 Option Bytes Programming functions + * @brief Option Bytes Programming functions + * +@verbatim + =============================================================================== + Option Bytes Programming functions + =============================================================================== + + This group includes the following functions: + - void FLASH_OB_Unlock(void) + - void FLASH_OB_Lock(void) + - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) + - void FLASH_OB_RDPConfig(uint8_t OB_RDP) + - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) + - void FLASH_OB_BORConfig(uint8_t OB_BOR) + - FLASH_Status FLASH_ProgramOTP(uint32_t Address, uint32_t Data) + - FLASH_Status FLASH_OB_Launch(void) + - uint32_t FLASH_OB_GetUser(void) + - uint8_t FLASH_OB_GetWRP(void) + - uint8_t FLASH_OB_GetRDP(void) + - uint8_t FLASH_OB_GetBOR(void) + + Any operation of erase or program should follow these steps: + 1. Call the FLASH_OB_Unlock() function to enable the FLASH option control register access + + 2. Call one or several functions to program the desired Option Bytes: + - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) => to Enable/Disable + the desired sector write protection + - void FLASH_OB_RDPConfig(uint8_t OB_RDP) => to set the desired read Protection Level + - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) => to configure + the user Option Bytes. + - void FLASH_OB_BORConfig(uint8_t OB_BOR) => to set the BOR Level + + 3. Once all needed Option Bytes to be programmed are correctly written, call the + FLASH_OB_Launch() function to launch the Option Bytes programming process. + + @note When changing the IWDG mode from HW to SW or from SW to HW, a system + reset is needed to make the change effective. + + 4. Call the FLASH_OB_Lock() function to disable the FLASH option control register + access (recommended to protect the Option Bytes against possible unwanted operations) + +@endverbatim + * @{ + */ + +/** + * @brief Unlocks the FLASH Option Control Registers access. + * @param None + * @retval None + */ +void FLASH_OB_Unlock(void) +{ + if((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET) + { + /* Authorizes the Option Byte register programming */ + FLASH->OPTKEYR = FLASH_OPT_KEY1; + FLASH->OPTKEYR = FLASH_OPT_KEY2; + } +} + +/** + * @brief Locks the FLASH Option Control Registers access. + * @param None + * @retval None + */ +void FLASH_OB_Lock(void) +{ + /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */ + FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK; +} + +/** + * @brief Enables or disables the write protection of the desired sectors + * @param OB_WRP: specifies the sector(s) to be write protected or unprotected. + * This parameter can be one of the following values: + * @arg OB_WRP: A value between OB_WRP_Sector0 and OB_WRP_Sector11 + * @arg OB_WRP_Sector_All + * @param Newstate: new state of the Write Protection. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_OB_WRP(OB_WRP)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + status = FLASH_WaitForLastOperation(); + + if(status == FLASH_COMPLETE) + { + if(NewState != DISABLE) + { + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS &= (~OB_WRP); + } + else + { + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)OB_WRP; + } + } +} + +/** + * @brief Sets the read protection level. + * @param OB_RDP: specifies the read protection level. + * This parameter can be one of the following values: + * @arg OB_RDP_Level_0: No protection + * @arg OB_RDP_Level_1: Read protection of the memory + * @arg OB_RDP_Level_2: Full chip protection + * + * !!!Warning!!! When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0 + * + * @retval None + */ +void FLASH_OB_RDPConfig(uint8_t OB_RDP) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_OB_RDP(OB_RDP)); + + status = FLASH_WaitForLastOperation(); + + if(status == FLASH_COMPLETE) + { + *(__IO uint8_t*)OPTCR_BYTE1_ADDRESS = OB_RDP; + + } +} + +/** + * @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. + * @param OB_IWDG: Selects the IWDG mode + * This parameter can be one of the following values: + * @arg OB_IWDG_SW: Software IWDG selected + * @arg OB_IWDG_HW: Hardware IWDG selected + * @param OB_STOP: Reset event when entering STOP mode. + * This parameter can be one of the following values: + * @arg OB_STOP_NoRST: No reset generated when entering in STOP + * @arg OB_STOP_RST: Reset generated when entering in STOP + * @param OB_STDBY: Reset event when entering Standby mode. + * This parameter can be one of the following values: + * @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY + * @arg OB_STDBY_RST: Reset generated when entering in STANDBY + * @retval None + */ +void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) +{ + uint8_t optiontmp = 0xFF; + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_OB_IWDG_SOURCE(OB_IWDG)); + assert_param(IS_OB_STOP_SOURCE(OB_STOP)); + assert_param(IS_OB_STDBY_SOURCE(OB_STDBY)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + if(status == FLASH_COMPLETE) + { + /* Mask OPTLOCK, OPTSTRT and BOR_LEV bits */ + optiontmp = (uint8_t)((*(__IO uint8_t *)OPTCR_BYTE0_ADDRESS) & (uint8_t)0x0F); + + /* Update User Option Byte */ + *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS = OB_IWDG | (uint8_t)(OB_STDBY | (uint8_t)(OB_STOP | ((uint8_t)optiontmp))); + } +} + +/** + * @brief Sets the BOR Level. + * @param OB_BOR: specifies the Option Bytes BOR Reset Level. + * This parameter can be one of the following values: + * @arg OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V + * @arg OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V + * @arg OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V + * @arg OB_BOR_OFF: Supply voltage ranges from 1.62 to 2.1 V + * @retval None + */ +void FLASH_OB_BORConfig(uint8_t OB_BOR) +{ + /* Check the parameters */ + assert_param(IS_OB_BOR(OB_BOR)); + + /* Set the BOR Level */ + *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS &= (~FLASH_OPTCR_BOR_LEV); + *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= OB_BOR; + +} + +/** + * @brief Launch the option byte loading. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, + * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. + */ +FLASH_Status FLASH_OB_Launch(void) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Set the OPTSTRT bit in OPTCR register */ + *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= FLASH_OPTCR_OPTSTRT; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(); + + return status; +} + +/** + * @brief Returns the FLASH User Option Bytes values. + * @param None + * @retval The FLASH User Option Bytes values: IWDG_SW(Bit0), RST_STOP(Bit1) + * and RST_STDBY(Bit2). + */ +uint8_t FLASH_OB_GetUser(void) +{ + /* Return the User Option Byte */ + return (uint8_t)(FLASH->OPTCR >> 5); +} + +/** + * @brief Returns the FLASH Write Protection Option Bytes value. + * @param None + * @retval The FLASH Write Protection Option Bytes value + */ +uint16_t FLASH_OB_GetWRP(void) +{ + /* Return the FLASH write protection Register value */ + return (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS)); +} + +/** + * @brief Returns the FLASH Read Protection level. + * @param None + * @retval FLASH ReadOut Protection Status: + * - SET, when OB_RDP_Level_1 or OB_RDP_Level_2 is set + * - RESET, when OB_RDP_Level_0 is set + */ +FlagStatus FLASH_OB_GetRDP(void) +{ + FlagStatus readstatus = RESET; + + if ((*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS) != (uint8_t)OB_RDP_Level_0)) + { + readstatus = SET; + } + else + { + readstatus = RESET; + } + return readstatus; +} + +/** + * @brief Returns the FLASH BOR level. + * @param None + * @retval The FLASH BOR level: + * - OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V + * - OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V + * - OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V + * - OB_BOR_OFF : Supply voltage ranges from 1.62 to 2.1 V + */ +uint8_t FLASH_OB_GetBOR(void) +{ + /* Return the FLASH BOR level */ + return (uint8_t)(*(__IO uint8_t *)(OPTCR_BYTE0_ADDRESS) & (uint8_t)0x0C); +} + +/** + * @} + */ + +/** @defgroup FLASH_Group4 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified FLASH interrupts. + * @param FLASH_IT: specifies the FLASH interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg FLASH_IT_ERR: FLASH Error Interrupt + * @arg FLASH_IT_EOP: FLASH end of operation Interrupt + * @retval None + */ +void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FLASH_IT(FLASH_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState != DISABLE) + { + /* Enable the interrupt sources */ + FLASH->CR |= FLASH_IT; + } + else + { + /* Disable the interrupt sources */ + FLASH->CR &= ~(uint32_t)FLASH_IT; + } +} + +/** + * @brief Checks whether the specified FLASH flag is set or not. + * @param FLASH_FLAG: specifies the FLASH flag to check. + * This parameter can be one of the following values: + * @arg FLASH_FLAG_EOP: FLASH End of Operation flag + * @arg FLASH_FLAG_OPERR: FLASH operation Error flag + * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag + * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag + * @arg FLASH_FLAG_PGPERR: FLASH Programming Parallelism error flag + * @arg FLASH_FLAG_PGSERR: FLASH Programming Sequence error flag + * @arg FLASH_FLAG_BSY: FLASH Busy flag + * @retval The new state of FLASH_FLAG (SET or RESET). + */ +FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)); + + if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the new state of FLASH_FLAG (SET or RESET) */ + return bitstatus; +} + +/** + * @brief Clears the FLASH's pending flags. + * @param FLASH_FLAG: specifies the FLASH flags to clear. + * This parameter can be any combination of the following values: + * @arg FLASH_FLAG_EOP: FLASH End of Operation flag + * @arg FLASH_FLAG_OPERR: FLASH operation Error flag + * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag + * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag + * @arg FLASH_FLAG_PGPERR: FLASH Programming Parallelism error flag + * @arg FLASH_FLAG_PGSERR: FLASH Programming Sequence error flag + * @retval None + */ +void FLASH_ClearFlag(uint32_t FLASH_FLAG) +{ + /* Check the parameters */ + assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)); + + /* Clear the flags */ + FLASH->SR = FLASH_FLAG; +} + +/** + * @brief Returns the FLASH Status. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, + * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. + */ +FLASH_Status FLASH_GetStatus(void) +{ + FLASH_Status flashstatus = FLASH_COMPLETE; + + if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) + { + flashstatus = FLASH_BUSY; + } + else + { + if((FLASH->SR & FLASH_FLAG_WRPERR) != (uint32_t)0x00) + { + flashstatus = FLASH_ERROR_WRP; + } + else + { + if((FLASH->SR & (uint32_t)0xEF) != (uint32_t)0x00) + { + flashstatus = FLASH_ERROR_PROGRAM; + } + else + { + if((FLASH->SR & FLASH_FLAG_OPERR) != (uint32_t)0x00) + { + flashstatus = FLASH_ERROR_OPERATION; + } + else + { + flashstatus = FLASH_COMPLETE; + } + } + } + } + /* Return the FLASH Status */ + return flashstatus; +} + +/** + * @brief Waits for a FLASH operation to complete. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, + * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. + */ +FLASH_Status FLASH_WaitForLastOperation(void) +{ + __IO FLASH_Status status = FLASH_COMPLETE; + + /* Check for the FLASH Status */ + status = FLASH_GetStatus(); + + /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset. + Even if the FLASH operation fails, the BUSY flag will be reset and an error + flag will be set */ + while(status == FLASH_BUSY) + { + status = FLASH_GetStatus(); + } + /* Return the operation status */ + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_fsmc.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_fsmc.c new file mode 100644 index 0000000..c9780a5 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_fsmc.c @@ -0,0 +1,982 @@ +/** + ****************************************************************************** + * @file stm32f4xx_fsmc.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the FSMC peripheral: + * - Interface with SRAM, PSRAM, NOR and OneNAND memories + * - Interface with NAND memories + * - Interface with 16-bit PC Card compatible memories + * - Interrupts and flags management + * + ****************************************************************************** + + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_fsmc.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup FSMC + * @brief FSMC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* --------------------- FSMC registers bit mask ---------------------------- */ +/* FSMC BCRx Mask */ +#define BCR_MBKEN_SET ((uint32_t)0x00000001) +#define BCR_MBKEN_RESET ((uint32_t)0x000FFFFE) +#define BCR_FACCEN_SET ((uint32_t)0x00000040) + +/* FSMC PCRx Mask */ +#define PCR_PBKEN_SET ((uint32_t)0x00000004) +#define PCR_PBKEN_RESET ((uint32_t)0x000FFFFB) +#define PCR_ECCEN_SET ((uint32_t)0x00000040) +#define PCR_ECCEN_RESET ((uint32_t)0x000FFFBF) +#define PCR_MEMORYTYPE_NAND ((uint32_t)0x00000008) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup FSMC_Private_Functions + * @{ + */ + +/** @defgroup FSMC_Group1 NOR/SRAM Controller functions + * @brief NOR/SRAM Controller functions + * +@verbatim + =============================================================================== + NOR/SRAM Controller functions + =============================================================================== + + The following sequence should be followed to configure the FSMC to interface with + SRAM, PSRAM, NOR or OneNAND memory connected to the NOR/SRAM Bank: + + 1. Enable the clock for the FSMC and associated GPIOs using the following functions: + RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); + + 2. FSMC pins configuration + - Connect the involved FSMC pins to AF12 using the following function + GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FSMC); + - Configure these FSMC pins in alternate function mode by calling the function + GPIO_Init(); + + 3. Declare a FSMC_NORSRAMInitTypeDef structure, for example: + FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; + and fill the FSMC_NORSRAMInitStructure variable with the allowed values of + the structure member. + + 4. Initialize the NOR/SRAM Controller by calling the function + FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); + + 5. Then enable the NOR/SRAM Bank, for example: + FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE); + + 6. At this stage you can read/write from/to the memory connected to the NOR/SRAM Bank. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the FSMC NOR/SRAM Banks registers to their default + * reset values. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1 + * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2 + * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3 + * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4 + * @retval None + */ +void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank) +{ + /* Check the parameter */ + assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank)); + + /* FSMC_Bank1_NORSRAM1 */ + if(FSMC_Bank == FSMC_Bank1_NORSRAM1) + { + FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030DB; + } + /* FSMC_Bank1_NORSRAM2, FSMC_Bank1_NORSRAM3 or FSMC_Bank1_NORSRAM4 */ + else + { + FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030D2; + } + FSMC_Bank1->BTCR[FSMC_Bank + 1] = 0x0FFFFFFF; + FSMC_Bank1E->BWTR[FSMC_Bank] = 0x0FFFFFFF; +} + +/** + * @brief Initializes the FSMC NOR/SRAM Banks according to the specified + * parameters in the FSMC_NORSRAMInitStruct. + * @param FSMC_NORSRAMInitStruct : pointer to a FSMC_NORSRAMInitTypeDef structure + * that contains the configuration information for the FSMC NOR/SRAM + * specified Banks. + * @retval None + */ +void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct) +{ + /* Check the parameters */ + assert_param(IS_FSMC_NORSRAM_BANK(FSMC_NORSRAMInitStruct->FSMC_Bank)); + assert_param(IS_FSMC_MUX(FSMC_NORSRAMInitStruct->FSMC_DataAddressMux)); + assert_param(IS_FSMC_MEMORY(FSMC_NORSRAMInitStruct->FSMC_MemoryType)); + assert_param(IS_FSMC_MEMORY_WIDTH(FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth)); + assert_param(IS_FSMC_BURSTMODE(FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode)); + assert_param(IS_FSMC_ASYNWAIT(FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait)); + assert_param(IS_FSMC_WAIT_POLARITY(FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity)); + assert_param(IS_FSMC_WRAP_MODE(FSMC_NORSRAMInitStruct->FSMC_WrapMode)); + assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive)); + assert_param(IS_FSMC_WRITE_OPERATION(FSMC_NORSRAMInitStruct->FSMC_WriteOperation)); + assert_param(IS_FSMC_WAITE_SIGNAL(FSMC_NORSRAMInitStruct->FSMC_WaitSignal)); + assert_param(IS_FSMC_EXTENDED_MODE(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode)); + assert_param(IS_FSMC_WRITE_BURST(FSMC_NORSRAMInitStruct->FSMC_WriteBurst)); + assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime)); + assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime)); + assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime)); + assert_param(IS_FSMC_TURNAROUND_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration)); + assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision)); + assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency)); + assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode)); + + /* Bank1 NOR/SRAM control register configuration */ + FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] = + (uint32_t)FSMC_NORSRAMInitStruct->FSMC_DataAddressMux | + FSMC_NORSRAMInitStruct->FSMC_MemoryType | + FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth | + FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode | + FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait | + FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity | + FSMC_NORSRAMInitStruct->FSMC_WrapMode | + FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive | + FSMC_NORSRAMInitStruct->FSMC_WriteOperation | + FSMC_NORSRAMInitStruct->FSMC_WaitSignal | + FSMC_NORSRAMInitStruct->FSMC_ExtendedMode | + FSMC_NORSRAMInitStruct->FSMC_WriteBurst; + if(FSMC_NORSRAMInitStruct->FSMC_MemoryType == FSMC_MemoryType_NOR) + { + FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] |= (uint32_t)BCR_FACCEN_SET; + } + /* Bank1 NOR/SRAM timing register configuration */ + FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank+1] = + (uint32_t)FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime << 4) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime << 8) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration << 16) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision << 20) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency << 24) | + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode; + + + /* Bank1 NOR/SRAM timing register for write configuration, if extended mode is used */ + if(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode == FSMC_ExtendedMode_Enable) + { + assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime)); + assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime)); + assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime)); + assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision)); + assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency)); + assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode)); + FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = + (uint32_t)FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime | + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime << 4 )| + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime << 8) | + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision << 20) | + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency << 24) | + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode; + } + else + { + FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = 0x0FFFFFFF; + } +} + +/** + * @brief Fills each FSMC_NORSRAMInitStruct member with its default value. + * @param FSMC_NORSRAMInitStruct: pointer to a FSMC_NORSRAMInitTypeDef structure + * which will be initialized. + * @retval None + */ +void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct) +{ + /* Reset NOR/SRAM Init structure parameters values */ + FSMC_NORSRAMInitStruct->FSMC_Bank = FSMC_Bank1_NORSRAM1; + FSMC_NORSRAMInitStruct->FSMC_DataAddressMux = FSMC_DataAddressMux_Enable; + FSMC_NORSRAMInitStruct->FSMC_MemoryType = FSMC_MemoryType_SRAM; + FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; + FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; + FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; + FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; + FSMC_NORSRAMInitStruct->FSMC_WrapMode = FSMC_WrapMode_Disable; + FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; + FSMC_NORSRAMInitStruct->FSMC_WriteOperation = FSMC_WriteOperation_Enable; + FSMC_NORSRAMInitStruct->FSMC_WaitSignal = FSMC_WaitSignal_Enable; + FSMC_NORSRAMInitStruct->FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; + FSMC_NORSRAMInitStruct->FSMC_WriteBurst = FSMC_WriteBurst_Disable; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime = 0xFF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime = 0xFF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A; +} + +/** + * @brief Enables or disables the specified NOR/SRAM Memory Bank. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1 + * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2 + * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3 + * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4 + * @param NewState: new state of the FSMC_Bank. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState) +{ + assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected NOR/SRAM Bank by setting the PBKEN bit in the BCRx register */ + FSMC_Bank1->BTCR[FSMC_Bank] |= BCR_MBKEN_SET; + } + else + { + /* Disable the selected NOR/SRAM Bank by clearing the PBKEN bit in the BCRx register */ + FSMC_Bank1->BTCR[FSMC_Bank] &= BCR_MBKEN_RESET; + } +} +/** + * @} + */ + +/** @defgroup FSMC_Group2 NAND Controller functions + * @brief NAND Controller functions + * +@verbatim + =============================================================================== + NAND Controller functions + =============================================================================== + + The following sequence should be followed to configure the FSMC to interface with + 8-bit or 16-bit NAND memory connected to the NAND Bank: + + 1. Enable the clock for the FSMC and associated GPIOs using the following functions: + RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); + + 2. FSMC pins configuration + - Connect the involved FSMC pins to AF12 using the following function + GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FSMC); + - Configure these FSMC pins in alternate function mode by calling the function + GPIO_Init(); + + 3. Declare a FSMC_NANDInitTypeDef structure, for example: + FSMC_NANDInitTypeDef FSMC_NANDInitStructure; + and fill the FSMC_NANDInitStructure variable with the allowed values of + the structure member. + + 4. Initialize the NAND Controller by calling the function + FSMC_NANDInit(&FSMC_NANDInitStructure); + + 5. Then enable the NAND Bank, for example: + FSMC_NANDCmd(FSMC_Bank3_NAND, ENABLE); + + 6. At this stage you can read/write from/to the memory connected to the NAND Bank. + +@note To enable the Error Correction Code (ECC), you have to use the function + FSMC_NANDECCCmd(FSMC_Bank3_NAND, ENABLE); + and to get the current ECC value you have to use the function + ECCval = FSMC_GetECC(FSMC_Bank3_NAND); + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the FSMC NAND Banks registers to their default reset values. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @retval None + */ +void FSMC_NANDDeInit(uint32_t FSMC_Bank) +{ + /* Check the parameter */ + assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + /* Set the FSMC_Bank2 registers to their reset values */ + FSMC_Bank2->PCR2 = 0x00000018; + FSMC_Bank2->SR2 = 0x00000040; + FSMC_Bank2->PMEM2 = 0xFCFCFCFC; + FSMC_Bank2->PATT2 = 0xFCFCFCFC; + } + /* FSMC_Bank3_NAND */ + else + { + /* Set the FSMC_Bank3 registers to their reset values */ + FSMC_Bank3->PCR3 = 0x00000018; + FSMC_Bank3->SR3 = 0x00000040; + FSMC_Bank3->PMEM3 = 0xFCFCFCFC; + FSMC_Bank3->PATT3 = 0xFCFCFCFC; + } +} + +/** + * @brief Initializes the FSMC NAND Banks according to the specified parameters + * in the FSMC_NANDInitStruct. + * @param FSMC_NANDInitStruct : pointer to a FSMC_NANDInitTypeDef structure that + * contains the configuration information for the FSMC NAND specified Banks. + * @retval None + */ +void FSMC_NANDInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct) +{ + uint32_t tmppcr = 0x00000000, tmppmem = 0x00000000, tmppatt = 0x00000000; + + /* Check the parameters */ + assert_param( IS_FSMC_NAND_BANK(FSMC_NANDInitStruct->FSMC_Bank)); + assert_param( IS_FSMC_WAIT_FEATURE(FSMC_NANDInitStruct->FSMC_Waitfeature)); + assert_param( IS_FSMC_MEMORY_WIDTH(FSMC_NANDInitStruct->FSMC_MemoryDataWidth)); + assert_param( IS_FSMC_ECC_STATE(FSMC_NANDInitStruct->FSMC_ECC)); + assert_param( IS_FSMC_ECCPAGE_SIZE(FSMC_NANDInitStruct->FSMC_ECCPageSize)); + assert_param( IS_FSMC_TCLR_TIME(FSMC_NANDInitStruct->FSMC_TCLRSetupTime)); + assert_param( IS_FSMC_TAR_TIME(FSMC_NANDInitStruct->FSMC_TARSetupTime)); + assert_param(IS_FSMC_SETUP_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime)); + assert_param(IS_FSMC_SETUP_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime)); + + /* Set the tmppcr value according to FSMC_NANDInitStruct parameters */ + tmppcr = (uint32_t)FSMC_NANDInitStruct->FSMC_Waitfeature | + PCR_MEMORYTYPE_NAND | + FSMC_NANDInitStruct->FSMC_MemoryDataWidth | + FSMC_NANDInitStruct->FSMC_ECC | + FSMC_NANDInitStruct->FSMC_ECCPageSize | + (FSMC_NANDInitStruct->FSMC_TCLRSetupTime << 9 )| + (FSMC_NANDInitStruct->FSMC_TARSetupTime << 13); + + /* Set tmppmem value according to FSMC_CommonSpaceTimingStructure parameters */ + tmppmem = (uint32_t)FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime | + (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime << 8) | + (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime << 16)| + (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime << 24); + + /* Set tmppatt value according to FSMC_AttributeSpaceTimingStructure parameters */ + tmppatt = (uint32_t)FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime | + (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime << 8) | + (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime << 16)| + (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime << 24); + + if(FSMC_NANDInitStruct->FSMC_Bank == FSMC_Bank2_NAND) + { + /* FSMC_Bank2_NAND registers configuration */ + FSMC_Bank2->PCR2 = tmppcr; + FSMC_Bank2->PMEM2 = tmppmem; + FSMC_Bank2->PATT2 = tmppatt; + } + else + { + /* FSMC_Bank3_NAND registers configuration */ + FSMC_Bank3->PCR3 = tmppcr; + FSMC_Bank3->PMEM3 = tmppmem; + FSMC_Bank3->PATT3 = tmppatt; + } +} + + +/** + * @brief Fills each FSMC_NANDInitStruct member with its default value. + * @param FSMC_NANDInitStruct: pointer to a FSMC_NANDInitTypeDef structure which + * will be initialized. + * @retval None + */ +void FSMC_NANDStructInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct) +{ + /* Reset NAND Init structure parameters values */ + FSMC_NANDInitStruct->FSMC_Bank = FSMC_Bank2_NAND; + FSMC_NANDInitStruct->FSMC_Waitfeature = FSMC_Waitfeature_Disable; + FSMC_NANDInitStruct->FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; + FSMC_NANDInitStruct->FSMC_ECC = FSMC_ECC_Disable; + FSMC_NANDInitStruct->FSMC_ECCPageSize = FSMC_ECCPageSize_256Bytes; + FSMC_NANDInitStruct->FSMC_TCLRSetupTime = 0x0; + FSMC_NANDInitStruct->FSMC_TARSetupTime = 0x0; + FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; +} + +/** + * @brief Enables or disables the specified NAND Memory Bank. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @param NewState: new state of the FSMC_Bank. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState) +{ + assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected NAND Bank by setting the PBKEN bit in the PCRx register */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->PCR2 |= PCR_PBKEN_SET; + } + else + { + FSMC_Bank3->PCR3 |= PCR_PBKEN_SET; + } + } + else + { + /* Disable the selected NAND Bank by clearing the PBKEN bit in the PCRx register */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->PCR2 &= PCR_PBKEN_RESET; + } + else + { + FSMC_Bank3->PCR3 &= PCR_PBKEN_RESET; + } + } +} +/** + * @brief Enables or disables the FSMC NAND ECC feature. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @param NewState: new state of the FSMC NAND ECC feature. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FSMC_NANDECCCmd(uint32_t FSMC_Bank, FunctionalState NewState) +{ + assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected NAND Bank ECC function by setting the ECCEN bit in the PCRx register */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->PCR2 |= PCR_ECCEN_SET; + } + else + { + FSMC_Bank3->PCR3 |= PCR_ECCEN_SET; + } + } + else + { + /* Disable the selected NAND Bank ECC function by clearing the ECCEN bit in the PCRx register */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->PCR2 &= PCR_ECCEN_RESET; + } + else + { + FSMC_Bank3->PCR3 &= PCR_ECCEN_RESET; + } + } +} + +/** + * @brief Returns the error correction code register value. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @retval The Error Correction Code (ECC) value. + */ +uint32_t FSMC_GetECC(uint32_t FSMC_Bank) +{ + uint32_t eccval = 0x00000000; + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + /* Get the ECCR2 register value */ + eccval = FSMC_Bank2->ECCR2; + } + else + { + /* Get the ECCR3 register value */ + eccval = FSMC_Bank3->ECCR3; + } + /* Return the error correction code value */ + return(eccval); +} +/** + * @} + */ + +/** @defgroup FSMC_Group3 PCCARD Controller functions + * @brief PCCARD Controller functions + * +@verbatim + =============================================================================== + PCCARD Controller functions + =============================================================================== + + The following sequence should be followed to configure the FSMC to interface with + 16-bit PC Card compatible memory connected to the PCCARD Bank: + + 1. Enable the clock for the FSMC and associated GPIOs using the following functions: + RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); + + 2. FSMC pins configuration + - Connect the involved FSMC pins to AF12 using the following function + GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FSMC); + - Configure these FSMC pins in alternate function mode by calling the function + GPIO_Init(); + + 3. Declare a FSMC_PCCARDInitTypeDef structure, for example: + FSMC_PCCARDInitTypeDef FSMC_PCCARDInitStructure; + and fill the FSMC_PCCARDInitStructure variable with the allowed values of + the structure member. + + 4. Initialize the PCCARD Controller by calling the function + FSMC_PCCARDInit(&FSMC_PCCARDInitStructure); + + 5. Then enable the PCCARD Bank: + FSMC_PCCARDCmd(ENABLE); + + 6. At this stage you can read/write from/to the memory connected to the PCCARD Bank. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the FSMC PCCARD Bank registers to their default reset values. + * @param None + * @retval None + */ +void FSMC_PCCARDDeInit(void) +{ + /* Set the FSMC_Bank4 registers to their reset values */ + FSMC_Bank4->PCR4 = 0x00000018; + FSMC_Bank4->SR4 = 0x00000000; + FSMC_Bank4->PMEM4 = 0xFCFCFCFC; + FSMC_Bank4->PATT4 = 0xFCFCFCFC; + FSMC_Bank4->PIO4 = 0xFCFCFCFC; +} + +/** + * @brief Initializes the FSMC PCCARD Bank according to the specified parameters + * in the FSMC_PCCARDInitStruct. + * @param FSMC_PCCARDInitStruct : pointer to a FSMC_PCCARDInitTypeDef structure + * that contains the configuration information for the FSMC PCCARD Bank. + * @retval None + */ +void FSMC_PCCARDInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct) +{ + /* Check the parameters */ + assert_param(IS_FSMC_WAIT_FEATURE(FSMC_PCCARDInitStruct->FSMC_Waitfeature)); + assert_param(IS_FSMC_TCLR_TIME(FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime)); + assert_param(IS_FSMC_TAR_TIME(FSMC_PCCARDInitStruct->FSMC_TARSetupTime)); + + assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime)); + + assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime)); + assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime)); + + /* Set the PCR4 register value according to FSMC_PCCARDInitStruct parameters */ + FSMC_Bank4->PCR4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_Waitfeature | + FSMC_MemoryDataWidth_16b | + (FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime << 9) | + (FSMC_PCCARDInitStruct->FSMC_TARSetupTime << 13); + + /* Set PMEM4 register value according to FSMC_CommonSpaceTimingStructure parameters */ + FSMC_Bank4->PMEM4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime | + (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime << 8) | + (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime << 16)| + (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime << 24); + + /* Set PATT4 register value according to FSMC_AttributeSpaceTimingStructure parameters */ + FSMC_Bank4->PATT4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime | + (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime << 8) | + (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime << 16)| + (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime << 24); + + /* Set PIO4 register value according to FSMC_IOSpaceTimingStructure parameters */ + FSMC_Bank4->PIO4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime | + (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime << 8) | + (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime << 16)| + (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime << 24); +} + +/** + * @brief Fills each FSMC_PCCARDInitStruct member with its default value. + * @param FSMC_PCCARDInitStruct: pointer to a FSMC_PCCARDInitTypeDef structure + * which will be initialized. + * @retval None + */ +void FSMC_PCCARDStructInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct) +{ + /* Reset PCCARD Init structure parameters values */ + FSMC_PCCARDInitStruct->FSMC_Waitfeature = FSMC_Waitfeature_Disable; + FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime = 0x0; + FSMC_PCCARDInitStruct->FSMC_TARSetupTime = 0x0; + FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; +} + +/** + * @brief Enables or disables the PCCARD Memory Bank. + * @param NewState: new state of the PCCARD Memory Bank. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FSMC_PCCARDCmd(FunctionalState NewState) +{ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the PCCARD Bank by setting the PBKEN bit in the PCR4 register */ + FSMC_Bank4->PCR4 |= PCR_PBKEN_SET; + } + else + { + /* Disable the PCCARD Bank by clearing the PBKEN bit in the PCR4 register */ + FSMC_Bank4->PCR4 &= PCR_PBKEN_RESET; + } +} +/** + * @} + */ + +/** @defgroup FSMC_Group4 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified FSMC interrupts. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD + * @param FSMC_IT: specifies the FSMC interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. + * @arg FSMC_IT_Level: Level edge detection interrupt. + * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. + * @param NewState: new state of the specified FSMC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FSMC_ITConfig(uint32_t FSMC_Bank, uint32_t FSMC_IT, FunctionalState NewState) +{ + assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); + assert_param(IS_FSMC_IT(FSMC_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected FSMC_Bank2 interrupts */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->SR2 |= FSMC_IT; + } + /* Enable the selected FSMC_Bank3 interrupts */ + else if (FSMC_Bank == FSMC_Bank3_NAND) + { + FSMC_Bank3->SR3 |= FSMC_IT; + } + /* Enable the selected FSMC_Bank4 interrupts */ + else + { + FSMC_Bank4->SR4 |= FSMC_IT; + } + } + else + { + /* Disable the selected FSMC_Bank2 interrupts */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + + FSMC_Bank2->SR2 &= (uint32_t)~FSMC_IT; + } + /* Disable the selected FSMC_Bank3 interrupts */ + else if (FSMC_Bank == FSMC_Bank3_NAND) + { + FSMC_Bank3->SR3 &= (uint32_t)~FSMC_IT; + } + /* Disable the selected FSMC_Bank4 interrupts */ + else + { + FSMC_Bank4->SR4 &= (uint32_t)~FSMC_IT; + } + } +} + +/** + * @brief Checks whether the specified FSMC flag is set or not. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD + * @param FSMC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg FSMC_FLAG_RisingEdge: Rising edge detection Flag. + * @arg FSMC_FLAG_Level: Level detection Flag. + * @arg FSMC_FLAG_FallingEdge: Falling edge detection Flag. + * @arg FSMC_FLAG_FEMPT: Fifo empty Flag. + * @retval The new state of FSMC_FLAG (SET or RESET). + */ +FlagStatus FSMC_GetFlagStatus(uint32_t FSMC_Bank, uint32_t FSMC_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t tmpsr = 0x00000000; + + /* Check the parameters */ + assert_param(IS_FSMC_GETFLAG_BANK(FSMC_Bank)); + assert_param(IS_FSMC_GET_FLAG(FSMC_FLAG)); + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + tmpsr = FSMC_Bank2->SR2; + } + else if(FSMC_Bank == FSMC_Bank3_NAND) + { + tmpsr = FSMC_Bank3->SR3; + } + /* FSMC_Bank4_PCCARD*/ + else + { + tmpsr = FSMC_Bank4->SR4; + } + + /* Get the flag status */ + if ((tmpsr & FSMC_FLAG) != (uint16_t)RESET ) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @brief Clears the FSMC's pending flags. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD + * @param FSMC_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg FSMC_FLAG_RisingEdge: Rising edge detection Flag. + * @arg FSMC_FLAG_Level: Level detection Flag. + * @arg FSMC_FLAG_FallingEdge: Falling edge detection Flag. + * @retval None + */ +void FSMC_ClearFlag(uint32_t FSMC_Bank, uint32_t FSMC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_FSMC_GETFLAG_BANK(FSMC_Bank)); + assert_param(IS_FSMC_CLEAR_FLAG(FSMC_FLAG)) ; + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->SR2 &= ~FSMC_FLAG; + } + else if(FSMC_Bank == FSMC_Bank3_NAND) + { + FSMC_Bank3->SR3 &= ~FSMC_FLAG; + } + /* FSMC_Bank4_PCCARD*/ + else + { + FSMC_Bank4->SR4 &= ~FSMC_FLAG; + } +} + +/** + * @brief Checks whether the specified FSMC interrupt has occurred or not. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD + * @param FSMC_IT: specifies the FSMC interrupt source to check. + * This parameter can be one of the following values: + * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. + * @arg FSMC_IT_Level: Level edge detection interrupt. + * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. + * @retval The new state of FSMC_IT (SET or RESET). + */ +ITStatus FSMC_GetITStatus(uint32_t FSMC_Bank, uint32_t FSMC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t tmpsr = 0x0, itstatus = 0x0, itenable = 0x0; + + /* Check the parameters */ + assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); + assert_param(IS_FSMC_GET_IT(FSMC_IT)); + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + tmpsr = FSMC_Bank2->SR2; + } + else if(FSMC_Bank == FSMC_Bank3_NAND) + { + tmpsr = FSMC_Bank3->SR3; + } + /* FSMC_Bank4_PCCARD*/ + else + { + tmpsr = FSMC_Bank4->SR4; + } + + itstatus = tmpsr & FSMC_IT; + + itenable = tmpsr & (FSMC_IT >> 3); + if ((itstatus != (uint32_t)RESET) && (itenable != (uint32_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the FSMC's interrupt pending bits. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD + * @param FSMC_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. + * @arg FSMC_IT_Level: Level edge detection interrupt. + * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. + * @retval None + */ +void FSMC_ClearITPendingBit(uint32_t FSMC_Bank, uint32_t FSMC_IT) +{ + /* Check the parameters */ + assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); + assert_param(IS_FSMC_IT(FSMC_IT)); + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->SR2 &= ~(FSMC_IT >> 3); + } + else if(FSMC_Bank == FSMC_Bank3_NAND) + { + FSMC_Bank3->SR3 &= ~(FSMC_IT >> 3); + } + /* FSMC_Bank4_PCCARD*/ + else + { + FSMC_Bank4->SR4 &= ~(FSMC_IT >> 3); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c new file mode 100644 index 0000000..8e16716 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c @@ -0,0 +1,561 @@ +/** + ****************************************************************************** + * @file stm32f4xx_gpio.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the GPIO peripheral: + * - Initialization and Configuration + * - GPIO Read and Write + * - GPIO Alternate functions configuration + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + * 1. Enable the GPIO AHB clock using the following function + * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); + * + * 2. Configure the GPIO pin(s) using GPIO_Init() + * Four possible configuration are available for each pin: + * - Input: Floating, Pull-up, Pull-down. + * - Output: Push-Pull (Pull-up, Pull-down or no Pull) + * Open Drain (Pull-up, Pull-down or no Pull). + * In output mode, the speed is configurable: 2 MHz, 25 MHz, + * 50 MHz or 100 MHz. + * - Alternate Function: Push-Pull (Pull-up, Pull-down or no Pull) + * Open Drain (Pull-up, Pull-down or no Pull). + * - Analog: required mode when a pin is to be used as ADC channel + * or DAC output. + * + * 3- Peripherals alternate function: + * - For ADC and DAC, configure the desired pin in analog mode using + * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AN; + * - For other peripherals (TIM, USART...): + * - Connect the pin to the desired peripherals' Alternate + * Function (AF) using GPIO_PinAFConfig() function + * - Configure the desired pin in alternate function mode using + * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF + * - Select the type, pull-up/pull-down and output speed via + * GPIO_PuPd, GPIO_OType and GPIO_Speed members + * - Call GPIO_Init() function + * + * 4. To get the level of a pin configured in input mode use GPIO_ReadInputDataBit() + * + * 5. To set/reset the level of a pin configured in output mode use + * GPIO_SetBits()/GPIO_ResetBits() + * + * 6. During and just after reset, the alternate functions are not + * active and the GPIO pins are configured in input floating mode + * (except JTAG pins). + * + * 7. The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as + * general-purpose (PC14 and PC15, respectively) when the LSE + * oscillator is off. The LSE has priority over the GPIO function. + * + * 8. The HSE oscillator pins OSC_IN/OSC_OUT can be used as + * general-purpose PH0 and PH1, respectively, when the HSE + * oscillator is off. The HSE has priority over the GPIO function. + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_gpio.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup GPIO + * @brief GPIO driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup GPIO_Private_Functions + * @{ + */ + +/** @defgroup GPIO_Group1 Initialization and Configuration + * @brief Initialization and Configuration + * +@verbatim + =============================================================================== + Initialization and Configuration + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the GPIOx peripheral registers to their default reset values. + * @note By default, The GPIO pins are configured in input floating mode (except JTAG pins). + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @retval None + */ +void GPIO_DeInit(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + if (GPIOx == GPIOA) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, DISABLE); + } + else if (GPIOx == GPIOB) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, DISABLE); + } + else if (GPIOx == GPIOC) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, DISABLE); + } + else if (GPIOx == GPIOD) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, DISABLE); + } + else if (GPIOx == GPIOE) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, DISABLE); + } + else if (GPIOx == GPIOF) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOF, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOF, DISABLE); + } + else if (GPIOx == GPIOG) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOG, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOG, DISABLE); + } + else if (GPIOx == GPIOH) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, DISABLE); + } + else + { + if (GPIOx == GPIOI) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOI, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOI, DISABLE); + } + } +} + +/** + * @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains + * the configuration information for the specified GPIO peripheral. + * @retval None + */ +void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) +{ + uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); + assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); + assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd)); + + /* -------------------------Configure the port pins---------------- */ + /*-- GPIO Mode Configuration --*/ + for (pinpos = 0x00; pinpos < 0x10; pinpos++) + { + pos = ((uint32_t)0x01) << pinpos; + /* Get the port pins position */ + currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; + + if (currentpin == pos) + { + GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2)); + GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2)); + + if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF)) + { + /* Check Speed mode parameters */ + assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); + + /* Speed mode configuration */ + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2)); + GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2)); + + /* Check Output mode parameters */ + assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType)); + + /* Output mode configuration*/ + GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos)) ; + GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos)); + } + + /* Pull-up Pull down resistor configuration*/ + GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2)); + GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2)); + } + } +} + +/** + * @brief Fills each GPIO_InitStruct member with its default value. + * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will be initialized. + * @retval None + */ +void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct) +{ + /* Reset GPIO init structure parameters values */ + GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All; + GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStruct->GPIO_OType = GPIO_OType_PP; + GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL; +} + +/** + * @brief Locks GPIO Pins configuration registers. + * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, + * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. + * @note The configuration of the locked GPIO pins can no longer be modified + * until the next reset. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to be locked. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + __IO uint32_t tmp = 0x00010000; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + tmp |= GPIO_Pin; + /* Set LCKK bit */ + GPIOx->LCKR = tmp; + /* Reset LCKK bit */ + GPIOx->LCKR = GPIO_Pin; + /* Set LCKK bit */ + GPIOx->LCKR = tmp; + /* Read LCKK bit*/ + tmp = GPIOx->LCKR; + /* Read LCKK bit*/ + tmp = GPIOx->LCKR; +} + +/** + * @} + */ + +/** @defgroup GPIO_Group2 GPIO Read and Write + * @brief GPIO Read and Write + * +@verbatim + =============================================================================== + GPIO Read and Write + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Reads the specified input port pin. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to read. + * This parameter can be GPIO_Pin_x where x can be (0..15). + * @retval The input port pin value. + */ +uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + uint8_t bitstatus = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) + { + bitstatus = (uint8_t)Bit_SET; + } + else + { + bitstatus = (uint8_t)Bit_RESET; + } + return bitstatus; +} + +/** + * @brief Reads the specified GPIO input data port. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @retval GPIO input data port value. + */ +uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + return ((uint16_t)GPIOx->IDR); +} + +/** + * @brief Reads the specified output data port bit. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to read. + * This parameter can be GPIO_Pin_x where x can be (0..15). + * @retval The output port pin value. + */ +uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + uint8_t bitstatus = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET) + { + bitstatus = (uint8_t)Bit_SET; + } + else + { + bitstatus = (uint8_t)Bit_RESET; + } + return bitstatus; +} + +/** + * @brief Reads the specified GPIO output data port. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @retval GPIO output data port value. + */ +uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + return ((uint16_t)GPIOx->ODR); +} + +/** + * @brief Sets the selected data port bits. + * @note This functions uses GPIOx_BSRR register to allow atomic read/modify + * accesses. In this way, there is no risk of an IRQ occurring between + * the read and the modify access. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bits to be written. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIOx->BSRRL = GPIO_Pin; +} + +/** + * @brief Clears the selected data port bits. + * @note This functions uses GPIOx_BSRR register to allow atomic read/modify + * accesses. In this way, there is no risk of an IRQ occurring between + * the read and the modify access. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bits to be written. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIOx->BSRRH = GPIO_Pin; +} + +/** + * @brief Sets or clears the selected data port bit. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be one of GPIO_Pin_x where x can be (0..15). + * @param BitVal: specifies the value to be written to the selected bit. + * This parameter can be one of the BitAction enum values: + * @arg Bit_RESET: to clear the port pin + * @arg Bit_SET: to set the port pin + * @retval None + */ +void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_BIT_ACTION(BitVal)); + + if (BitVal != Bit_RESET) + { + GPIOx->BSRRL = GPIO_Pin; + } + else + { + GPIOx->BSRRH = GPIO_Pin ; + } +} + +/** + * @brief Writes data to the specified GPIO data port. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @param PortVal: specifies the value to be written to the port output data register. + * @retval None + */ +void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + GPIOx->ODR = PortVal; +} + +/** + * @brief Toggles the specified GPIO pins.. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @param GPIO_Pin: Specifies the pins to be toggled. + * @retval None + */ +void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + GPIOx->ODR ^= GPIO_Pin; +} + +/** + * @} + */ + +/** @defgroup GPIO_Group3 GPIO Alternate functions configuration function + * @brief GPIO Alternate functions configuration function + * +@verbatim + =============================================================================== + GPIO Alternate functions configuration function + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Changes the mapping of the specified pin. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. + * @param GPIO_PinSource: specifies the pin for the Alternate function. + * This parameter can be GPIO_PinSourcex where x can be (0..15). + * @param GPIO_AFSelection: selects the pin to used as Alternate function. + * This parameter can be one of the following values: + * @arg GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin to AF0 (default after reset) + * @arg GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2) to AF0 (default after reset) + * @arg GPIO_AF_TAMPER: Connect TAMPER pins (TAMPER_1 and TAMPER_2) to AF0 (default after reset) + * @arg GPIO_AF_SWJ: Connect SWJ pins (SWD and JTAG)to AF0 (default after reset) + * @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset) + * @arg GPIO_AF_TIM1: Connect TIM1 pins to AF1 + * @arg GPIO_AF_TIM2: Connect TIM2 pins to AF1 + * @arg GPIO_AF_TIM3: Connect TIM3 pins to AF2 + * @arg GPIO_AF_TIM4: Connect TIM4 pins to AF2 + * @arg GPIO_AF_TIM5: Connect TIM5 pins to AF2 + * @arg GPIO_AF_TIM8: Connect TIM8 pins to AF3 + * @arg GPIO_AF_TIM9: Connect TIM9 pins to AF3 + * @arg GPIO_AF_TIM10: Connect TIM10 pins to AF3 + * @arg GPIO_AF_TIM11: Connect TIM11 pins to AF3 + * @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4 + * @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4 + * @arg GPIO_AF_I2C3: Connect I2C3 pins to AF4 + * @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5 + * @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5 + * @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6 + * @arg GPIO_AF_I2S3ext: Connect I2S3ext pins to AF7 + * @arg GPIO_AF_USART1: Connect USART1 pins to AF7 + * @arg GPIO_AF_USART2: Connect USART2 pins to AF7 + * @arg GPIO_AF_USART3: Connect USART3 pins to AF7 + * @arg GPIO_AF_UART4: Connect UART4 pins to AF8 + * @arg GPIO_AF_UART5: Connect UART5 pins to AF8 + * @arg GPIO_AF_USART6: Connect USART6 pins to AF8 + * @arg GPIO_AF_CAN1: Connect CAN1 pins to AF9 + * @arg GPIO_AF_CAN2: Connect CAN2 pins to AF9 + * @arg GPIO_AF_TIM12: Connect TIM12 pins to AF9 + * @arg GPIO_AF_TIM13: Connect TIM13 pins to AF9 + * @arg GPIO_AF_TIM14: Connect TIM14 pins to AF9 + * @arg GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10 + * @arg GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10 + * @arg GPIO_AF_ETH: Connect ETHERNET pins to AF11 + * @arg GPIO_AF_FSMC: Connect FSMC pins to AF12 + * @arg GPIO_AF_OTG_HS_FS: Connect OTG HS (configured in FS) pins to AF12 + * @arg GPIO_AF_SDIO: Connect SDIO pins to AF12 + * @arg GPIO_AF_DCMI: Connect DCMI pins to AF13 + * @arg GPIO_AF_EVENTOUT: Connect EVENTOUT pins to AF15 + * @retval None + */ +void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF) +{ + uint32_t temp = 0x00; + uint32_t temp_2 = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); + assert_param(IS_GPIO_AF(GPIO_AF)); + + temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ; + GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ; + temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp; + GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash.c new file mode 100644 index 0000000..d4fe401 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash.c @@ -0,0 +1,700 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hash.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the HASH / HMAC Processor (HASH) peripheral: + * - Initialization and Configuration functions + * - Message Digest generation functions + * - context swapping functions + * - DMA interface function + * - Interrupts and flags management + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + * HASH operation : + * ---------------- + * 1. Enable the HASH controller clock using + * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE) function. + * + * 2. Initialise the HASH using HASH_Init() function. + * + * 3 . Reset the HASH processor core, so that the HASH will be ready + * to compute he message digest of a new message by using + * HASH_Reset() function. + * + * 4. Enable the HASH controller using the HASH_Cmd() function. + * + * 5. if using DMA for Data input transfer, Activate the DMA Request + * using HASH_DMACmd() function + * + * 6. if DMA is not used for data transfer, use HASH_DataIn() function + * to enter data to IN FIFO. + * + * + * 7. Configure the Number of valid bits in last word of the message + * using HASH_SetLastWordValidBitsNbr() function. + * + * 8. if the message length is not an exact multiple of 512 bits, + * then the function HASH_StartDigest() must be called to + * launch the computation of the final digest. + * + * 9. Once computed, the digest can be read using HASH_GetDigest() + * function. + * + * 10. To control HASH events you can use one of the following + * two methods: + * a- Check on HASH flags using the HASH_GetFlagStatus() function. + * b- Use HASH interrupts through the function HASH_ITConfig() at + * initialization phase and HASH_GetITStatus() function into + * interrupt routines in hashing phase. + * After checking on a flag you should clear it using HASH_ClearFlag() + * function. And after checking on an interrupt event you should + * clear it using HASH_ClearITPendingBit() function. + * + * 11. Save and restore hash processor context using + * HASH_SaveContext() and HASH_RestoreContext() functions. + * + * + * + * HMAC operation : + * ---------------- + * The HMAC algorithm is used for message authentication, by + * irreversibly binding the message being processed to a key chosen + * by the user. + * For HMAC specifications, refer to "HMAC: keyed-hashing for message + * authentication, H. Krawczyk, M. Bellare, R. Canetti, February 1997" + * + * Basically, the HMAC algorithm consists of two nested hash operations: + * HMAC(message) = Hash[((key | pad) XOR 0x5C) | Hash(((key | pad) XOR 0x36) | message)] + * where: + * - "pad" is a sequence of zeroes needed to extend the key to the + * length of the underlying hash function data block (that is + * 512 bits for both the SHA-1 and MD5 hash algorithms) + * - "|" represents the concatenation operator + * + * + * To compute the HMAC, four different phases are required: + * + * 1. Initialise the HASH using HASH_Init() function to do HMAC + * operation. + * + * 2. The key (to be used for the inner hash function) is then given + * to the core. This operation follows the same mechanism as the + * one used to send the message in the hash operation (that is, + * by HASH_DataIn() function and, finally, + * HASH_StartDigest() function. + * + * 3. Once the last word has been entered and computation has started, + * the hash processor elaborates the key. It is then ready to + * accept the message text using the same mechanism as the one + * used to send the message in the hash operation. + * + * 4. After the first hash round, the hash processor returns "ready" + * to indicate that it is ready to receive the key to be used for + * the outer hash function (normally, this key is the same as the + * one used for the inner hash function). When the last word of + * the key is entered and computation starts, the HMAC result is + * made available using HASH_GetDigest() function. + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hash.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup HASH + * @brief HASH driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup HASH_Private_Functions + * @{ + */ + +/** @defgroup HASH_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + This section provides functions allowing to + - Initialize the HASH peripheral + - Configure the HASH Processor + - MD5/SHA1, + - HASH/HMAC, + - datatype + - HMAC Key (if mode = HMAC) + - Reset the HASH Processor + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the HASH peripheral registers to their default reset values + * @param None + * @retval None + */ +void HASH_DeInit(void) +{ + /* Enable HASH reset state */ + RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_HASH, ENABLE); + /* Release HASH from reset state */ + RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_HASH, DISABLE); +} + +/** + * @brief Initializes the HASH peripheral according to the specified parameters + * in the HASH_InitStruct structure. + * @note the hash processor is reset when calling this function so that the + * HASH will be ready to compute the message digest of a new message. + * There is no need to call HASH_Reset() function. + * @param HASH_InitStruct: pointer to a HASH_InitTypeDef structure that contains + * the configuration information for the HASH peripheral. + * @note The field HASH_HMACKeyType in HASH_InitTypeDef must be filled only + * if the algorithm mode is HMAC. + * @retval None + */ +void HASH_Init(HASH_InitTypeDef* HASH_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_HASH_ALGOSELECTION(HASH_InitStruct->HASH_AlgoSelection)); + assert_param(IS_HASH_DATATYPE(HASH_InitStruct->HASH_DataType)); + assert_param(IS_HASH_ALGOMODE(HASH_InitStruct->HASH_AlgoMode)); + + /* Configure the Algorithm used, algorithm mode and the datatype */ + HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE); + HASH->CR |= (HASH_InitStruct->HASH_AlgoSelection | \ + HASH_InitStruct->HASH_DataType | \ + HASH_InitStruct->HASH_AlgoMode); + + /* if algorithm mode is HMAC, set the Key */ + if(HASH_InitStruct->HASH_AlgoMode == HASH_AlgoMode_HMAC) + { + assert_param(IS_HASH_HMAC_KEYTYPE(HASH_InitStruct->HASH_HMACKeyType)); + HASH->CR &= ~HASH_CR_LKEY; + HASH->CR |= HASH_InitStruct->HASH_HMACKeyType; + } + + /* Reset the HASH processor core, so that the HASH will be ready to compute + the message digest of a new message */ + HASH->CR |= HASH_CR_INIT; +} + +/** + * @brief Fills each HASH_InitStruct member with its default value. + * @param HASH_InitStruct : pointer to a HASH_InitTypeDef structure which will + * be initialized. + * @note The default values set are : Processor mode is HASH, Algorithm selected is SHA1, + * Data type selected is 32b and HMAC Key Type is short key. + * @retval None + */ +void HASH_StructInit(HASH_InitTypeDef* HASH_InitStruct) +{ + /* Initialize the HASH_AlgoSelection member */ + HASH_InitStruct->HASH_AlgoSelection = HASH_AlgoSelection_SHA1; + + /* Initialize the HASH_AlgoMode member */ + HASH_InitStruct->HASH_AlgoMode = HASH_AlgoMode_HASH; + + /* Initialize the HASH_DataType member */ + HASH_InitStruct->HASH_DataType = HASH_DataType_32b; + + /* Initialize the HASH_HMACKeyType member */ + HASH_InitStruct->HASH_HMACKeyType = HASH_HMACKeyType_ShortKey; +} + +/** + * @brief Resets the HASH processor core, so that the HASH will be ready + * to compute the message digest of a new message. + * @note Calling this function will clear the HASH_SR_DCIS (Digest calculation + * completion interrupt status) bit corresponding to HASH_IT_DCI + * interrupt and HASH_FLAG_DCIS flag. + * @param None + * @retval None + */ +void HASH_Reset(void) +{ + /* Reset the HASH processor core */ + HASH->CR |= HASH_CR_INIT; +} +/** + * @} + */ + +/** @defgroup HASH_Group2 Message Digest generation functions + * @brief Message Digest generation functions + * +@verbatim + =============================================================================== + Message Digest generation functions + =============================================================================== + This section provides functions allowing the generation of message digest: + - Push data in the IN FIFO : using HASH_DataIn() + - Get the number of words set in IN FIFO, use HASH_GetInFIFOWordsNbr() + - set the last word valid bits number using HASH_SetLastWordValidBitsNbr() + - start digest calculation : using HASH_StartDigest() + - Get the Digest message : using HASH_GetDigest() + +@endverbatim + * @{ + */ + + +/** + * @brief Configure the Number of valid bits in last word of the message + * @param ValidNumber: Number of valid bits in last word of the message. + * This parameter must be a number between 0 and 0x1F. + * - 0x00: All 32 bits of the last data written are valid + * - 0x01: Only bit [0] of the last data written is valid + * - 0x02: Only bits[1:0] of the last data written are valid + * - 0x03: Only bits[2:0] of the last data written are valid + * - ... + * - 0x1F: Only bits[30:0] of the last data written are valid + * @note The Number of valid bits must be set before to start the message + * digest competition (in Hash and HMAC) and key treatment(in HMAC). + * @retval None + */ +void HASH_SetLastWordValidBitsNbr(uint16_t ValidNumber) +{ + /* Check the parameters */ + assert_param(IS_HASH_VALIDBITSNUMBER(ValidNumber)); + + /* Configure the Number of valid bits in last word of the message */ + HASH->STR &= ~(HASH_STR_NBW); + HASH->STR |= ValidNumber; +} + +/** + * @brief Writes data in the Data Input FIFO + * @param Data: new data of the message to be processed. + * @retval None + */ +void HASH_DataIn(uint32_t Data) +{ + /* Write in the DIN register a new data */ + HASH->DIN = Data; +} + +/** + * @brief Returns the number of words already pushed into the IN FIFO. + * @param None + * @retval The value of words already pushed into the IN FIFO. + */ +uint8_t HASH_GetInFIFOWordsNbr(void) +{ + /* Return the value of NBW bits */ + return ((HASH->CR & HASH_CR_NBW) >> 8); +} + +/** + * @brief Provides the message digest result. + * @note In MD5 mode, Data[4] filed of HASH_MsgDigest structure is not used + * and is read as zero. + * @param HASH_MessageDigest: pointer to a HASH_MsgDigest structure which will + * hold the message digest result + * @retval None + */ +void HASH_GetDigest(HASH_MsgDigest* HASH_MessageDigest) +{ + /* Get the data field */ + HASH_MessageDigest->Data[0] = HASH->HR[0]; + HASH_MessageDigest->Data[1] = HASH->HR[1]; + HASH_MessageDigest->Data[2] = HASH->HR[2]; + HASH_MessageDigest->Data[3] = HASH->HR[3]; + HASH_MessageDigest->Data[4] = HASH->HR[4]; +} + +/** + * @brief Starts the message padding and calculation of the final message + * @param None + * @retval None + */ +void HASH_StartDigest(void) +{ + /* Start the Digest calculation */ + HASH->STR |= HASH_STR_DCAL; +} +/** + * @} + */ + +/** @defgroup HASH_Group3 Context swapping functions + * @brief Context swapping functions + * +@verbatim + =============================================================================== + Context swapping functions + =============================================================================== + + This section provides functions allowing to save and store HASH Context + + It is possible to interrupt a HASH/HMAC process to perform another processing + with a higher priority, and to complete the interrupted process later on, when + the higher priority task is complete. To do so, the context of the interrupted + task must be saved from the HASH registers to memory, and then be restored + from memory to the HASH registers. + + 1. To save the current context, use HASH_SaveContext() function + 2. To restore the saved context, use HASH_RestoreContext() function + + +@endverbatim + * @{ + */ + +/** + * @brief Save the Hash peripheral Context. + * @note The context can be saved only when no block is currently being + * processed. So user must wait for DINIS = 1 (the last block has been + * processed and the input FIFO is empty) or NBW != 0 (the FIFO is not + * full and no processing is ongoing). + * @param HASH_ContextSave: pointer to a HASH_Context structure that contains + * the repository for current context. + * @retval None + */ +void HASH_SaveContext(HASH_Context* HASH_ContextSave) +{ + uint8_t i = 0; + + /* save context registers */ + HASH_ContextSave->HASH_IMR = HASH->IMR; + HASH_ContextSave->HASH_STR = HASH->STR; + HASH_ContextSave->HASH_CR = HASH->CR; + for(i=0; i<=50;i++) + { + HASH_ContextSave->HASH_CSR[i] = HASH->CSR[i]; + } +} + +/** + * @brief Restore the Hash peripheral Context. + * @note After calling this function, user can restart the processing from the + * point where it has been interrupted. + * @param HASH_ContextRestore: pointer to a HASH_Context structure that contains + * the repository for saved context. + * @retval None + */ +void HASH_RestoreContext(HASH_Context* HASH_ContextRestore) +{ + uint8_t i = 0; + + /* restore context registers */ + HASH->IMR = HASH_ContextRestore->HASH_IMR; + HASH->STR = HASH_ContextRestore->HASH_STR; + HASH->CR = HASH_ContextRestore->HASH_CR; + + /* Initialize the hash processor */ + HASH->CR |= HASH_CR_INIT; + + /* continue restoring context registers */ + for(i=0; i<=50;i++) + { + HASH->CSR[i] = HASH_ContextRestore->HASH_CSR[i]; + } +} +/** + * @} + */ + +/** @defgroup HASH_Group4 HASH's DMA interface Configuration function + * @brief HASH's DMA interface Configuration function + * +@verbatim + =============================================================================== + HASH's DMA interface Configuration function + =============================================================================== + + This section provides functions allowing to configure the DMA interface for + HASH/ HMAC data input transfer. + + When the DMA mode is enabled (using the HASH_DMACmd() function), data can be + sent to the IN FIFO using the DMA peripheral. + + + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the HASH DMA interface. + * @note The DMA is disabled by hardware after the end of transfer. + * @param NewState: new state of the selected HASH DMA transfer request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void HASH_DMACmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the HASH DMA request */ + HASH->CR |= HASH_CR_DMAE; + } + else + { + /* Disable the HASH DMA request */ + HASH->CR &= ~HASH_CR_DMAE; + } +} +/** + * @} + */ + +/** @defgroup HASH_Group5 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + + This section provides functions allowing to configure the HASH Interrupts and + to get the status and clear flags and Interrupts pending bits. + + The HASH provides 2 Interrupts sources and 5 Flags: + + Flags : + ---------- + 1. HASH_FLAG_DINIS : set when 16 locations are free in the Data IN FIFO + which means that a new block (512 bit) can be entered + into the input buffer. + + 2. HASH_FLAG_DCIS : set when Digest calculation is complete + + 3. HASH_FLAG_DMAS : set when HASH's DMA interface is enabled (DMAE=1) or + a transfer is ongoing. + This Flag is cleared only by hardware. + + 4. HASH_FLAG_BUSY : set when The hash core is processing a block of data + This Flag is cleared only by hardware. + + 5. HASH_FLAG_DINNE : set when Data IN FIFO is not empty which means that + the Data IN FIFO contains at least one word of data. + This Flag is cleared only by hardware. + + Interrupts : + ------------ + + 1. HASH_IT_DINI : if enabled, this interrupt source is pending when 16 + locations are free in the Data IN FIFO which means that + a new block (512 bit) can be entered into the input buffer. + This interrupt source is cleared using + HASH_ClearITPendingBit(HASH_IT_DINI) function. + + 2. HASH_IT_DCI : if enabled, this interrupt source is pending when Digest + calculation is complete. + This interrupt source is cleared using + HASH_ClearITPendingBit(HASH_IT_DCI) function. + + Managing the HASH controller events : + ------------------------------------ + The user should identify which mode will be used in his application to manage + the HASH controller events: Polling mode or Interrupt mode. + + 1. In the Polling Mode it is advised to use the following functions: + - HASH_GetFlagStatus() : to check if flags events occur. + - HASH_ClearFlag() : to clear the flags events. + + 2. In the Interrupt Mode it is advised to use the following functions: + - HASH_ITConfig() : to enable or disable the interrupt source. + - HASH_GetITStatus() : to check if Interrupt occurs. + - HASH_ClearITPendingBit() : to clear the Interrupt pending Bit + (corresponding Flag). + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified HASH interrupts. + * @param HASH_IT: specifies the HASH interrupt source to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg HASH_IT_DINI: Data Input interrupt + * @arg HASH_IT_DCI: Digest Calculation Completion Interrupt + * @param NewState: new state of the specified HASH interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void HASH_ITConfig(uint8_t HASH_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_HASH_IT(HASH_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected HASH interrupt */ + HASH->IMR |= HASH_IT; + } + else + { + /* Disable the selected HASH interrupt */ + HASH->IMR &= (uint8_t) ~HASH_IT; + } +} + +/** + * @brief Checks whether the specified HASH flag is set or not. + * @param HASH_FLAG: specifies the HASH flag to check. + * This parameter can be one of the following values: + * @arg HASH_FLAG_DINIS: Data input interrupt status flag + * @arg HASH_FLAG_DCIS: Digest calculation completion interrupt status flag + * @arg HASH_FLAG_BUSY: Busy flag + * @arg HASH_FLAG_DMAS: DMAS Status flag + * @arg HASH_FLAG_DINNE: Data Input register (DIN) not empty status flag + * @retval The new state of HASH_FLAG (SET or RESET) + */ +FlagStatus HASH_GetFlagStatus(uint16_t HASH_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t tempreg = 0; + + /* Check the parameters */ + assert_param(IS_HASH_GET_FLAG(HASH_FLAG)); + + /* check if the FLAG is in CR register */ + if ((HASH_FLAG & HASH_FLAG_DINNE) != (uint16_t)RESET ) + { + tempreg = HASH->CR; + } + else /* The FLAG is in SR register */ + { + tempreg = HASH->SR; + } + + /* Check the status of the specified HASH flag */ + if ((tempreg & HASH_FLAG) != (uint16_t)RESET) + { + /* HASH is set */ + bitstatus = SET; + } + else + { + /* HASH_FLAG is reset */ + bitstatus = RESET; + } + + /* Return the HASH_FLAG status */ + return bitstatus; +} +/** + * @brief Clears the HASH flags. + * @param HASH_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg HASH_FLAG_DINIS: Data Input Flag + * @arg HASH_FLAG_DCIS: Digest Calculation Completion Flag + * @retval None + */ +void HASH_ClearFlag(uint16_t HASH_FLAG) +{ + /* Check the parameters */ + assert_param(IS_HASH_CLEAR_FLAG(HASH_FLAG)); + + /* Clear the selected HASH flags */ + HASH->SR = ~(uint32_t)HASH_FLAG; +} +/** + * @brief Checks whether the specified HASH interrupt has occurred or not. + * @param HASH_IT: specifies the HASH interrupt source to check. + * This parameter can be one of the following values: + * @arg HASH_IT_DINI: Data Input interrupt + * @arg HASH_IT_DCI: Digest Calculation Completion Interrupt + * @retval The new state of HASH_IT (SET or RESET). + */ +ITStatus HASH_GetITStatus(uint8_t HASH_IT) +{ + ITStatus bitstatus = RESET; + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_HASH_GET_IT(HASH_IT)); + + + /* Check the status of the specified HASH interrupt */ + tmpreg = HASH->SR; + + if (((HASH->IMR & tmpreg) & HASH_IT) != RESET) + { + /* HASH_IT is set */ + bitstatus = SET; + } + else + { + /* HASH_IT is reset */ + bitstatus = RESET; + } + /* Return the HASH_IT status */ + return bitstatus; +} + +/** + * @brief Clears the HASH interrupt pending bit(s). + * @param HASH_IT: specifies the HASH interrupt pending bit(s) to clear. + * This parameter can be any combination of the following values: + * @arg HASH_IT_DINI: Data Input interrupt + * @arg HASH_IT_DCI: Digest Calculation Completion Interrupt + * @retval None + */ +void HASH_ClearITPendingBit(uint8_t HASH_IT) +{ + /* Check the parameters */ + assert_param(IS_HASH_IT(HASH_IT)); + + /* Clear the selected HASH interrupt pending bit */ + HASH->SR = (uint8_t)~HASH_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash_md5.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash_md5.c new file mode 100644 index 0000000..56d495f --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash_md5.c @@ -0,0 +1,314 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hash_md5.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides high level functions to compute the HASH MD5 and + * HMAC MD5 Digest of an input message. + * It uses the stm32f4xx_hash.c/.h drivers to access the STM32F4xx HASH + * peripheral. + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + * 1. Enable The HASH controller clock using + * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE); function. + * + * 2. Calculate the HASH MD5 Digest using HASH_MD5() function. + * + * 3. Calculate the HMAC MD5 Digest using HMAC_MD5() function. + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hash.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup HASH + * @brief HASH driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define MD5BUSY_TIMEOUT ((uint32_t) 0x00010000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup HASH_Private_Functions + * @{ + */ + +/** @defgroup HASH_Group7 High Level MD5 functions + * @brief High Level MD5 Hash and HMAC functions + * +@verbatim + =============================================================================== + High Level MD5 Hash and HMAC functions + =============================================================================== + + +@endverbatim + * @{ + */ + +/** + * @brief Compute the HASH MD5 digest. + * @param Input: pointer to the Input buffer to be treated. + * @param Ilen: length of the Input buffer. + * @param Output: the returned digest + * @retval An ErrorStatus enumeration value: + * - SUCCESS: digest computation done + * - ERROR: digest computation failed + */ +ErrorStatus HASH_MD5(uint8_t *Input, uint32_t Ilen, uint8_t Output[16]) +{ + HASH_InitTypeDef MD5_HASH_InitStructure; + HASH_MsgDigest MD5_MessageDigest; + __IO uint16_t nbvalidbitsdata = 0; + uint32_t i = 0; + __IO uint32_t counter = 0; + uint32_t busystatus = 0; + ErrorStatus status = SUCCESS; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + + + /* Number of valid bits in last word of the Input data */ + nbvalidbitsdata = 8 * (Ilen % 4); + + /* HASH peripheral initialization */ + HASH_DeInit(); + + /* HASH Configuration */ + MD5_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_MD5; + MD5_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH; + MD5_HASH_InitStructure.HASH_DataType = HASH_DataType_8b; + HASH_Init(&MD5_HASH_InitStructure); + + /* Configure the number of valid bits in last word of the data */ + HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); + + /* Write the Input block in the IN FIFO */ + for(i=0; i 64) + { + /* HMAC long Key */ + MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey; + } + else + { + /* HMAC short Key */ + MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey; + } + HASH_Init(&MD5_HASH_InitStructure); + + /* Configure the number of valid bits in last word of the Key */ + HASH_SetLastWordValidBitsNbr(nbvalidbitskey); + + /* Write the Key */ + for(i=0; i
© COPYRIGHT 2011 STMicroelectronics
+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hash.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup HASH + * @brief HASH driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define SHA1BUSY_TIMEOUT ((uint32_t) 0x00010000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup HASH_Private_Functions + * @{ + */ + +/** @defgroup HASH_Group6 High Level SHA1 functions + * @brief High Level SHA1 Hash and HMAC functions + * +@verbatim + =============================================================================== + High Level SHA1 Hash and HMAC functions + =============================================================================== + + +@endverbatim + * @{ + */ + +/** + * @brief Compute the HASH SHA1 digest. + * @param Input: pointer to the Input buffer to be treated. + * @param Ilen: length of the Input buffer. + * @param Output: the returned digest + * @retval An ErrorStatus enumeration value: + * - SUCCESS: digest computation done + * - ERROR: digest computation failed + */ +ErrorStatus HASH_SHA1(uint8_t *Input, uint32_t Ilen, uint8_t Output[20]) +{ + HASH_InitTypeDef SHA1_HASH_InitStructure; + HASH_MsgDigest SHA1_MessageDigest; + __IO uint16_t nbvalidbitsdata = 0; + uint32_t i = 0; + __IO uint32_t counter = 0; + uint32_t busystatus = 0; + ErrorStatus status = SUCCESS; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + + /* Number of valid bits in last word of the Input data */ + nbvalidbitsdata = 8 * (Ilen % 4); + + /* HASH peripheral initialization */ + HASH_DeInit(); + + /* HASH Configuration */ + SHA1_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_SHA1; + SHA1_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH; + SHA1_HASH_InitStructure.HASH_DataType = HASH_DataType_8b; + HASH_Init(&SHA1_HASH_InitStructure); + + /* Configure the number of valid bits in last word of the data */ + HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); + + /* Write the Input block in the IN FIFO */ + for(i=0; i 64) + { + /* HMAC long Key */ + SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey; + } + else + { + /* HMAC short Key */ + SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey; + } + HASH_Init(&SHA1_HASH_InitStructure); + + /* Configure the number of valid bits in last word of the Key */ + HASH_SetLastWordValidBitsNbr(nbvalidbitskey); + + /* Write the Key */ + for(i=0; iGPIO_Mode = GPIO_Mode_AF + * - Select the type, pull-up/pull-down and output speed via + * GPIO_PuPd, GPIO_OType and GPIO_Speed members + * - Call GPIO_Init() function + * Recommended configuration is Push-Pull, Pull-up, Open-Drain. + * Add an external pull up if necessary (typically 4.7 KOhm). + * + * 4. Program the Mode, duty cycle , Own address, Ack, Speed and Acknowledged + * Address using the I2C_Init() function. + * + * 5. Optionally you can enable/configure the following parameters without + * re-initialization (i.e there is no need to call again I2C_Init() function): + * - Enable the acknowledge feature using I2C_AcknowledgeConfig() function + * - Enable the dual addressing mode using I2C_DualAddressCmd() function + * - Enable the general call using the I2C_GeneralCallCmd() function + * - Enable the clock stretching using I2C_StretchClockCmd() function + * - Enable the fast mode duty cycle using the I2C_FastModeDutyCycleConfig() + * function. + * - Configure the NACK position for Master Receiver mode in case of + * 2 bytes reception using the function I2C_NACKPositionConfig(). + * - Enable the PEC Calculation using I2C_CalculatePEC() function + * - For SMBus Mode: + * - Enable the Address Resolution Protocol (ARP) using I2C_ARPCmd() function + * - Configure the SMBusAlert pin using I2C_SMBusAlertConfig() function + * + * 6. Enable the NVIC and the corresponding interrupt using the function + * I2C_ITConfig() if you need to use interrupt mode. + * + * 7. When using the DMA mode + * - Configure the DMA using DMA_Init() function + * - Active the needed channel Request using I2C_DMACmd() or + * I2C_DMALastTransferCmd() function. + * @note When using DMA mode, I2C interrupts may be used at the same time to + * control the communication flow (Start/Stop/Ack... events and errors). + * + * 8. Enable the I2C using the I2C_Cmd() function. + * + * 9. Enable the DMA using the DMA_Cmd() function when using DMA mode in the + * transfers. + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_i2c.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup I2C + * @brief I2C driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +#define CR1_CLEAR_MASK ((uint16_t)0xFBF5) /*I2C_ClockSpeed)); + assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode)); + assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle)); + assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1)); + assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack)); + assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress)); + +/*---------------------------- I2Cx CR2 Configuration ------------------------*/ + /* Get the I2Cx CR2 value */ + tmpreg = I2Cx->CR2; + /* Clear frequency FREQ[5:0] bits */ + tmpreg &= (uint16_t)~((uint16_t)I2C_CR2_FREQ); + /* Get pclk1 frequency value */ + RCC_GetClocksFreq(&rcc_clocks); + pclk1 = rcc_clocks.PCLK1_Frequency; + /* Set frequency bits depending on pclk1 value */ + freqrange = (uint16_t)(pclk1 / 1000000); + tmpreg |= freqrange; + /* Write to I2Cx CR2 */ + I2Cx->CR2 = tmpreg; + +/*---------------------------- I2Cx CCR Configuration ------------------------*/ + /* Disable the selected I2C peripheral to configure TRISE */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PE); + /* Reset tmpreg value */ + /* Clear F/S, DUTY and CCR[11:0] bits */ + tmpreg = 0; + + /* Configure speed in standard mode */ + if (I2C_InitStruct->I2C_ClockSpeed <= 100000) + { + /* Standard mode speed calculate */ + result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1)); + /* Test if CCR value is under 0x4*/ + if (result < 0x04) + { + /* Set minimum allowed value */ + result = 0x04; + } + /* Set speed value for standard mode */ + tmpreg |= result; + /* Set Maximum Rise Time for standard mode */ + I2Cx->TRISE = freqrange + 1; + } + /* Configure speed in fast mode */ + /* To use the I2C at 400 KHz (in fast mode), the PCLK1 frequency (I2C peripheral + input clock) must be a multiple of 10 MHz */ + else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/ + { + if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2) + { + /* Fast mode speed calculate: Tlow/Thigh = 2 */ + result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3)); + } + else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/ + { + /* Fast mode speed calculate: Tlow/Thigh = 16/9 */ + result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25)); + /* Set DUTY bit */ + result |= I2C_DutyCycle_16_9; + } + + /* Test if CCR value is under 0x1*/ + if ((result & I2C_CCR_CCR) == 0) + { + /* Set minimum allowed value */ + result |= (uint16_t)0x0001; + } + /* Set speed value and set F/S bit for fast mode */ + tmpreg |= (uint16_t)(result | I2C_CCR_FS); + /* Set Maximum Rise Time for fast mode */ + I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1); + } + + /* Write to I2Cx CCR */ + I2Cx->CCR = tmpreg; + /* Enable the selected I2C peripheral */ + I2Cx->CR1 |= I2C_CR1_PE; + +/*---------------------------- I2Cx CR1 Configuration ------------------------*/ + /* Get the I2Cx CR1 value */ + tmpreg = I2Cx->CR1; + /* Clear ACK, SMBTYPE and SMBUS bits */ + tmpreg &= CR1_CLEAR_MASK; + /* Configure I2Cx: mode and acknowledgement */ + /* Set SMBTYPE and SMBUS bits according to I2C_Mode value */ + /* Set ACK bit according to I2C_Ack value */ + tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack); + /* Write to I2Cx CR1 */ + I2Cx->CR1 = tmpreg; + +/*---------------------------- I2Cx OAR1 Configuration -----------------------*/ + /* Set I2Cx Own Address1 and acknowledged address */ + I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1); +} + +/** + * @brief Fills each I2C_InitStruct member with its default value. + * @param I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized. + * @retval None + */ +void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct) +{ +/*---------------- Reset I2C init structure parameters values ----------------*/ + /* initialize the I2C_ClockSpeed member */ + I2C_InitStruct->I2C_ClockSpeed = 5000; + /* Initialize the I2C_Mode member */ + I2C_InitStruct->I2C_Mode = I2C_Mode_I2C; + /* Initialize the I2C_DutyCycle member */ + I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2; + /* Initialize the I2C_OwnAddress1 member */ + I2C_InitStruct->I2C_OwnAddress1 = 0; + /* Initialize the I2C_Ack member */ + I2C_InitStruct->I2C_Ack = I2C_Ack_Disable; + /* Initialize the I2C_AcknowledgedAddress member */ + I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; +} + +/** + * @brief Enables or disables the specified I2C peripheral. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C peripheral */ + I2Cx->CR1 |= I2C_CR1_PE; + } + else + { + /* Disable the selected I2C peripheral */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PE); + } +} + +/** + * @brief Generates I2Cx communication START condition. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C START condition generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Generate a START condition */ + I2Cx->CR1 |= I2C_CR1_START; + } + else + { + /* Disable the START condition generation */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_START); + } +} + +/** + * @brief Generates I2Cx communication STOP condition. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C STOP condition generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Generate a STOP condition */ + I2Cx->CR1 |= I2C_CR1_STOP; + } + else + { + /* Disable the STOP condition generation */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_STOP); + } +} + +/** + * @brief Transmits the address byte to select the slave device. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param Address: specifies the slave address which will be transmitted + * @param I2C_Direction: specifies whether the I2C device will be a Transmitter + * or a Receiver. + * This parameter can be one of the following values + * @arg I2C_Direction_Transmitter: Transmitter mode + * @arg I2C_Direction_Receiver: Receiver mode + * @retval None. + */ +void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_DIRECTION(I2C_Direction)); + /* Test on the direction to set/reset the read/write bit */ + if (I2C_Direction != I2C_Direction_Transmitter) + { + /* Set the address bit0 for read */ + Address |= I2C_OAR1_ADD0; + } + else + { + /* Reset the address bit0 for write */ + Address &= (uint8_t)~((uint8_t)I2C_OAR1_ADD0); + } + /* Send the address */ + I2Cx->DR = Address; +} + +/** + * @brief Enables or disables the specified I2C acknowledge feature. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C Acknowledgement. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the acknowledgement */ + I2Cx->CR1 |= I2C_CR1_ACK; + } + else + { + /* Disable the acknowledgement */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK); + } +} + +/** + * @brief Configures the specified I2C own address2. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param Address: specifies the 7bit I2C own address2. + * @retval None. + */ +void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address) +{ + uint16_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Get the old register value */ + tmpreg = I2Cx->OAR2; + + /* Reset I2Cx Own address2 bit [7:1] */ + tmpreg &= (uint16_t)~((uint16_t)I2C_OAR2_ADD2); + + /* Set I2Cx Own address2 */ + tmpreg |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE); + + /* Store the new register value */ + I2Cx->OAR2 = tmpreg; +} + +/** + * @brief Enables or disables the specified I2C dual addressing mode. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C dual addressing mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable dual addressing mode */ + I2Cx->OAR2 |= I2C_OAR2_ENDUAL; + } + else + { + /* Disable dual addressing mode */ + I2Cx->OAR2 &= (uint16_t)~((uint16_t)I2C_OAR2_ENDUAL); + } +} + +/** + * @brief Enables or disables the specified I2C general call feature. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C General call. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable generall call */ + I2Cx->CR1 |= I2C_CR1_ENGC; + } + else + { + /* Disable generall call */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENGC); + } +} + +/** + * @brief Enables or disables the specified I2C software reset. + * @note When software reset is enabled, the I2C IOs are released (this can + * be useful to recover from bus errors). + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C software reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Peripheral under reset */ + I2Cx->CR1 |= I2C_CR1_SWRST; + } + else + { + /* Peripheral not under reset */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_SWRST); + } +} + +/** + * @brief Enables or disables the specified I2C Clock stretching. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx Clock stretching. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState == DISABLE) + { + /* Enable the selected I2C Clock stretching */ + I2Cx->CR1 |= I2C_CR1_NOSTRETCH; + } + else + { + /* Disable the selected I2C Clock stretching */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_NOSTRETCH); + } +} + +/** + * @brief Selects the specified I2C fast mode duty cycle. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param I2C_DutyCycle: specifies the fast mode duty cycle. + * This parameter can be one of the following values: + * @arg I2C_DutyCycle_2: I2C fast mode Tlow/Thigh = 2 + * @arg I2C_DutyCycle_16_9: I2C fast mode Tlow/Thigh = 16/9 + * @retval None + */ +void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_DUTY_CYCLE(I2C_DutyCycle)); + if (I2C_DutyCycle != I2C_DutyCycle_16_9) + { + /* I2C fast mode Tlow/Thigh=2 */ + I2Cx->CCR &= I2C_DutyCycle_2; + } + else + { + /* I2C fast mode Tlow/Thigh=16/9 */ + I2Cx->CCR |= I2C_DutyCycle_16_9; + } +} + +/** + * @brief Selects the specified I2C NACK position in master receiver mode. + * @note This function is useful in I2C Master Receiver mode when the number + * of data to be received is equal to 2. In this case, this function + * should be called (with parameter I2C_NACKPosition_Next) before data + * reception starts,as described in the 2-byte reception procedure + * recommended in Reference Manual in Section: Master receiver. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param I2C_NACKPosition: specifies the NACK position. + * This parameter can be one of the following values: + * @arg I2C_NACKPosition_Next: indicates that the next byte will be the last + * received byte. + * @arg I2C_NACKPosition_Current: indicates that current byte is the last + * received byte. + * + * @note This function configures the same bit (POS) as I2C_PECPositionConfig() + * but is intended to be used in I2C mode while I2C_PECPositionConfig() + * is intended to used in SMBUS mode. + * + * @retval None + */ +void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_NACK_POSITION(I2C_NACKPosition)); + + /* Check the input parameter */ + if (I2C_NACKPosition == I2C_NACKPosition_Next) + { + /* Next byte in shift register is the last received byte */ + I2Cx->CR1 |= I2C_NACKPosition_Next; + } + else + { + /* Current byte in shift register is the last received byte */ + I2Cx->CR1 &= I2C_NACKPosition_Current; + } +} + +/** + * @brief Drives the SMBusAlert pin high or low for the specified I2C. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param I2C_SMBusAlert: specifies SMBAlert pin level. + * This parameter can be one of the following values: + * @arg I2C_SMBusAlert_Low: SMBAlert pin driven low + * @arg I2C_SMBusAlert_High: SMBAlert pin driven high + * @retval None + */ +void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_SMBUS_ALERT(I2C_SMBusAlert)); + if (I2C_SMBusAlert == I2C_SMBusAlert_Low) + { + /* Drive the SMBusAlert pin Low */ + I2Cx->CR1 |= I2C_SMBusAlert_Low; + } + else + { + /* Drive the SMBusAlert pin High */ + I2Cx->CR1 &= I2C_SMBusAlert_High; + } +} + +/** + * @brief Enables or disables the specified I2C ARP. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx ARP. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C ARP */ + I2Cx->CR1 |= I2C_CR1_ENARP; + } + else + { + /* Disable the selected I2C ARP */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENARP); + } +} +/** + * @} + */ + +/** @defgroup I2C_Group2 Data transfers functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + Data transfers functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Sends a data byte through the I2Cx peripheral. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param Data: Byte to be transmitted.. + * @retval None + */ +void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Write in the DR register the data to be sent */ + I2Cx->DR = Data; +} + +/** + * @brief Returns the most recent received data by the I2Cx peripheral. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @retval The value of the received data. + */ +uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Return the data in the DR register */ + return (uint8_t)I2Cx->DR; +} + +/** + * @} + */ + +/** @defgroup I2C_Group3 PEC management functions + * @brief PEC management functions + * +@verbatim + =============================================================================== + PEC management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified I2C PEC transfer. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C PEC transmission. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C PEC transmission */ + I2Cx->CR1 |= I2C_CR1_PEC; + } + else + { + /* Disable the selected I2C PEC transmission */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PEC); + } +} + +/** + * @brief Selects the specified I2C PEC position. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param I2C_PECPosition: specifies the PEC position. + * This parameter can be one of the following values: + * @arg I2C_PECPosition_Next: indicates that the next byte is PEC + * @arg I2C_PECPosition_Current: indicates that current byte is PEC + * + * @note This function configures the same bit (POS) as I2C_NACKPositionConfig() + * but is intended to be used in SMBUS mode while I2C_NACKPositionConfig() + * is intended to used in I2C mode. + * + * @retval None + */ +void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_PEC_POSITION(I2C_PECPosition)); + if (I2C_PECPosition == I2C_PECPosition_Next) + { + /* Next byte in shift register is PEC */ + I2Cx->CR1 |= I2C_PECPosition_Next; + } + else + { + /* Current byte in shift register is PEC */ + I2Cx->CR1 &= I2C_PECPosition_Current; + } +} + +/** + * @brief Enables or disables the PEC value calculation of the transferred bytes. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx PEC value calculation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C PEC calculation */ + I2Cx->CR1 |= I2C_CR1_ENPEC; + } + else + { + /* Disable the selected I2C PEC calculation */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENPEC); + } +} + +/** + * @brief Returns the PEC value for the specified I2C. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @retval The PEC value. + */ +uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Return the selected I2C PEC value */ + return ((I2Cx->SR2) >> 8); +} + +/** + * @} + */ + +/** @defgroup I2C_Group4 DMA transfers management functions + * @brief DMA transfers management functions + * +@verbatim + =============================================================================== + DMA transfers management functions + =============================================================================== + This section provides functions allowing to configure the I2C DMA channels + requests. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified I2C DMA requests. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C DMA transfer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C DMA requests */ + I2Cx->CR2 |= I2C_CR2_DMAEN; + } + else + { + /* Disable the selected I2C DMA requests */ + I2Cx->CR2 &= (uint16_t)~((uint16_t)I2C_CR2_DMAEN); + } +} + +/** + * @brief Specifies that the next DMA transfer is the last one. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C DMA last transfer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Next DMA transfer is the last transfer */ + I2Cx->CR2 |= I2C_CR2_LAST; + } + else + { + /* Next DMA transfer is not the last transfer */ + I2Cx->CR2 &= (uint16_t)~((uint16_t)I2C_CR2_LAST); + } +} + +/** + * @} + */ + +/** @defgroup I2C_Group5 Interrupts events and flags management functions + * @brief Interrupts, events and flags management functions + * +@verbatim + =============================================================================== + Interrupts, events and flags management functions + =============================================================================== + This section provides functions allowing to configure the I2C Interrupts + sources and check or clear the flags or pending bits status. + The user should identify which mode will be used in his application to manage + the communication: Polling mode, Interrupt mode or DMA mode. + + =============================================================================== + I2C State Monitoring Functions + =============================================================================== + This I2C driver provides three different ways for I2C state monitoring + depending on the application requirements and constraints: + + + 1. Basic state monitoring (Using I2C_CheckEvent() function) + ----------------------------------------------------------- + It compares the status registers (SR1 and SR2) content to a given event + (can be the combination of one or more flags). + It returns SUCCESS if the current status includes the given flags + and returns ERROR if one or more flags are missing in the current status. + + - When to use + - This function is suitable for most applications as well as for startup + activity since the events are fully described in the product reference + manual (RM0090). + - It is also suitable for users who need to define their own events. + + - Limitations + - If an error occurs (ie. error flags are set besides to the monitored + flags), the I2C_CheckEvent() function may return SUCCESS despite + the communication hold or corrupted real state. + In this case, it is advised to use error interrupts to monitor + the error events and handle them in the interrupt IRQ handler. + + @note + For error management, it is advised to use the following functions: + - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). + - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs. + Where x is the peripheral instance (I2C1, I2C2 ...) + - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the + I2Cx_ER_IRQHandler() function in order to determine which error occurred. + - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() + and/or I2C_GenerateStop() in order to clear the error flag and source + and return to correct communication status. + + + 2. Advanced state monitoring (Using the function I2C_GetLastEvent()) + -------------------------------------------------------------------- + Using the function I2C_GetLastEvent() which returns the image of both status + registers in a single word (uint32_t) (Status Register 2 value is shifted left + by 16 bits and concatenated to Status Register 1). + + - When to use + - This function is suitable for the same applications above but it + allows to overcome the mentioned limitation of I2C_GetFlagStatus() + function. + - The returned value could be compared to events already defined in + the library (stm32f4xx_i2c.h) or to custom values defined by user. + This function is suitable when multiple flags are monitored at the + same time. + - At the opposite of I2C_CheckEvent() function, this function allows + user to choose when an event is accepted (when all events flags are + set and no other flags are set or just when the needed flags are set + like I2C_CheckEvent() function. + + - Limitations + - User may need to define his own events. + - Same remark concerning the error management is applicable for this + function if user decides to check only regular communication flags + (and ignores error flags). + + + 3. Flag-based state monitoring (Using the function I2C_GetFlagStatus()) + ----------------------------------------------------------------------- + + Using the function I2C_GetFlagStatus() which simply returns the status of + one single flag (ie. I2C_FLAG_RXNE ...). + + - When to use + - This function could be used for specific applications or in debug + phase. + - It is suitable when only one flag checking is needed (most I2C + events are monitored through multiple flags). + - Limitations: + - When calling this function, the Status register is accessed. + Some flags are cleared when the status register is accessed. + So checking the status of one Flag, may clear other ones. + - Function may need to be called twice or more in order to monitor + one single event. + + For detailed description of Events, please refer to section I2C_Events in + stm32f4xx_i2c.h file. + +@endverbatim + * @{ + */ + +/** + * @brief Reads the specified I2C register and returns its value. + * @param I2C_Register: specifies the register to read. + * This parameter can be one of the following values: + * @arg I2C_Register_CR1: CR1 register. + * @arg I2C_Register_CR2: CR2 register. + * @arg I2C_Register_OAR1: OAR1 register. + * @arg I2C_Register_OAR2: OAR2 register. + * @arg I2C_Register_DR: DR register. + * @arg I2C_Register_SR1: SR1 register. + * @arg I2C_Register_SR2: SR2 register. + * @arg I2C_Register_CCR: CCR register. + * @arg I2C_Register_TRISE: TRISE register. + * @retval The value of the read register. + */ +uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_REGISTER(I2C_Register)); + + tmp = (uint32_t) I2Cx; + tmp += I2C_Register; + + /* Return the selected register value */ + return (*(__IO uint16_t *) tmp); +} + +/** + * @brief Enables or disables the specified I2C interrupts. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param I2C_IT: specifies the I2C interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg I2C_IT_BUF: Buffer interrupt mask + * @arg I2C_IT_EVT: Event interrupt mask + * @arg I2C_IT_ERR: Error interrupt mask + * @param NewState: new state of the specified I2C interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_I2C_CONFIG_IT(I2C_IT)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C interrupts */ + I2Cx->CR2 |= I2C_IT; + } + else + { + /* Disable the selected I2C interrupts */ + I2Cx->CR2 &= (uint16_t)~I2C_IT; + } +} + +/* + =============================================================================== + 1. Basic state monitoring + =============================================================================== + */ + +/** + * @brief Checks whether the last I2Cx Event is equal to the one passed + * as parameter. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param I2C_EVENT: specifies the event to be checked. + * This parameter can be one of the following values: + * @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: EV1 + * @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: EV1 + * @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED: EV1 + * @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED: EV1 + * @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED: EV1 + * @arg I2C_EVENT_SLAVE_BYTE_RECEIVED: EV2 + * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF): EV2 + * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL): EV2 + * @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED: EV3 + * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF): EV3 + * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL): EV3 + * @arg I2C_EVENT_SLAVE_ACK_FAILURE: EV3_2 + * @arg I2C_EVENT_SLAVE_STOP_DETECTED: EV4 + * @arg I2C_EVENT_MASTER_MODE_SELECT: EV5 + * @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: EV6 + * @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: EV6 + * @arg I2C_EVENT_MASTER_BYTE_RECEIVED: EV7 + * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING: EV8 + * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED: EV8_2 + * @arg I2C_EVENT_MASTER_MODE_ADDRESS10: EV9 + * + * @note For detailed description of Events, please refer to section I2C_Events + * in stm32f4xx_i2c.h file. + * + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Last event is equal to the I2C_EVENT + * - ERROR: Last event is different from the I2C_EVENT + */ +ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) +{ + uint32_t lastevent = 0; + uint32_t flag1 = 0, flag2 = 0; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_EVENT(I2C_EVENT)); + + /* Read the I2Cx status register */ + flag1 = I2Cx->SR1; + flag2 = I2Cx->SR2; + flag2 = flag2 << 16; + + /* Get the last event value from I2C status register */ + lastevent = (flag1 | flag2) & FLAG_MASK; + + /* Check whether the last event contains the I2C_EVENT */ + if ((lastevent & I2C_EVENT) == I2C_EVENT) + { + /* SUCCESS: last event is equal to I2C_EVENT */ + status = SUCCESS; + } + else + { + /* ERROR: last event is different from I2C_EVENT */ + status = ERROR; + } + /* Return status */ + return status; +} + +/* + =============================================================================== + 2. Advanced state monitoring + =============================================================================== + */ + +/** + * @brief Returns the last I2Cx Event. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * + * @note For detailed description of Events, please refer to section I2C_Events + * in stm32f4xx_i2c.h file. + * + * @retval The last event + */ +uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx) +{ + uint32_t lastevent = 0; + uint32_t flag1 = 0, flag2 = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Read the I2Cx status register */ + flag1 = I2Cx->SR1; + flag2 = I2Cx->SR2; + flag2 = flag2 << 16; + + /* Get the last event value from I2C status register */ + lastevent = (flag1 | flag2) & FLAG_MASK; + + /* Return status */ + return lastevent; +} + +/* + =============================================================================== + 3. Flag-based state monitoring + =============================================================================== + */ + +/** + * @brief Checks whether the specified I2C flag is set or not. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param I2C_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg I2C_FLAG_DUALF: Dual flag (Slave mode) + * @arg I2C_FLAG_SMBHOST: SMBus host header (Slave mode) + * @arg I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode) + * @arg I2C_FLAG_GENCALL: General call header flag (Slave mode) + * @arg I2C_FLAG_TRA: Transmitter/Receiver flag + * @arg I2C_FLAG_BUSY: Bus busy flag + * @arg I2C_FLAG_MSL: Master/Slave flag + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_FLAG_BERR: Bus error flag + * @arg I2C_FLAG_TXE: Data register empty flag (Transmitter) + * @arg I2C_FLAG_RXNE: Data register not empty (Receiver) flag + * @arg I2C_FLAG_STOPF: Stop detection flag (Slave mode) + * @arg I2C_FLAG_ADD10: 10-bit header sent flag (Master mode) + * @arg I2C_FLAG_BTF: Byte transfer finished flag + * @arg I2C_FLAG_ADDR: Address sent flag (Master mode) "ADSL" + * Address matched flag (Slave mode)"ENDAD" + * @arg I2C_FLAG_SB: Start bit flag (Master mode) + * @retval The new state of I2C_FLAG (SET or RESET). + */ +FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) +{ + FlagStatus bitstatus = RESET; + __IO uint32_t i2creg = 0, i2cxbase = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_GET_FLAG(I2C_FLAG)); + + /* Get the I2Cx peripheral base address */ + i2cxbase = (uint32_t)I2Cx; + + /* Read flag register index */ + i2creg = I2C_FLAG >> 28; + + /* Get bit[23:0] of the flag */ + I2C_FLAG &= FLAG_MASK; + + if(i2creg != 0) + { + /* Get the I2Cx SR1 register address */ + i2cxbase += 0x14; + } + else + { + /* Flag in I2Cx SR2 Register */ + I2C_FLAG = (uint32_t)(I2C_FLAG >> 16); + /* Get the I2Cx SR2 register address */ + i2cxbase += 0x18; + } + + if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET) + { + /* I2C_FLAG is set */ + bitstatus = SET; + } + else + { + /* I2C_FLAG is reset */ + bitstatus = RESET; + } + + /* Return the I2C_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the I2Cx's pending flags. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param I2C_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_FLAG_BERR: Bus error flag + * + * @note STOPF (STOP detection) is cleared by software sequence: a read operation + * to I2C_SR1 register (I2C_GetFlagStatus()) followed by a write operation + * to I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). + * @note ADD10 (10-bit header sent) is cleared by software sequence: a read + * operation to I2C_SR1 (I2C_GetFlagStatus()) followed by writing the + * second byte of the address in DR register. + * @note BTF (Byte Transfer Finished) is cleared by software sequence: a read + * operation to I2C_SR1 register (I2C_GetFlagStatus()) followed by a + * read/write to I2C_DR register (I2C_SendData()). + * @note ADDR (Address sent) is cleared by software sequence: a read operation to + * I2C_SR1 register (I2C_GetFlagStatus()) followed by a read operation to + * I2C_SR2 register ((void)(I2Cx->SR2)). + * @note SB (Start Bit) is cleared software sequence: a read operation to I2C_SR1 + * register (I2C_GetFlagStatus()) followed by a write operation to I2C_DR + * register (I2C_SendData()). + * + * @retval None + */ +void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) +{ + uint32_t flagpos = 0; + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG)); + /* Get the I2C flag position */ + flagpos = I2C_FLAG & FLAG_MASK; + /* Clear the selected I2C flag */ + I2Cx->SR1 = (uint16_t)~flagpos; +} + +/** + * @brief Checks whether the specified I2C interrupt has occurred or not. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param I2C_IT: specifies the interrupt source to check. + * This parameter can be one of the following values: + * @arg I2C_IT_SMBALERT: SMBus Alert flag + * @arg I2C_IT_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_IT_PECERR: PEC error in reception flag + * @arg I2C_IT_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_IT_AF: Acknowledge failure flag + * @arg I2C_IT_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_IT_BERR: Bus error flag + * @arg I2C_IT_TXE: Data register empty flag (Transmitter) + * @arg I2C_IT_RXNE: Data register not empty (Receiver) flag + * @arg I2C_IT_STOPF: Stop detection flag (Slave mode) + * @arg I2C_IT_ADD10: 10-bit header sent flag (Master mode) + * @arg I2C_IT_BTF: Byte transfer finished flag + * @arg I2C_IT_ADDR: Address sent flag (Master mode) "ADSL" + * Address matched flag (Slave mode)"ENDAD" + * @arg I2C_IT_SB: Start bit flag (Master mode) + * @retval The new state of I2C_IT (SET or RESET). + */ +ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT) +{ + ITStatus bitstatus = RESET; + uint32_t enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_GET_IT(I2C_IT)); + + /* Check if the interrupt source is enabled or not */ + enablestatus = (uint32_t)(((I2C_IT & ITEN_MASK) >> 16) & (I2Cx->CR2)) ; + + /* Get bit[23:0] of the flag */ + I2C_IT &= FLAG_MASK; + + /* Check the status of the specified I2C flag */ + if (((I2Cx->SR1 & I2C_IT) != (uint32_t)RESET) && enablestatus) + { + /* I2C_IT is set */ + bitstatus = SET; + } + else + { + /* I2C_IT is reset */ + bitstatus = RESET; + } + /* Return the I2C_IT status */ + return bitstatus; +} + +/** + * @brief Clears the I2Cx's interrupt pending bits. + * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. + * @param I2C_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg I2C_IT_SMBALERT: SMBus Alert interrupt + * @arg I2C_IT_TIMEOUT: Timeout or Tlow error interrupt + * @arg I2C_IT_PECERR: PEC error in reception interrupt + * @arg I2C_IT_OVR: Overrun/Underrun interrupt (Slave mode) + * @arg I2C_IT_AF: Acknowledge failure interrupt + * @arg I2C_IT_ARLO: Arbitration lost interrupt (Master mode) + * @arg I2C_IT_BERR: Bus error interrupt + * + * @note STOPF (STOP detection) is cleared by software sequence: a read operation + * to I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to + * I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). + * @note ADD10 (10-bit header sent) is cleared by software sequence: a read + * operation to I2C_SR1 (I2C_GetITStatus()) followed by writing the second + * byte of the address in I2C_DR register. + * @note BTF (Byte Transfer Finished) is cleared by software sequence: a read + * operation to I2C_SR1 register (I2C_GetITStatus()) followed by a + * read/write to I2C_DR register (I2C_SendData()). + * @note ADDR (Address sent) is cleared by software sequence: a read operation to + * I2C_SR1 register (I2C_GetITStatus()) followed by a read operation to + * I2C_SR2 register ((void)(I2Cx->SR2)). + * @note SB (Start Bit) is cleared by software sequence: a read operation to + * I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to + * I2C_DR register (I2C_SendData()). + * @retval None + */ +void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT) +{ + uint32_t flagpos = 0; + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLEAR_IT(I2C_IT)); + + /* Get the I2C flag position */ + flagpos = I2C_IT & FLAG_MASK; + + /* Clear the selected I2C flag */ + I2Cx->SR1 = (uint16_t)~flagpos; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_iwdg.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_iwdg.c new file mode 100644 index 0000000..a4fddec --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_iwdg.c @@ -0,0 +1,263 @@ +/** + ****************************************************************************** + * @file stm32f4xx_iwdg.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Independent watchdog (IWDG) peripheral: + * - Prescaler and Counter configuration + * - IWDG activation + * - Flag management + * + * @verbatim + * + * =================================================================== + * IWDG features + * =================================================================== + * + * The IWDG can be started by either software or hardware (configurable + * through option byte). + * + * The IWDG is clocked by its own dedicated low-speed clock (LSI) and + * thus stays active even if the main clock fails. + * Once the IWDG is started, the LSI is forced ON and cannot be disabled + * (LSI cannot be disabled too), and the counter starts counting down from + * the reset value of 0xFFF. When it reaches the end of count value (0x000) + * a system reset is generated. + * The IWDG counter should be reloaded at regular intervals to prevent + * an MCU reset. + * + * The IWDG is implemented in the VDD voltage domain that is still functional + * in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY). + * + * IWDGRST flag in RCC_CSR register can be used to inform when a IWDG + * reset occurs. + * + * Min-max timeout value @32KHz (LSI): ~125us / ~32.7s + * The IWDG timeout may vary due to LSI frequency dispersion. STM32F4xx + * devices provide the capability to measure the LSI frequency (LSI clock + * connected internally to TIM5 CH4 input capture). The measured value + * can be used to have an IWDG timeout with an acceptable accuracy. + * For more information, please refer to the STM32F4xx Reference manual + * + * + * =================================================================== + * How to use this driver + * =================================================================== + * 1. Enable write access to IWDG_PR and IWDG_RLR registers using + * IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable) function + * + * 2. Configure the IWDG prescaler using IWDG_SetPrescaler() function + * + * 3. Configure the IWDG counter value using IWDG_SetReload() function. + * This value will be loaded in the IWDG counter each time the counter + * is reloaded, then the IWDG will start counting down from this value. + * + * 4. Start the IWDG using IWDG_Enable() function, when the IWDG is used + * in software mode (no need to enable the LSI, it will be enabled + * by hardware) + * + * 5. Then the application program must reload the IWDG counter at regular + * intervals during normal operation to prevent an MCU reset, using + * IWDG_ReloadCounter() function. + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_iwdg.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup IWDG + * @brief IWDG driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* KR register bit mask */ +#define KR_KEY_RELOAD ((uint16_t)0xAAAA) +#define KR_KEY_ENABLE ((uint16_t)0xCCCC) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup IWDG_Private_Functions + * @{ + */ + +/** @defgroup IWDG_Group1 Prescaler and Counter configuration functions + * @brief Prescaler and Counter configuration functions + * +@verbatim + =============================================================================== + Prescaler and Counter configuration functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables write access to IWDG_PR and IWDG_RLR registers. + * @param IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers. + * This parameter can be one of the following values: + * @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers + * @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers + * @retval None + */ +void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess) +{ + /* Check the parameters */ + assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess)); + IWDG->KR = IWDG_WriteAccess; +} + +/** + * @brief Sets IWDG Prescaler value. + * @param IWDG_Prescaler: specifies the IWDG Prescaler value. + * This parameter can be one of the following values: + * @arg IWDG_Prescaler_4: IWDG prescaler set to 4 + * @arg IWDG_Prescaler_8: IWDG prescaler set to 8 + * @arg IWDG_Prescaler_16: IWDG prescaler set to 16 + * @arg IWDG_Prescaler_32: IWDG prescaler set to 32 + * @arg IWDG_Prescaler_64: IWDG prescaler set to 64 + * @arg IWDG_Prescaler_128: IWDG prescaler set to 128 + * @arg IWDG_Prescaler_256: IWDG prescaler set to 256 + * @retval None + */ +void IWDG_SetPrescaler(uint8_t IWDG_Prescaler) +{ + /* Check the parameters */ + assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler)); + IWDG->PR = IWDG_Prescaler; +} + +/** + * @brief Sets IWDG Reload value. + * @param Reload: specifies the IWDG Reload value. + * This parameter must be a number between 0 and 0x0FFF. + * @retval None + */ +void IWDG_SetReload(uint16_t Reload) +{ + /* Check the parameters */ + assert_param(IS_IWDG_RELOAD(Reload)); + IWDG->RLR = Reload; +} + +/** + * @brief Reloads IWDG counter with value defined in the reload register + * (write access to IWDG_PR and IWDG_RLR registers disabled). + * @param None + * @retval None + */ +void IWDG_ReloadCounter(void) +{ + IWDG->KR = KR_KEY_RELOAD; +} + +/** + * @} + */ + +/** @defgroup IWDG_Group2 IWDG activation function + * @brief IWDG activation function + * +@verbatim + =============================================================================== + IWDG activation function + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled). + * @param None + * @retval None + */ +void IWDG_Enable(void) +{ + IWDG->KR = KR_KEY_ENABLE; +} + +/** + * @} + */ + +/** @defgroup IWDG_Group3 Flag management function + * @brief Flag management function + * +@verbatim + =============================================================================== + Flag management function + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Checks whether the specified IWDG flag is set or not. + * @param IWDG_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg IWDG_FLAG_PVU: Prescaler Value Update on going + * @arg IWDG_FLAG_RVU: Reload Value Update on going + * @retval The new state of IWDG_FLAG (SET or RESET). + */ +FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_IWDG_FLAG(IWDG_FLAG)); + if ((IWDG->SR & IWDG_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c new file mode 100644 index 0000000..9a14f55 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c @@ -0,0 +1,656 @@ +/** + ****************************************************************************** + * @file stm32f4xx_pwr.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Power Controller (PWR) peripheral: + * - Backup Domain Access + * - PVD configuration + * - WakeUp pin configuration + * - Main and Backup Regulators configuration + * - FLASH Power Down configuration + * - Low Power modes configuration + * - Flags management + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_pwr.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup PWR + * @brief PWR driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* --------- PWR registers bit address in the alias region ---------- */ +#define PWR_OFFSET (PWR_BASE - PERIPH_BASE) + +/* --- CR Register ---*/ + +/* Alias word address of DBP bit */ +#define CR_OFFSET (PWR_OFFSET + 0x00) +#define DBP_BitNumber 0x08 +#define CR_DBP_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (DBP_BitNumber * 4)) + +/* Alias word address of PVDE bit */ +#define PVDE_BitNumber 0x04 +#define CR_PVDE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PVDE_BitNumber * 4)) + +/* Alias word address of FPDS bit */ +#define FPDS_BitNumber 0x09 +#define CR_FPDS_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (FPDS_BitNumber * 4)) + +/* Alias word address of PMODE bit */ +#define PMODE_BitNumber 0x0E +#define CR_PMODE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PMODE_BitNumber * 4)) + + +/* --- CSR Register ---*/ + +/* Alias word address of EWUP bit */ +#define CSR_OFFSET (PWR_OFFSET + 0x04) +#define EWUP_BitNumber 0x08 +#define CSR_EWUP_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (EWUP_BitNumber * 4)) + +/* Alias word address of BRE bit */ +#define BRE_BitNumber 0x09 +#define CSR_BRE_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (BRE_BitNumber * 4)) + +/* ------------------ PWR registers bit mask ------------------------ */ + +/* CR register bit mask */ +#define CR_DS_MASK ((uint32_t)0xFFFFFFFC) +#define CR_PLS_MASK ((uint32_t)0xFFFFFF1F) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup PWR_Private_Functions + * @{ + */ + +/** @defgroup PWR_Group1 Backup Domain Access function + * @brief Backup Domain Access function + * +@verbatim + =============================================================================== + Backup Domain Access function + =============================================================================== + + After reset, the backup domain (RTC registers, RTC backup data + registers and backup SRAM) is protected against possible unwanted + write accesses. + To enable access to the RTC Domain and RTC registers, proceed as follows: + - Enable the Power Controller (PWR) APB1 interface clock using the + RCC_APB1PeriphClockCmd() function. + - Enable access to RTC domain using the PWR_BackupAccessCmd() function. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the PWR peripheral registers to their default reset values. + * @param None + * @retval None + */ +void PWR_DeInit(void) +{ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE); +} + +/** + * @brief Enables or disables access to the backup domain (RTC registers, RTC + * backup data registers and backup SRAM). + * @note If the HSE divided by 2, 3, ..31 is used as the RTC clock, the + * Backup Domain Access should be kept enabled. + * @param NewState: new state of the access to the backup domain. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_BackupAccessCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_DBP_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup PWR_Group2 PVD configuration functions + * @brief PVD configuration functions + * +@verbatim + =============================================================================== + PVD configuration functions + =============================================================================== + + - The PVD is used to monitor the VDD power supply by comparing it to a threshold + selected by the PVD Level (PLS[2:0] bits in the PWR_CR). + - A PVDO flag is available to indicate if VDD/VDDA is higher or lower than the + PVD threshold. This event is internally connected to the EXTI line16 + and can generate an interrupt if enabled through the EXTI registers. + - The PVD is stopped in Standby mode. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD). + * @param PWR_PVDLevel: specifies the PVD detection level + * This parameter can be one of the following values: + * @arg PWR_PVDLevel_0: PVD detection level set to 2.0V + * @arg PWR_PVDLevel_1: PVD detection level set to 2.2V + * @arg PWR_PVDLevel_2: PVD detection level set to 2.3V + * @arg PWR_PVDLevel_3: PVD detection level set to 2.5V + * @arg PWR_PVDLevel_4: PVD detection level set to 2.7V + * @arg PWR_PVDLevel_5: PVD detection level set to 2.8V + * @arg PWR_PVDLevel_6: PVD detection level set to 2.9V + * @arg PWR_PVDLevel_7: PVD detection level set to 3.0V + * @note Refer to the electrical characteristics of you device datasheet for more details. + * @retval None + */ +void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_PWR_PVD_LEVEL(PWR_PVDLevel)); + + tmpreg = PWR->CR; + + /* Clear PLS[7:5] bits */ + tmpreg &= CR_PLS_MASK; + + /* Set PLS[7:5] bits according to PWR_PVDLevel value */ + tmpreg |= PWR_PVDLevel; + + /* Store the new value */ + PWR->CR = tmpreg; +} + +/** + * @brief Enables or disables the Power Voltage Detector(PVD). + * @param NewState: new state of the PVD. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_PVDCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup PWR_Group3 WakeUp pin configuration functions + * @brief WakeUp pin configuration functions + * +@verbatim + =============================================================================== + WakeUp pin configuration functions + =============================================================================== + + - WakeUp pin is used to wakeup the system from Standby mode. This pin is + forced in input pull down configuration and is active on rising edges. + - There is only one WakeUp pin: WakeUp Pin 1 on PA.00. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the WakeUp Pin functionality. + * @param NewState: new state of the WakeUp Pin functionality. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_WakeUpPinCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CSR_EWUP_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup PWR_Group4 Main and Backup Regulators configuration functions + * @brief Main and Backup Regulators configuration functions + * +@verbatim + =============================================================================== + Main and Backup Regulators configuration functions + =============================================================================== + + - The backup domain includes 4 Kbytes of backup SRAM accessible only from the + CPU, and address in 32-bit, 16-bit or 8-bit mode. Its content is retained + even in Standby or VBAT mode when the low power backup regulator is enabled. + It can be considered as an internal EEPROM when VBAT is always present. + You can use the PWR_BackupRegulatorCmd() function to enable the low power + backup regulator and use the PWR_GetFlagStatus(PWR_FLAG_BRR) to check if it is + ready or not. + + - When the backup domain is supplied by VDD (analog switch connected to VDD) + the backup SRAM is powered from VDD which replaces the VBAT power supply to + save battery life. + + - The backup SRAM is not mass erased by an tamper event. It is read protected + to prevent confidential data, such as cryptographic private key, from being + accessed. The backup SRAM can be erased only through the Flash interface when + a protection level change from level 1 to level 0 is requested. + Refer to the description of Read protection (RDP) in the Flash programming manual. + + - The main internal regulator can be configured to have a tradeoff between performance + and power consumption when the device does not operate at the maximum frequency. + This is done through PWR_MainRegulatorModeConfig() function which configure VOS bit + in PWR_CR register: + - When this bit is set (Regulator voltage output Scale 1 mode selected) the System + frequency can go up to 168 MHz. + - When this bit is reset (Regulator voltage output Scale 2 mode selected) the System + frequency can go up to 144 MHz. + Refer to the datasheets for more details. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the Backup Regulator. + * @param NewState: new state of the Backup Regulator. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_BackupRegulatorCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CSR_BRE_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the main internal regulator output voltage. + * @param PWR_Regulator_Voltage: specifies the regulator output voltage to achieve + * a tradeoff between performance and power consumption when the device does + * not operate at the maximum frequency (refer to the datasheets for more details). + * This parameter can be one of the following values: + * @arg PWR_Regulator_Voltage_Scale1: Regulator voltage output Scale 1 mode, + * System frequency up to 168 MHz. + * @arg PWR_Regulator_Voltage_Scale2: Regulator voltage output Scale 2 mode, + * System frequency up to 144 MHz. + * @retval None + */ +void PWR_MainRegulatorModeConfig(uint32_t PWR_Regulator_Voltage) +{ + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR_VOLTAGE(PWR_Regulator_Voltage)); + + if (PWR_Regulator_Voltage == PWR_Regulator_Voltage_Scale2) + { + PWR->CR &= ~PWR_Regulator_Voltage_Scale1; + } + else + { + PWR->CR |= PWR_Regulator_Voltage_Scale1; + } +} + +/** + * @} + */ + +/** @defgroup PWR_Group5 FLASH Power Down configuration functions + * @brief FLASH Power Down configuration functions + * +@verbatim + =============================================================================== + FLASH Power Down configuration functions + =============================================================================== + + - By setting the FPDS bit in the PWR_CR register by using the PWR_FlashPowerDownCmd() + function, the Flash memory also enters power down mode when the device enters + Stop mode. When the Flash memory is in power down mode, an additional startup + delay is incurred when waking up from Stop mode. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the Flash Power Down in STOP mode. + * @param NewState: new state of the Flash power mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_FlashPowerDownCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_FPDS_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup PWR_Group6 Low Power modes configuration functions + * @brief Low Power modes configuration functions + * +@verbatim + =============================================================================== + Low Power modes configuration functions + =============================================================================== + + The devices feature 3 low-power modes: + - Sleep mode: Cortex-M4 core stopped, peripherals kept running. + - Stop mode: all clocks are stopped, regulator running, regulator in low power mode + - Standby mode: 1.2V domain powered off. + + Sleep mode + =========== + - Entry: + - The Sleep mode is entered by using the __WFI() or __WFE() functions. + - Exit: + - Any peripheral interrupt acknowledged by the nested vectored interrupt + controller (NVIC) can wake up the device from Sleep mode. + + Stop mode + ========== + In Stop mode, all clocks in the 1.2V domain are stopped, the PLL, the HSI, + and the HSE RC oscillators are disabled. Internal SRAM and register contents + are preserved. + The voltage regulator can be configured either in normal or low-power mode. + To minimize the consumption In Stop mode, FLASH can be powered off before + entering the Stop mode. It can be switched on again by software after exiting + the Stop mode using the PWR_FlashPowerDownCmd() function. + + - Entry: + - The Stop mode is entered using the PWR_EnterSTOPMode(PWR_Regulator_LowPower,) + function with regulator in LowPower or with Regulator ON. + - Exit: + - Any EXTI Line (Internal or External) configured in Interrupt/Event mode. + + Standby mode + ============ + The Standby mode allows to achieve the lowest power consumption. It is based + on the Cortex-M4 deepsleep mode, with the voltage regulator disabled. + The 1.2V domain is consequently powered off. The PLL, the HSI oscillator and + the HSE oscillator are also switched off. SRAM and register contents are lost + except for the RTC registers, RTC backup registers, backup SRAM and Standby + circuitry. + + The voltage regulator is OFF. + + - Entry: + - The Standby mode is entered using the PWR_EnterSTANDBYMode() function. + - Exit: + - WKUP pin rising edge, RTC alarm (Alarm A and Alarm B), RTC wakeup, + tamper event, time-stamp event, external reset in NRST pin, IWDG reset. + + Auto-wakeup (AWU) from low-power mode + ===================================== + The MCU can be woken up from low-power mode by an RTC Alarm event, an RTC + Wakeup event, a tamper event, a time-stamp event, or a comparator event, + without depending on an external interrupt (Auto-wakeup mode). + + - RTC auto-wakeup (AWU) from the Stop mode + ---------------------------------------- + + - To wake up from the Stop mode with an RTC alarm event, it is necessary to: + - Configure the EXTI Line 17 to be sensitive to rising edges (Interrupt + or Event modes) using the EXTI_Init() function. + - Enable the RTC Alarm Interrupt using the RTC_ITConfig() function + - Configure the RTC to generate the RTC alarm using the RTC_SetAlarm() + and RTC_AlarmCmd() functions. + - To wake up from the Stop mode with an RTC Tamper or time stamp event, it + is necessary to: + - Configure the EXTI Line 21 to be sensitive to rising edges (Interrupt + or Event modes) using the EXTI_Init() function. + - Enable the RTC Tamper or time stamp Interrupt using the RTC_ITConfig() + function + - Configure the RTC to detect the tamper or time stamp event using the + RTC_TimeStampConfig(), RTC_TamperTriggerConfig() and RTC_TamperCmd() + functions. + - To wake up from the Stop mode with an RTC WakeUp event, it is necessary to: + - Configure the EXTI Line 22 to be sensitive to rising edges (Interrupt + or Event modes) using the EXTI_Init() function. + - Enable the RTC WakeUp Interrupt using the RTC_ITConfig() function + - Configure the RTC to generate the RTC WakeUp event using the RTC_WakeUpClockConfig(), + RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions. + + - RTC auto-wakeup (AWU) from the Standby mode + ------------------------------------------- + - To wake up from the Standby mode with an RTC alarm event, it is necessary to: + - Enable the RTC Alarm Interrupt using the RTC_ITConfig() function + - Configure the RTC to generate the RTC alarm using the RTC_SetAlarm() + and RTC_AlarmCmd() functions. + - To wake up from the Standby mode with an RTC Tamper or time stamp event, it + is necessary to: + - Enable the RTC Tamper or time stamp Interrupt using the RTC_ITConfig() + function + - Configure the RTC to detect the tamper or time stamp event using the + RTC_TimeStampConfig(), RTC_TamperTriggerConfig() and RTC_TamperCmd() + functions. + - To wake up from the Standby mode with an RTC WakeUp event, it is necessary to: + - Enable the RTC WakeUp Interrupt using the RTC_ITConfig() function + - Configure the RTC to generate the RTC WakeUp event using the RTC_WakeUpClockConfig(), + RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions. + +@endverbatim + * @{ + */ + +/** + * @brief Enters STOP mode. + * + * @note In Stop mode, all I/O pins keep the same state as in Run mode. + * @note When exiting Stop mode by issuing an interrupt or a wakeup event, + * the HSI RC oscillator is selected as system clock. + * @note When the voltage regulator operates in low power mode, an additional + * startup delay is incurred when waking up from Stop mode. + * By keeping the internal regulator ON during Stop mode, the consumption + * is higher although the startup time is reduced. + * + * @param PWR_Regulator: specifies the regulator state in STOP mode. + * This parameter can be one of the following values: + * @arg PWR_Regulator_ON: STOP mode with regulator ON + * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode + * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. + * This parameter can be one of the following values: + * @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction + * @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction + * @retval None + */ +void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR(PWR_Regulator)); + assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); + + /* Select the regulator state in STOP mode ---------------------------------*/ + tmpreg = PWR->CR; + /* Clear PDDS and LPDSR bits */ + tmpreg &= CR_DS_MASK; + + /* Set LPDSR bit according to PWR_Regulator value */ + tmpreg |= PWR_Regulator; + + /* Store the new value */ + PWR->CR = tmpreg; + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* Select STOP mode entry --------------------------------------------------*/ + if(PWR_STOPEntry == PWR_STOPEntry_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else + { + /* Request Wait For Event */ + __WFE(); + } + /* Reset SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); +} + +/** + * @brief Enters STANDBY mode. + * @note In Standby mode, all I/O pins are high impedance except for: + * - Reset pad (still available) + * - RTC_AF1 pin (PC13) if configured for tamper, time-stamp, RTC + * Alarm out, or RTC clock calibration out. + * - RTC_AF2 pin (PI8) if configured for tamper or time-stamp. + * - WKUP pin 1 (PA0) if enabled. + * @param None + * @retval None + */ +void PWR_EnterSTANDBYMode(void) +{ + /* Clear Wakeup flag */ + PWR->CR |= PWR_CR_CWUF; + + /* Select STANDBY mode */ + PWR->CR |= PWR_CR_PDDS; + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + +/* This option is used to ensure that store operations are completed */ +#if defined ( __CC_ARM ) + __force_stores(); +#endif + /* Request Wait For Interrupt */ + __WFI(); +} + +/** + * @} + */ + +/** @defgroup PWR_Group7 Flags management functions + * @brief Flags management functions + * +@verbatim + =============================================================================== + Flags management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Checks whether the specified PWR flag is set or not. + * @param PWR_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup event + * was received from the WKUP pin or from the RTC alarm (Alarm A + * or Alarm B), RTC Tamper event, RTC TimeStamp event or RTC Wakeup. + * An additional wakeup event is detected if the WKUP pin is enabled + * (by setting the EWUP bit) when the WKUP pin level is already high. + * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the system was + * resumed from StandBy mode. + * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD is enabled + * by the PWR_PVDCmd() function. The PVD is stopped by Standby mode + * For this reason, this bit is equal to 0 after Standby or reset + * until the PVDE bit is set. + * @arg PWR_FLAG_BRR: Backup regulator ready flag. This bit is not reset + * when the device wakes up from Standby mode or by a system reset + * or power reset. + * @arg PWR_FLAG_VOSRDY: This flag indicates that the Regulator voltage + * scaling output selection is ready. + * @retval The new state of PWR_FLAG (SET or RESET). + */ +FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_PWR_GET_FLAG(PWR_FLAG)); + + if ((PWR->CSR & PWR_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @brief Clears the PWR's pending flags. + * @param PWR_FLAG: specifies the flag to clear. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag + * @arg PWR_FLAG_SB: StandBy flag + * @retval None + */ +void PWR_ClearFlag(uint32_t PWR_FLAG) +{ + /* Check the parameters */ + assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG)); + + PWR->CR |= PWR_FLAG << 2; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c new file mode 100644 index 0000000..8776374 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c @@ -0,0 +1,1808 @@ +/** + ****************************************************************************** + * @file stm32f4xx_rcc.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Reset and clock control (RCC) peripheral: + * - Internal/external clocks, PLL, CSS and MCO configuration + * - System, AHB and APB busses clocks configuration + * - Peripheral clocks configuration + * - Interrupts and flags management + * + * @verbatim + * + * =================================================================== + * RCC specific features + * =================================================================== + * + * After reset the device is running from Internal High Speed oscillator + * (HSI 16MHz) with Flash 0 wait state, Flash prefetch buffer, D-Cache + * and I-Cache are disabled, and all peripherals are off except internal + * SRAM, Flash and JTAG. + * - There is no prescaler on High speed (AHB) and Low speed (APB) busses; + * all peripherals mapped on these busses are running at HSI speed. + * - The clock for all peripherals is switched off, except the SRAM and FLASH. + * - All GPIOs are in input floating state, except the JTAG pins which + * are assigned to be used for debug purpose. + * + * Once the device started from reset, the user application has to: + * - Configure the clock source to be used to drive the System clock + * (if the application needs higher frequency/performance) + * - Configure the System clock frequency and Flash settings + * - Configure the AHB and APB busses prescalers + * - Enable the clock for the peripheral(s) to be used + * - Configure the clock source(s) for peripherals which clocks are not + * derived from the System clock (I2S, RTC, ADC, USB OTG FS/SDIO/RNG) + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup RCC + * @brief RCC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* ------------ RCC registers bit address in the alias region ----------- */ +#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) +/* --- CR Register ---*/ +/* Alias word address of HSION bit */ +#define CR_OFFSET (RCC_OFFSET + 0x00) +#define HSION_BitNumber 0x00 +#define CR_HSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4)) +/* Alias word address of CSSON bit */ +#define CSSON_BitNumber 0x13 +#define CR_CSSON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4)) +/* Alias word address of PLLON bit */ +#define PLLON_BitNumber 0x18 +#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4)) +/* Alias word address of PLLI2SON bit */ +#define PLLI2SON_BitNumber 0x1A +#define CR_PLLI2SON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLI2SON_BitNumber * 4)) + +/* --- CFGR Register ---*/ +/* Alias word address of I2SSRC bit */ +#define CFGR_OFFSET (RCC_OFFSET + 0x08) +#define I2SSRC_BitNumber 0x17 +#define CFGR_I2SSRC_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (I2SSRC_BitNumber * 4)) + +/* --- BDCR Register ---*/ +/* Alias word address of RTCEN bit */ +#define BDCR_OFFSET (RCC_OFFSET + 0x70) +#define RTCEN_BitNumber 0x0F +#define BDCR_RTCEN_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (RTCEN_BitNumber * 4)) +/* Alias word address of BDRST bit */ +#define BDRST_BitNumber 0x10 +#define BDCR_BDRST_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (BDRST_BitNumber * 4)) +/* --- CSR Register ---*/ +/* Alias word address of LSION bit */ +#define CSR_OFFSET (RCC_OFFSET + 0x74) +#define LSION_BitNumber 0x00 +#define CSR_LSION_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4)) +/* ---------------------- RCC registers bit mask ------------------------ */ +/* CFGR register bit mask */ +#define CFGR_MCO2_RESET_MASK ((uint32_t)0x07FFFFFF) +#define CFGR_MCO1_RESET_MASK ((uint32_t)0xF89FFFFF) + +/* RCC Flag Mask */ +#define FLAG_MASK ((uint8_t)0x1F) + +/* CR register byte 3 (Bits[23:16]) base address */ +#define CR_BYTE3_ADDRESS ((uint32_t)0x40023802) + +/* CIR register byte 2 (Bits[15:8]) base address */ +#define CIR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + 0x0C + 0x01)) + +/* CIR register byte 3 (Bits[23:16]) base address */ +#define CIR_BYTE3_ADDRESS ((uint32_t)(RCC_BASE + 0x0C + 0x02)) + +/* BDCR register base address */ +#define BDCR_ADDRESS (PERIPH_BASE + BDCR_OFFSET) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RCC_Private_Functions + * @{ + */ + +/** @defgroup RCC_Group1 Internal and external clocks, PLL, CSS and MCO configuration functions + * @brief Internal and external clocks, PLL, CSS and MCO configuration functions + * +@verbatim + =============================================================================== + Internal/external clocks, PLL, CSS and MCO configuration functions + =============================================================================== + + This section provide functions allowing to configure the internal/external clocks, + PLLs, CSS and MCO pins. + + 1. HSI (high-speed internal), 16 MHz factory-trimmed RC used directly or through + the PLL as System clock source. + + 2. LSI (low-speed internal), 32 KHz low consumption RC used as IWDG and/or RTC + clock source. + + 3. HSE (high-speed external), 4 to 26 MHz crystal oscillator used directly or + through the PLL as System clock source. Can be used also as RTC clock source. + + 4. LSE (low-speed external), 32 KHz oscillator used as RTC clock source. + + 5. PLL (clocked by HSI or HSE), featuring two different output clocks: + - The first output is used to generate the high speed system clock (up to 168 MHz) + - The second output is used to generate the clock for the USB OTG FS (48 MHz), + the random analog generator (<=48 MHz) and the SDIO (<= 48 MHz). + + 6. PLLI2S (clocked by HSI or HSE), used to generate an accurate clock to achieve + high-quality audio performance on the I2S interface. + + 7. CSS (Clock security system), once enable and if a HSE clock failure occurs + (HSE used directly or through PLL as System clock source), the System clock + is automatically switched to HSI and an interrupt is generated if enabled. + The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt) + exception vector. + + 8. MCO1 (microcontroller clock output), used to output HSI, LSE, HSE or PLL + clock (through a configurable prescaler) on PA8 pin. + + 9. MCO2 (microcontroller clock output), used to output HSE, PLL, SYSCLK or PLLI2S + clock (through a configurable prescaler) on PC9 pin. + +@endverbatim + * @{ + */ + +/** + * @brief Resets the RCC clock configuration to the default reset state. + * @note The default reset state of the clock configuration is given below: + * - HSI ON and used as system clock source + * - HSE, PLL and PLLI2S OFF + * - AHB, APB1 and APB2 prescaler set to 1. + * - CSS, MCO1 and MCO2 OFF + * - All interrupts disabled + * @note This function doesn't modify the configuration of the + * - Peripheral clocks + * - LSI, LSE and RTC clocks + * @param None + * @retval None + */ +void RCC_DeInit(void) +{ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000; + + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x24003010; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; +} + +/** + * @brief Configures the External High Speed oscillator (HSE). + * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application + * software should wait on HSERDY flag to be set indicating that HSE clock + * is stable and can be used to clock the PLL and/or system clock. + * @note HSE state can not be changed if it is used directly or through the + * PLL as system clock. In this case, you have to select another source + * of the system clock then change the HSE state (ex. disable it). + * @note The HSE is stopped by hardware when entering STOP and STANDBY modes. + * @note This function reset the CSSON bit, so if the Clock security system(CSS) + * was previously enabled you have to enable it again after calling this + * function. + * @param RCC_HSE: specifies the new state of the HSE. + * This parameter can be one of the following values: + * @arg RCC_HSE_OFF: turn OFF the HSE oscillator, HSERDY flag goes low after + * 6 HSE oscillator clock cycles. + * @arg RCC_HSE_ON: turn ON the HSE oscillator + * @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock + * @retval None + */ +void RCC_HSEConfig(uint8_t RCC_HSE) +{ + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_HSE)); + + /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/ + *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE_OFF; + + /* Set the new HSE configuration -------------------------------------------*/ + *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE; +} + +/** + * @brief Waits for HSE start-up. + * @note This functions waits on HSERDY flag to be set and return SUCCESS if + * this flag is set, otherwise returns ERROR if the timeout is reached + * and this flag is not set. The timeout value is defined by the constant + * HSE_STARTUP_TIMEOUT in stm32f4xx.h file. You can tailor it depending + * on the HSE crystal used in your application. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: HSE oscillator is stable and ready to use + * - ERROR: HSE oscillator not yet ready + */ +ErrorStatus RCC_WaitForHSEStartUp(void) +{ + __IO uint32_t startupcounter = 0; + ErrorStatus status = ERROR; + FlagStatus hsestatus = RESET; + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + hsestatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY); + startupcounter++; + } while((startupcounter != HSE_STARTUP_TIMEOUT) && (hsestatus == RESET)); + + if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + return (status); +} + +/** + * @brief Adjusts the Internal High Speed oscillator (HSI) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal HSI RC. + * @param HSICalibrationValue: specifies the calibration trimming value. + * This parameter must be a number between 0 and 0x1F. + * @retval None + */ +void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_RCC_CALIBRATION_VALUE(HSICalibrationValue)); + + tmpreg = RCC->CR; + + /* Clear HSITRIM[4:0] bits */ + tmpreg &= ~RCC_CR_HSITRIM; + + /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */ + tmpreg |= (uint32_t)HSICalibrationValue << 3; + + /* Store the new value */ + RCC->CR = tmpreg; +} + +/** + * @brief Enables or disables the Internal High Speed oscillator (HSI). + * @note The HSI is stopped by hardware when entering STOP and STANDBY modes. + * It is used (enabled by hardware) as system clock source after startup + * from Reset, wakeup from STOP and STANDBY mode, or in case of failure + * of the HSE used directly or indirectly as system clock (if the Clock + * Security System CSS is enabled). + * @note HSI can not be stopped if it is used as system clock source. In this case, + * you have to select another source of the system clock then stop the HSI. + * @note After enabling the HSI, the application software should wait on HSIRDY + * flag to be set indicating that HSI clock is stable and can be used as + * system clock source. + * @param NewState: new state of the HSI. + * This parameter can be: ENABLE or DISABLE. + * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator + * clock cycles. + * @retval None + */ +void RCC_HSICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_HSION_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the External Low Speed oscillator (LSE). + * @note As the LSE is in the Backup domain and write access is denied to + * this domain after reset, you have to enable write access using + * PWR_BackupAccessCmd(ENABLE) function before to configure the LSE + * (to be done once after reset). + * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_Bypass), the application + * software should wait on LSERDY flag to be set indicating that LSE clock + * is stable and can be used to clock the RTC. + * @param RCC_LSE: specifies the new state of the LSE. + * This parameter can be one of the following values: + * @arg RCC_LSE_OFF: turn OFF the LSE oscillator, LSERDY flag goes low after + * 6 LSE oscillator clock cycles. + * @arg RCC_LSE_ON: turn ON the LSE oscillator + * @arg RCC_LSE_Bypass: LSE oscillator bypassed with external clock + * @retval None + */ +void RCC_LSEConfig(uint8_t RCC_LSE) +{ + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_LSE)); + + /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/ + /* Reset LSEON bit */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF; + + /* Reset LSEBYP bit */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF; + + /* Configure LSE (RCC_LSE_OFF is already covered by the code section above) */ + switch (RCC_LSE) + { + case RCC_LSE_ON: + /* Set LSEON bit */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_ON; + break; + case RCC_LSE_Bypass: + /* Set LSEBYP and LSEON bits */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_Bypass | RCC_LSE_ON; + break; + default: + break; + } +} + +/** + * @brief Enables or disables the Internal Low Speed oscillator (LSI). + * @note After enabling the LSI, the application software should wait on + * LSIRDY flag to be set indicating that LSI clock is stable and can + * be used to clock the IWDG and/or the RTC. + * @note LSI can not be disabled if the IWDG is running. + * @param NewState: new state of the LSI. + * This parameter can be: ENABLE or DISABLE. + * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator + * clock cycles. + * @retval None + */ +void RCC_LSICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CSR_LSION_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the main PLL clock source, multiplication and division factors. + * @note This function must be used only when the main PLL is disabled. + * + * @param RCC_PLLSource: specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLLSource_HSI: HSI oscillator clock selected as PLL clock entry + * @arg RCC_PLLSource_HSE: HSE oscillator clock selected as PLL clock entry + * @note This clock source (RCC_PLLSource) is common for the main PLL and PLLI2S. + * + * @param PLLM: specifies the division factor for PLL VCO input clock + * This parameter must be a number between 0 and 63. + * @note You have to set the PLLM parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 2 MHz. It is recommended to select a frequency + * of 2 MHz to limit PLL jitter. + * + * @param PLLN: specifies the multiplication factor for PLL VCO output clock + * This parameter must be a number between 192 and 432. + * @note You have to set the PLLN parameter correctly to ensure that the VCO + * output frequency is between 192 and 432 MHz. + * + * @param PLLP: specifies the division factor for main system clock (SYSCLK) + * This parameter must be a number in the range {2, 4, 6, or 8}. + * @note You have to set the PLLP parameter correctly to not exceed 168 MHz on + * the System clock frequency. + * + * @param PLLQ: specifies the division factor for OTG FS, SDIO and RNG clocks + * This parameter must be a number between 4 and 15. + * @note If the USB OTG FS is used in your application, you have to set the + * PLLQ parameter correctly to have 48 MHz clock for the USB. However, + * the SDIO and RNG need a frequency lower than or equal to 48 MHz to work + * correctly. + * + * @retval None + */ +void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource)); + assert_param(IS_RCC_PLLM_VALUE(PLLM)); + assert_param(IS_RCC_PLLN_VALUE(PLLN)); + assert_param(IS_RCC_PLLP_VALUE(PLLP)); + assert_param(IS_RCC_PLLQ_VALUE(PLLQ)); + + RCC->PLLCFGR = PLLM | (PLLN << 6) | (((PLLP >> 1) -1) << 16) | (RCC_PLLSource) | + (PLLQ << 24); +} + +/** + * @brief Enables or disables the main PLL. + * @note After enabling the main PLL, the application software should wait on + * PLLRDY flag to be set indicating that PLL clock is stable and can + * be used as system clock source. + * @note The main PLL can not be disabled if it is used as system clock source + * @note The main PLL is disabled by hardware when entering STOP and STANDBY modes. + * @param NewState: new state of the main PLL. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PLLCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_PLLON_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the PLLI2S clock multiplication and division factors. + * + * @note This function must be used only when the PLLI2S is disabled. + * @note PLLI2S clock source is common with the main PLL (configured in + * RCC_PLLConfig function ) + * + * @param PLLI2SN: specifies the multiplication factor for PLLI2S VCO output clock + * This parameter must be a number between 192 and 432. + * @note You have to set the PLLI2SN parameter correctly to ensure that the VCO + * output frequency is between 192 and 432 MHz. + * + * @param PLLI2SR: specifies the division factor for I2S clock + * This parameter must be a number between 2 and 7. + * @note You have to set the PLLI2SR parameter correctly to not exceed 192 MHz + * on the I2S clock frequency. + * + * @retval None + */ +void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SN)); + assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SR)); + + RCC->PLLI2SCFGR = (PLLI2SN << 6) | (PLLI2SR << 28); +} + +/** + * @brief Enables or disables the PLLI2S. + * @note The PLLI2S is disabled by hardware when entering STOP and STANDBY modes. + * @param NewState: new state of the PLLI2S. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PLLI2SCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_PLLI2SON_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the Clock Security System. + * @note If a failure is detected on the HSE oscillator clock, this oscillator + * is automatically disabled and an interrupt is generated to inform the + * software about the failure (Clock Security System Interrupt, CSSI), + * allowing the MCU to perform rescue operations. The CSSI is linked to + * the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector. + * @param NewState: new state of the Clock Security System. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_ClockSecuritySystemCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_CSSON_BB = (uint32_t)NewState; +} + +/** + * @brief Selects the clock source to output on MCO1 pin(PA8). + * @note PA8 should be configured in alternate function mode. + * @param RCC_MCO1Source: specifies the clock source to output. + * This parameter can be one of the following values: + * @arg RCC_MCO1Source_HSI: HSI clock selected as MCO1 source + * @arg RCC_MCO1Source_LSE: LSE clock selected as MCO1 source + * @arg RCC_MCO1Source_HSE: HSE clock selected as MCO1 source + * @arg RCC_MCO1Source_PLLCLK: main PLL clock selected as MCO1 source + * @param RCC_MCO1Div: specifies the MCO1 prescaler. + * This parameter can be one of the following values: + * @arg RCC_MCO1Div_1: no division applied to MCO1 clock + * @arg RCC_MCO1Div_2: division by 2 applied to MCO1 clock + * @arg RCC_MCO1Div_3: division by 3 applied to MCO1 clock + * @arg RCC_MCO1Div_4: division by 4 applied to MCO1 clock + * @arg RCC_MCO1Div_5: division by 5 applied to MCO1 clock + * @retval None + */ +void RCC_MCO1Config(uint32_t RCC_MCO1Source, uint32_t RCC_MCO1Div) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_MCO1SOURCE(RCC_MCO1Source)); + assert_param(IS_RCC_MCO1DIV(RCC_MCO1Div)); + + tmpreg = RCC->CFGR; + + /* Clear MCO1[1:0] and MCO1PRE[2:0] bits */ + tmpreg &= CFGR_MCO1_RESET_MASK; + + /* Select MCO1 clock source and prescaler */ + tmpreg |= RCC_MCO1Source | RCC_MCO1Div; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Selects the clock source to output on MCO2 pin(PC9). + * @note PC9 should be configured in alternate function mode. + * @param RCC_MCO2Source: specifies the clock source to output. + * This parameter can be one of the following values: + * @arg RCC_MCO2Source_SYSCLK: System clock (SYSCLK) selected as MCO2 source + * @arg RCC_MCO2Source_PLLI2SCLK: PLLI2S clock selected as MCO2 source + * @arg RCC_MCO2Source_HSE: HSE clock selected as MCO2 source + * @arg RCC_MCO2Source_PLLCLK: main PLL clock selected as MCO2 source + * @param RCC_MCO2Div: specifies the MCO2 prescaler. + * This parameter can be one of the following values: + * @arg RCC_MCO2Div_1: no division applied to MCO2 clock + * @arg RCC_MCO2Div_2: division by 2 applied to MCO2 clock + * @arg RCC_MCO2Div_3: division by 3 applied to MCO2 clock + * @arg RCC_MCO2Div_4: division by 4 applied to MCO2 clock + * @arg RCC_MCO2Div_5: division by 5 applied to MCO2 clock + * @retval None + */ +void RCC_MCO2Config(uint32_t RCC_MCO2Source, uint32_t RCC_MCO2Div) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_MCO2SOURCE(RCC_MCO2Source)); + assert_param(IS_RCC_MCO2DIV(RCC_MCO2Div)); + + tmpreg = RCC->CFGR; + + /* Clear MCO2 and MCO2PRE[2:0] bits */ + tmpreg &= CFGR_MCO2_RESET_MASK; + + /* Select MCO2 clock source and prescaler */ + tmpreg |= RCC_MCO2Source | RCC_MCO2Div; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @} + */ + +/** @defgroup RCC_Group2 System AHB and APB busses clocks configuration functions + * @brief System, AHB and APB busses clocks configuration functions + * +@verbatim + =============================================================================== + System, AHB and APB busses clocks configuration functions + =============================================================================== + + This section provide functions allowing to configure the System, AHB, APB1 and + APB2 busses clocks. + + 1. Several clock sources can be used to drive the System clock (SYSCLK): HSI, + HSE and PLL. + The AHB clock (HCLK) is derived from System clock through configurable prescaler + and used to clock the CPU, memory and peripherals mapped on AHB bus (DMA, GPIO...). + APB1 (PCLK1) and APB2 (PCLK2) clocks are derived from AHB clock through + configurable prescalers and used to clock the peripherals mapped on these busses. + You can use "RCC_GetClocksFreq()" function to retrieve the frequencies of these clocks. + +@note All the peripheral clocks are derived from the System clock (SYSCLK) except: + - I2S: the I2S clock can be derived either from a specific PLL (PLLI2S) or + from an external clock mapped on the I2S_CKIN pin. + You have to use RCC_I2SCLKConfig() function to configure this clock. + - RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock + divided by 2 to 31. You have to use RCC_RTCCLKConfig() and RCC_RTCCLKCmd() + functions to configure this clock. + - USB OTG FS, SDIO and RTC: USB OTG FS require a frequency equal to 48 MHz + to work correctly, while the SDIO require a frequency equal or lower than + to 48. This clock is derived of the main PLL through PLLQ divider. + - IWDG clock which is always the LSI clock. + + 2. The maximum frequency of the SYSCLK and HCLK is 168 MHz, PCLK2 82 MHz and PCLK1 42 MHz. + Depending on the device voltage range, the maximum frequency should be + adapted accordingly: + +-------------------------------------------------------------------------------------+ + | Latency | HCLK clock frequency (MHz) | + | |---------------------------------------------------------------------| + | | voltage range | voltage range | voltage range | voltage range | + | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V | + |---------------|----------------|----------------|-----------------|-----------------| + |0WS(1CPU cycle)|0 < HCLK <= 30 |0 < HCLK <= 24 |0 < HCLK <= 18 |0 < HCLK <= 16 | + |---------------|----------------|----------------|-----------------|-----------------| + |1WS(2CPU cycle)|30 < HCLK <= 60 |24 < HCLK <= 48 |18 < HCLK <= 36 |16 < HCLK <= 32 | + |---------------|----------------|----------------|-----------------|-----------------| + |2WS(3CPU cycle)|60 < HCLK <= 90 |48 < HCLK <= 72 |36 < HCLK <= 54 |32 < HCLK <= 48 | + |---------------|----------------|----------------|-----------------|-----------------| + |3WS(4CPU cycle)|90 < HCLK <= 120|72 < HCLK <= 96 |54 < HCLK <= 72 |48 < HCLK <= 64 | + |---------------|----------------|----------------|-----------------|-----------------| + |4WS(5CPU cycle)|120< HCLK <= 150|96 < HCLK <= 120|72 < HCLK <= 90 |64 < HCLK <= 80 | + |---------------|----------------|----------------|-----------------|-----------------| + |5WS(6CPU cycle)|120< HCLK <= 168|120< HCLK <= 144|90 < HCLK <= 108 |80 < HCLK <= 96 | + |---------------|----------------|----------------|-----------------|-----------------| + |6WS(7CPU cycle)| NA |144< HCLK <= 168|108 < HCLK <= 120|96 < HCLK <= 112 | + |---------------|----------------|----------------|-----------------|-----------------| + |7WS(8CPU cycle)| NA | NA |120 < HCLK <= 138|112 < HCLK <= 120| + +-------------------------------------------------------------------------------------+ + @note When VOS bit (in PWR_CR register) is reset to '0, the maximum value of HCLK is 144 MHz. + You can use PWR_MainRegulatorModeConfig() function to set or reset this bit. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the system clock (SYSCLK). + * @note The HSI is used (enabled by hardware) as system clock source after + * startup from Reset, wake-up from STOP and STANDBY mode, or in case + * of failure of the HSE used directly or indirectly as system clock + * (if the Clock Security System CSS is enabled). + * @note A switch from one clock source to another occurs only if the target + * clock source is ready (clock stable after startup delay or PLL locked). + * If a clock source which is not yet ready is selected, the switch will + * occur when the clock source will be ready. + * You can use RCC_GetSYSCLKSource() function to know which clock is + * currently used as system clock source. + * @param RCC_SYSCLKSource: specifies the clock source used as system clock. + * This parameter can be one of the following values: + * @arg RCC_SYSCLKSource_HSI: HSI selected as system clock source + * @arg RCC_SYSCLKSource_HSE: HSE selected as system clock source + * @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock source + * @retval None + */ +void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource)); + + tmpreg = RCC->CFGR; + + /* Clear SW[1:0] bits */ + tmpreg &= ~RCC_CFGR_SW; + + /* Set SW[1:0] bits according to RCC_SYSCLKSource value */ + tmpreg |= RCC_SYSCLKSource; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Returns the clock source used as system clock. + * @param None + * @retval The clock source used as system clock. The returned value can be one + * of the following: + * - 0x00: HSI used as system clock + * - 0x04: HSE used as system clock + * - 0x08: PLL used as system clock + */ +uint8_t RCC_GetSYSCLKSource(void) +{ + return ((uint8_t)(RCC->CFGR & RCC_CFGR_SWS)); +} + +/** + * @brief Configures the AHB clock (HCLK). + * @note Depending on the device voltage range, the software has to set correctly + * these bits to ensure that HCLK not exceed the maximum allowed frequency + * (for more details refer to section above + * "CPU, AHB and APB busses clocks configuration functions") + * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from + * the system clock (SYSCLK). + * This parameter can be one of the following values: + * @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK + * @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2 + * @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4 + * @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8 + * @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16 + * @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64 + * @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128 + * @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256 + * @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512 + * @retval None + */ +void RCC_HCLKConfig(uint32_t RCC_SYSCLK) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_HCLK(RCC_SYSCLK)); + + tmpreg = RCC->CFGR; + + /* Clear HPRE[3:0] bits */ + tmpreg &= ~RCC_CFGR_HPRE; + + /* Set HPRE[3:0] bits according to RCC_SYSCLK value */ + tmpreg |= RCC_SYSCLK; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + + +/** + * @brief Configures the Low Speed APB clock (PCLK1). + * @param RCC_HCLK: defines the APB1 clock divider. This clock is derived from + * the AHB clock (HCLK). + * This parameter can be one of the following values: + * @arg RCC_HCLK_Div1: APB1 clock = HCLK + * @arg RCC_HCLK_Div2: APB1 clock = HCLK/2 + * @arg RCC_HCLK_Div4: APB1 clock = HCLK/4 + * @arg RCC_HCLK_Div8: APB1 clock = HCLK/8 + * @arg RCC_HCLK_Div16: APB1 clock = HCLK/16 + * @retval None + */ +void RCC_PCLK1Config(uint32_t RCC_HCLK) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PCLK(RCC_HCLK)); + + tmpreg = RCC->CFGR; + + /* Clear PPRE1[2:0] bits */ + tmpreg &= ~RCC_CFGR_PPRE1; + + /* Set PPRE1[2:0] bits according to RCC_HCLK value */ + tmpreg |= RCC_HCLK; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Configures the High Speed APB clock (PCLK2). + * @param RCC_HCLK: defines the APB2 clock divider. This clock is derived from + * the AHB clock (HCLK). + * This parameter can be one of the following values: + * @arg RCC_HCLK_Div1: APB2 clock = HCLK + * @arg RCC_HCLK_Div2: APB2 clock = HCLK/2 + * @arg RCC_HCLK_Div4: APB2 clock = HCLK/4 + * @arg RCC_HCLK_Div8: APB2 clock = HCLK/8 + * @arg RCC_HCLK_Div16: APB2 clock = HCLK/16 + * @retval None + */ +void RCC_PCLK2Config(uint32_t RCC_HCLK) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PCLK(RCC_HCLK)); + + tmpreg = RCC->CFGR; + + /* Clear PPRE2[2:0] bits */ + tmpreg &= ~RCC_CFGR_PPRE2; + + /* Set PPRE2[2:0] bits according to RCC_HCLK value */ + tmpreg |= RCC_HCLK << 3; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Returns the frequencies of different on chip clocks; SYSCLK, HCLK, + * PCLK1 and PCLK2. + * + * @note The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) + * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**) + * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * @note (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * @note (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * @note The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold + * the clocks frequencies. + * + * @note This function can be used by the user application to compute the + * baudrate for the communication peripherals or configure other parameters. + * @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function + * must be called to update the structure's field. Otherwise, any + * configuration based on this function will be incorrect. + * + * @retval None + */ +void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) +{ + uint32_t tmp = 0, presc = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock source */ + RCC_Clocks->SYSCLK_Frequency = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock source */ + RCC_Clocks->SYSCLK_Frequency = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN + SYSCLK = PLL_VCO / PLLP + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + RCC_Clocks->SYSCLK_Frequency = pllvco/pllp; + break; + default: + RCC_Clocks->SYSCLK_Frequency = HSI_VALUE; + break; + } + /* Compute HCLK, PCLK1 and PCLK2 clocks frequencies ------------------------*/ + + /* Get HCLK prescaler */ + tmp = RCC->CFGR & RCC_CFGR_HPRE; + tmp = tmp >> 4; + presc = APBAHBPrescTable[tmp]; + /* HCLK clock frequency */ + RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc; + + /* Get PCLK1 prescaler */ + tmp = RCC->CFGR & RCC_CFGR_PPRE1; + tmp = tmp >> 10; + presc = APBAHBPrescTable[tmp]; + /* PCLK1 clock frequency */ + RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc; + + /* Get PCLK2 prescaler */ + tmp = RCC->CFGR & RCC_CFGR_PPRE2; + tmp = tmp >> 13; + presc = APBAHBPrescTable[tmp]; + /* PCLK2 clock frequency */ + RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc; +} + +/** + * @} + */ + +/** @defgroup RCC_Group3 Peripheral clocks configuration functions + * @brief Peripheral clocks configuration functions + * +@verbatim + =============================================================================== + Peripheral clocks configuration functions + =============================================================================== + + This section provide functions allowing to configure the Peripheral clocks. + + 1. The RTC clock which is derived from the LSI, LSE or HSE clock divided by 2 to 31. + + 2. After restart from Reset or wakeup from STANDBY, all peripherals are off + except internal SRAM, Flash and JTAG. Before to start using a peripheral you + have to enable its interface clock. You can do this using RCC_AHBPeriphClockCmd() + , RCC_APB2PeriphClockCmd() and RCC_APB1PeriphClockCmd() functions. + + 3. To reset the peripherals configuration (to the default state after device reset) + you can use RCC_AHBPeriphResetCmd(), RCC_APB2PeriphResetCmd() and + RCC_APB1PeriphResetCmd() functions. + + 4. To further reduce power consumption in SLEEP mode the peripheral clocks can + be disabled prior to executing the WFI or WFE instructions. You can do this + using RCC_AHBPeriphClockLPModeCmd(), RCC_APB2PeriphClockLPModeCmd() and + RCC_APB1PeriphClockLPModeCmd() functions. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the RTC clock (RTCCLK). + * @note As the RTC clock configuration bits are in the Backup domain and write + * access is denied to this domain after reset, you have to enable write + * access using PWR_BackupAccessCmd(ENABLE) function before to configure + * the RTC clock source (to be done once after reset). + * @note Once the RTC clock is configured it can't be changed unless the + * Backup domain is reset using RCC_BackupResetCmd() function, or by + * a Power On Reset (POR). + * + * @param RCC_RTCCLKSource: specifies the RTC clock source. + * This parameter can be one of the following values: + * @arg RCC_RTCCLKSource_LSE: LSE selected as RTC clock + * @arg RCC_RTCCLKSource_LSI: LSI selected as RTC clock + * @arg RCC_RTCCLKSource_HSE_Divx: HSE clock divided by x selected + * as RTC clock, where x:[2,31] + * + * @note If the LSE or LSI is used as RTC clock source, the RTC continues to + * work in STOP and STANDBY modes, and can be used as wakeup source. + * However, when the HSE clock is used as RTC clock source, the RTC + * cannot be used in STOP and STANDBY modes. + * @note The maximum input clock frequency for RTC is 1MHz (when using HSE as + * RTC clock source). + * + * @retval None + */ +void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource)); + + if ((RCC_RTCCLKSource & 0x00000300) == 0x00000300) + { /* If HSE is selected as RTC clock source, configure HSE division factor for RTC clock */ + tmpreg = RCC->CFGR; + + /* Clear RTCPRE[4:0] bits */ + tmpreg &= ~RCC_CFGR_RTCPRE; + + /* Configure HSE division factor for RTC clock */ + tmpreg |= (RCC_RTCCLKSource & 0xFFFFCFF); + + /* Store the new value */ + RCC->CFGR = tmpreg; + } + + /* Select the RTC clock source */ + RCC->BDCR |= (RCC_RTCCLKSource & 0x00000FFF); +} + +/** + * @brief Enables or disables the RTC clock. + * @note This function must be used only after the RTC clock source was selected + * using the RCC_RTCCLKConfig function. + * @param NewState: new state of the RTC clock. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_RTCCLKCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) BDCR_RTCEN_BB = (uint32_t)NewState; +} + +/** + * @brief Forces or releases the Backup domain reset. + * @note This function resets the RTC peripheral (including the backup registers) + * and the RTC clock source selection in RCC_CSR register. + * @note The BKPSRAM is not affected by this reset. + * @param NewState: new state of the Backup domain reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_BackupResetCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) BDCR_BDRST_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the I2S clock source (I2SCLK). + * @note This function must be called before enabling the I2S APB clock. + * @param RCC_I2SCLKSource: specifies the I2S clock source. + * This parameter can be one of the following values: + * @arg RCC_I2S2CLKSource_PLLI2S: PLLI2S clock used as I2S clock source + * @arg RCC_I2S2CLKSource_Ext: External clock mapped on the I2S_CKIN pin + * used as I2S clock source + * @retval None + */ +void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource) +{ + /* Check the parameters */ + assert_param(IS_RCC_I2SCLK_SOURCE(RCC_I2SCLKSource)); + + *(__IO uint32_t *) CFGR_I2SSRC_BB = RCC_I2SCLKSource; +} + +/** + * @brief Enables or disables the AHB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_AHBPeriph: specifies the AHB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB1Periph_GPIOA: GPIOA clock + * @arg RCC_AHB1Periph_GPIOB: GPIOB clock + * @arg RCC_AHB1Periph_GPIOC: GPIOC clock + * @arg RCC_AHB1Periph_GPIOD: GPIOD clock + * @arg RCC_AHB1Periph_GPIOE: GPIOE clock + * @arg RCC_AHB1Periph_GPIOF: GPIOF clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOI: GPIOI clock + * @arg RCC_AHB1Periph_CRC: CRC clock + * @arg RCC_AHB1Periph_BKPSRAM: BKPSRAM interface clock + * @arg RCC_AHB1Periph_CCMDATARAMEN CCM data RAM interface clock + * @arg RCC_AHB1Periph_DMA1: DMA1 clock + * @arg RCC_AHB1Periph_DMA2: DMA2 clock + * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock + * @arg RCC_AHB1Periph_ETH_MAC_Tx: Ethernet Transmission clock + * @arg RCC_AHB1Periph_ETH_MAC_Rx: Ethernet Reception clock + * @arg RCC_AHB1Periph_ETH_MAC_PTP: Ethernet PTP clock + * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock + * @arg RCC_AHB1Periph_OTG_HS_ULPI: USB OTG HS ULPI clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB1_CLOCK_PERIPH(RCC_AHB1Periph)); + + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->AHB1ENR |= RCC_AHB1Periph; + } + else + { + RCC->AHB1ENR &= ~RCC_AHB1Periph; + } +} + +/** + * @brief Enables or disables the AHB2 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_AHBPeriph: specifies the AHB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB2Periph_DCMI: DCMI clock + * @arg RCC_AHB2Periph_CRYP: CRYP clock + * @arg RCC_AHB2Periph_HASH: HASH clock + * @arg RCC_AHB2Periph_RNG: RNG clock + * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB2ENR |= RCC_AHB2Periph; + } + else + { + RCC->AHB2ENR &= ~RCC_AHB2Periph; + } +} + +/** + * @brief Enables or disables the AHB3 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_AHBPeriph: specifies the AHB3 peripheral to gates its clock. + * This parameter must be: RCC_AHB3Periph_FSMC + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB3ENR |= RCC_AHB3Periph; + } + else + { + RCC->AHB3ENR &= ~RCC_AHB3Periph; + } +} + +/** + * @brief Enables or disables the Low Speed APB (APB1) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_TIM2: TIM2 clock + * @arg RCC_APB1Periph_TIM3: TIM3 clock + * @arg RCC_APB1Periph_TIM4: TIM4 clock + * @arg RCC_APB1Periph_TIM5: TIM5 clock + * @arg RCC_APB1Periph_TIM6: TIM6 clock + * @arg RCC_APB1Periph_TIM7: TIM7 clock + * @arg RCC_APB1Periph_TIM12: TIM12 clock + * @arg RCC_APB1Periph_TIM13: TIM13 clock + * @arg RCC_APB1Periph_TIM14: TIM14 clock + * @arg RCC_APB1Periph_WWDG: WWDG clock + * @arg RCC_APB1Periph_SPI2: SPI2 clock + * @arg RCC_APB1Periph_SPI3: SPI3 clock + * @arg RCC_APB1Periph_USART2: USART2 clock + * @arg RCC_APB1Periph_USART3: USART3 clock + * @arg RCC_APB1Periph_UART4: UART4 clock + * @arg RCC_APB1Periph_UART5: UART5 clock + * @arg RCC_APB1Periph_I2C1: I2C1 clock + * @arg RCC_APB1Periph_I2C2: I2C2 clock + * @arg RCC_APB1Periph_I2C3: I2C3 clock + * @arg RCC_APB1Periph_CAN1: CAN1 clock + * @arg RCC_APB1Periph_CAN2: CAN2 clock + * @arg RCC_APB1Periph_PWR: PWR clock + * @arg RCC_APB1Periph_DAC: DAC clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB1ENR |= RCC_APB1Periph; + } + else + { + RCC->APB1ENR &= ~RCC_APB1Periph; + } +} + +/** + * @brief Enables or disables the High Speed APB (APB2) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_TIM1: TIM1 clock + * @arg RCC_APB2Periph_TIM8: TIM8 clock + * @arg RCC_APB2Periph_USART1: USART1 clock + * @arg RCC_APB2Periph_USART6: USART6 clock + * @arg RCC_APB2Periph_ADC1: ADC1 clock + * @arg RCC_APB2Periph_ADC2: ADC2 clock + * @arg RCC_APB2Periph_ADC3: ADC3 clock + * @arg RCC_APB2Periph_SDIO: SDIO clock + * @arg RCC_APB2Periph_SPI1: SPI1 clock + * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock + * @arg RCC_APB2Periph_TIM9: TIM9 clock + * @arg RCC_APB2Periph_TIM10: TIM10 clock + * @arg RCC_APB2Periph_TIM11: TIM11 clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB2ENR |= RCC_APB2Periph; + } + else + { + RCC->APB2ENR &= ~RCC_APB2Periph; + } +} + +/** + * @brief Forces or releases AHB1 peripheral reset. + * @param RCC_AHB1Periph: specifies the AHB1 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_AHB1Periph_GPIOA: GPIOA clock + * @arg RCC_AHB1Periph_GPIOB: GPIOB clock + * @arg RCC_AHB1Periph_GPIOC: GPIOC clock + * @arg RCC_AHB1Periph_GPIOD: GPIOD clock + * @arg RCC_AHB1Periph_GPIOE: GPIOE clock + * @arg RCC_AHB1Periph_GPIOF: GPIOF clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOI: GPIOI clock + * @arg RCC_AHB1Periph_CRC: CRC clock + * @arg RCC_AHB1Periph_DMA1: DMA1 clock + * @arg RCC_AHB1Periph_DMA2: DMA2 clock + * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock + * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock + * + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB1_RESET_PERIPH(RCC_AHB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB1RSTR |= RCC_AHB1Periph; + } + else + { + RCC->AHB1RSTR &= ~RCC_AHB1Periph; + } +} + +/** + * @brief Forces or releases AHB2 peripheral reset. + * @param RCC_AHB2Periph: specifies the AHB2 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_AHB2Periph_DCMI: DCMI clock + * @arg RCC_AHB2Periph_CRYP: CRYP clock + * @arg RCC_AHB2Periph_HASH: HASH clock + * @arg RCC_AHB2Periph_RNG: RNG clock + * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB2RSTR |= RCC_AHB2Periph; + } + else + { + RCC->AHB2RSTR &= ~RCC_AHB2Periph; + } +} + +/** + * @brief Forces or releases AHB3 peripheral reset. + * @param RCC_AHB3Periph: specifies the AHB3 peripheral to reset. + * This parameter must be: RCC_AHB3Periph_FSMC + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB3RSTR |= RCC_AHB3Periph; + } + else + { + RCC->AHB3RSTR &= ~RCC_AHB3Periph; + } +} + +/** + * @brief Forces or releases Low Speed APB (APB1) peripheral reset. + * @param RCC_APB1Periph: specifies the APB1 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_TIM2: TIM2 clock + * @arg RCC_APB1Periph_TIM3: TIM3 clock + * @arg RCC_APB1Periph_TIM4: TIM4 clock + * @arg RCC_APB1Periph_TIM5: TIM5 clock + * @arg RCC_APB1Periph_TIM6: TIM6 clock + * @arg RCC_APB1Periph_TIM7: TIM7 clock + * @arg RCC_APB1Periph_TIM12: TIM12 clock + * @arg RCC_APB1Periph_TIM13: TIM13 clock + * @arg RCC_APB1Periph_TIM14: TIM14 clock + * @arg RCC_APB1Periph_WWDG: WWDG clock + * @arg RCC_APB1Periph_SPI2: SPI2 clock + * @arg RCC_APB1Periph_SPI3: SPI3 clock + * @arg RCC_APB1Periph_USART2: USART2 clock + * @arg RCC_APB1Periph_USART3: USART3 clock + * @arg RCC_APB1Periph_UART4: UART4 clock + * @arg RCC_APB1Periph_UART5: UART5 clock + * @arg RCC_APB1Periph_I2C1: I2C1 clock + * @arg RCC_APB1Periph_I2C2: I2C2 clock + * @arg RCC_APB1Periph_I2C3: I2C3 clock + * @arg RCC_APB1Periph_CAN1: CAN1 clock + * @arg RCC_APB1Periph_CAN2: CAN2 clock + * @arg RCC_APB1Periph_PWR: PWR clock + * @arg RCC_APB1Periph_DAC: DAC clock + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB1RSTR |= RCC_APB1Periph; + } + else + { + RCC->APB1RSTR &= ~RCC_APB1Periph; + } +} + +/** + * @brief Forces or releases High Speed APB (APB2) peripheral reset. + * @param RCC_APB2Periph: specifies the APB2 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_TIM1: TIM1 clock + * @arg RCC_APB2Periph_TIM8: TIM8 clock + * @arg RCC_APB2Periph_USART1: USART1 clock + * @arg RCC_APB2Periph_USART6: USART6 clock + * @arg RCC_APB2Periph_ADC1: ADC1 clock + * @arg RCC_APB2Periph_ADC2: ADC2 clock + * @arg RCC_APB2Periph_ADC3: ADC3 clock + * @arg RCC_APB2Periph_SDIO: SDIO clock + * @arg RCC_APB2Periph_SPI1: SPI1 clock + * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock + * @arg RCC_APB2Periph_TIM9: TIM9 clock + * @arg RCC_APB2Periph_TIM10: TIM10 clock + * @arg RCC_APB2Periph_TIM11: TIM11 clock + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_RESET_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB2RSTR |= RCC_APB2Periph; + } + else + { + RCC->APB2RSTR &= ~RCC_APB2Periph; + } +} + +/** + * @brief Enables or disables the AHB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_AHBPeriph: specifies the AHB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB1Periph_GPIOA: GPIOA clock + * @arg RCC_AHB1Periph_GPIOB: GPIOB clock + * @arg RCC_AHB1Periph_GPIOC: GPIOC clock + * @arg RCC_AHB1Periph_GPIOD: GPIOD clock + * @arg RCC_AHB1Periph_GPIOE: GPIOE clock + * @arg RCC_AHB1Periph_GPIOF: GPIOF clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOI: GPIOI clock + * @arg RCC_AHB1Periph_CRC: CRC clock + * @arg RCC_AHB1Periph_BKPSRAM: BKPSRAM interface clock + * @arg RCC_AHB1Periph_DMA1: DMA1 clock + * @arg RCC_AHB1Periph_DMA2: DMA2 clock + * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock + * @arg RCC_AHB1Periph_ETH_MAC_Tx: Ethernet Transmission clock + * @arg RCC_AHB1Periph_ETH_MAC_Rx: Ethernet Reception clock + * @arg RCC_AHB1Periph_ETH_MAC_PTP: Ethernet PTP clock + * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock + * @arg RCC_AHB1Periph_OTG_HS_ULPI: USB OTG HS ULPI clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB1_LPMODE_PERIPH(RCC_AHB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->AHB1LPENR |= RCC_AHB1Periph; + } + else + { + RCC->AHB1LPENR &= ~RCC_AHB1Periph; + } +} + +/** + * @brief Enables or disables the AHB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_AHBPeriph: specifies the AHB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB2Periph_DCMI: DCMI clock + * @arg RCC_AHB2Periph_CRYP: CRYP clock + * @arg RCC_AHB2Periph_HASH: HASH clock + * @arg RCC_AHB2Periph_RNG: RNG clock + * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->AHB2LPENR |= RCC_AHB2Periph; + } + else + { + RCC->AHB2LPENR &= ~RCC_AHB2Periph; + } +} + +/** + * @brief Enables or disables the AHB3 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_AHBPeriph: specifies the AHB3 peripheral to gates its clock. + * This parameter must be: RCC_AHB3Periph_FSMC + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->AHB3LPENR |= RCC_AHB3Periph; + } + else + { + RCC->AHB3LPENR &= ~RCC_AHB3Periph; + } +} + +/** + * @brief Enables or disables the APB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_TIM2: TIM2 clock + * @arg RCC_APB1Periph_TIM3: TIM3 clock + * @arg RCC_APB1Periph_TIM4: TIM4 clock + * @arg RCC_APB1Periph_TIM5: TIM5 clock + * @arg RCC_APB1Periph_TIM6: TIM6 clock + * @arg RCC_APB1Periph_TIM7: TIM7 clock + * @arg RCC_APB1Periph_TIM12: TIM12 clock + * @arg RCC_APB1Periph_TIM13: TIM13 clock + * @arg RCC_APB1Periph_TIM14: TIM14 clock + * @arg RCC_APB1Periph_WWDG: WWDG clock + * @arg RCC_APB1Periph_SPI2: SPI2 clock + * @arg RCC_APB1Periph_SPI3: SPI3 clock + * @arg RCC_APB1Periph_USART2: USART2 clock + * @arg RCC_APB1Periph_USART3: USART3 clock + * @arg RCC_APB1Periph_UART4: UART4 clock + * @arg RCC_APB1Periph_UART5: UART5 clock + * @arg RCC_APB1Periph_I2C1: I2C1 clock + * @arg RCC_APB1Periph_I2C2: I2C2 clock + * @arg RCC_APB1Periph_I2C3: I2C3 clock + * @arg RCC_APB1Periph_CAN1: CAN1 clock + * @arg RCC_APB1Periph_CAN2: CAN2 clock + * @arg RCC_APB1Periph_PWR: PWR clock + * @arg RCC_APB1Periph_DAC: DAC clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB1LPENR |= RCC_APB1Periph; + } + else + { + RCC->APB1LPENR &= ~RCC_APB1Periph; + } +} + +/** + * @brief Enables or disables the APB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_TIM1: TIM1 clock + * @arg RCC_APB2Periph_TIM8: TIM8 clock + * @arg RCC_APB2Periph_USART1: USART1 clock + * @arg RCC_APB2Periph_USART6: USART6 clock + * @arg RCC_APB2Periph_ADC1: ADC1 clock + * @arg RCC_APB2Periph_ADC2: ADC2 clock + * @arg RCC_APB2Periph_ADC3: ADC3 clock + * @arg RCC_APB2Periph_SDIO: SDIO clock + * @arg RCC_APB2Periph_SPI1: SPI1 clock + * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock + * @arg RCC_APB2Periph_TIM9: TIM9 clock + * @arg RCC_APB2Periph_TIM10: TIM10 clock + * @arg RCC_APB2Periph_TIM11: TIM11 clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB2LPENR |= RCC_APB2Periph; + } + else + { + RCC->APB2LPENR &= ~RCC_APB2Periph; + } +} + +/** + * @} + */ + +/** @defgroup RCC_Group4 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified RCC interrupts. + * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: main PLL ready interrupt + * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt + * @param NewState: new state of the specified RCC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_IT(RCC_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Perform Byte access to RCC_CIR[14:8] bits to enable the selected interrupts */ + *(__IO uint8_t *) CIR_BYTE2_ADDRESS |= RCC_IT; + } + else + { + /* Perform Byte access to RCC_CIR[14:8] bits to disable the selected interrupts */ + *(__IO uint8_t *) CIR_BYTE2_ADDRESS &= (uint8_t)~RCC_IT; + } +} + +/** + * @brief Checks whether the specified RCC flag is set or not. + * @param RCC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready + * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready + * @arg RCC_FLAG_PLLRDY: main PLL clock ready + * @arg RCC_FLAG_PLLI2SRDY: PLLI2S clock ready + * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready + * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready + * @arg RCC_FLAG_BORRST: POR/PDR or BOR reset + * @arg RCC_FLAG_PINRST: Pin reset + * @arg RCC_FLAG_PORRST: POR/PDR reset + * @arg RCC_FLAG_SFTRST: Software reset + * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset + * @arg RCC_FLAG_WWDGRST: Window Watchdog reset + * @arg RCC_FLAG_LPWRRST: Low Power reset + * @retval The new state of RCC_FLAG (SET or RESET). + */ +FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG) +{ + uint32_t tmp = 0; + uint32_t statusreg = 0; + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_RCC_FLAG(RCC_FLAG)); + + /* Get the RCC register index */ + tmp = RCC_FLAG >> 5; + if (tmp == 1) /* The flag to check is in CR register */ + { + statusreg = RCC->CR; + } + else if (tmp == 2) /* The flag to check is in BDCR register */ + { + statusreg = RCC->BDCR; + } + else /* The flag to check is in CSR register */ + { + statusreg = RCC->CSR; + } + + /* Get the flag position */ + tmp = RCC_FLAG & FLAG_MASK; + if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @brief Clears the RCC reset flags. + * The reset flags are: RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST, + * RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST + * @param None + * @retval None + */ +void RCC_ClearFlag(void) +{ + /* Set RMVF bit to clear the reset flags */ + RCC->CSR |= RCC_CSR_RMVF; +} + +/** + * @brief Checks whether the specified RCC interrupt has occurred or not. + * @param RCC_IT: specifies the RCC interrupt source to check. + * This parameter can be one of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: main PLL ready interrupt + * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt + * @arg RCC_IT_CSS: Clock Security System interrupt + * @retval The new state of RCC_IT (SET or RESET). + */ +ITStatus RCC_GetITStatus(uint8_t RCC_IT) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_RCC_GET_IT(RCC_IT)); + + /* Check the status of the specified RCC interrupt */ + if ((RCC->CIR & RCC_IT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the RCC_IT status */ + return bitstatus; +} + +/** + * @brief Clears the RCC's interrupt pending bits. + * @param RCC_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: main PLL ready interrupt + * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt + * @arg RCC_IT_CSS: Clock Security System interrupt + * @retval None + */ +void RCC_ClearITPendingBit(uint8_t RCC_IT) +{ + /* Check the parameters */ + assert_param(IS_RCC_CLEAR_IT(RCC_IT)); + + /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt + pending bits */ + *(__IO uint8_t *) CIR_BYTE3_ADDRESS = RCC_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rng.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rng.c new file mode 100644 index 0000000..9f0ba05 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rng.c @@ -0,0 +1,399 @@ +/** + ****************************************************************************** + * @file stm32f4xx_rng.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Random Number Generator (RNG) peripheral: + * - Initialization and Configuration + * - Get 32 bit Random number + * - Interrupts and flags management + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + * 1. Enable The RNG controller clock using + * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE) function. + * + * 2. Activate the RNG peripheral using RNG_Cmd() function. + * + * 3. Wait until the 32 bit Random number Generator contains a valid + * random data (using polling/interrupt mode). For more details, + * refer to "Interrupts and flags management functions" module + * description. + * + * 4. Get the 32 bit Random number using RNG_GetRandomNumber() function + * + * 5. To get another 32 bit Random number, go to step 3. + * + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_rng.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup RNG + * @brief RNG driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RNG_Private_Functions + * @{ + */ + +/** @defgroup RNG_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + This section provides functions allowing to + - Initialize the RNG peripheral + - Enable or disable the RNG peripheral + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the RNG peripheral registers to their default reset values. + * @param None + * @retval None + */ +void RNG_DeInit(void) +{ + /* Enable RNG reset state */ + RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, ENABLE); + + /* Release RNG from reset state */ + RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, DISABLE); +} + +/** + * @brief Enables or disables the RNG peripheral. + * @param NewState: new state of the RNG peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RNG_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the RNG */ + RNG->CR |= RNG_CR_RNGEN; + } + else + { + /* Disable the RNG */ + RNG->CR &= ~RNG_CR_RNGEN; + } +} +/** + * @} + */ + +/** @defgroup RNG_Group2 Get 32 bit Random number function + * @brief Get 32 bit Random number function + * + +@verbatim + =============================================================================== + Get 32 bit Random number function + =============================================================================== + This section provides a function allowing to get the 32 bit Random number + + @note Before to call this function you have to wait till DRDY flag is set, + using RNG_GetFlagStatus(RNG_FLAG_DRDY) function. + +@endverbatim + * @{ + */ + + +/** + * @brief Returns a 32-bit random number. + * + * @note Before to call this function you have to wait till DRDY (data ready) + * flag is set, using RNG_GetFlagStatus(RNG_FLAG_DRDY) function. + * @note Each time the the Random number data is read (using RNG_GetRandomNumber() + * function), the RNG_FLAG_DRDY flag is automatically cleared. + * @note In the case of a seed error, the generation of random numbers is + * interrupted for as long as the SECS bit is '1'. If a number is + * available in the RNG_DR register, it must not be used because it may + * not have enough entropy. In this case, it is recommended to clear the + * SEIS bit(using RNG_ClearFlag(RNG_FLAG_SECS) function), then disable + * and enable the RNG peripheral (using RNG_Cmd() function) to + * reinitialize and restart the RNG. + * @note In the case of a clock error, the RNG is no more able to generate + * random numbers because the PLL48CLK clock is not correct. User have + * to check that the clock controller is correctly configured to provide + * the RNG clock and clear the CEIS bit (using RNG_ClearFlag(RNG_FLAG_CECS) + * function) . The clock error has no impact on the previously generated + * random numbers, and the RNG_DR register contents can be used. + * + * @param None + * @retval 32-bit random number. + */ +uint32_t RNG_GetRandomNumber(void) +{ + /* Return the 32 bit random number from the DR register */ + return RNG->DR; +} + + +/** + * @} + */ + +/** @defgroup RNG_Group3 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + + This section provides functions allowing to configure the RNG Interrupts and + to get the status and clear flags and Interrupts pending bits. + + The RNG provides 3 Interrupts sources and 3 Flags: + + Flags : + ---------- + 1. RNG_FLAG_DRDY : In the case of the RNG_DR register contains valid + random data. it is cleared by reading the valid data + (using RNG_GetRandomNumber() function). + + 2. RNG_FLAG_CECS : In the case of a seed error detection. + + 3. RNG_FLAG_SECS : In the case of a clock error detection. + + + Interrupts : + ------------ + if enabled, an RNG interrupt is pending : + + 1. In the case of the RNG_DR register contains valid random data. + This interrupt source is cleared once the RNG_DR register has been read + (using RNG_GetRandomNumber() function) until a new valid value is + computed. + + or + 2. In the case of a seed error : One of the following faulty sequences has + been detected: + - More than 64 consecutive bits at the same value (0 or 1) + - More than 32 consecutive alternance of 0 and 1 (0101010101...01) + This interrupt source is cleared using RNG_ClearITPendingBit(RNG_IT_SEI) + function. + + or + 3. In the case of a clock error : the PLL48CLK (RNG peripheral clock source) + was not correctly detected (fPLL48CLK< fHCLK/16). + This interrupt source is cleared using RNG_ClearITPendingBit(RNG_IT_CEI) + function. + @note In this case, User have to check that the clock controller is + correctly configured to provide the RNG clock. + + Managing the RNG controller events : + ------------------------------------ + The user should identify which mode will be used in his application to manage + the RNG controller events: Polling mode or Interrupt mode. + + 1. In the Polling Mode it is advised to use the following functions: + - RNG_GetFlagStatus() : to check if flags events occur. + - RNG_ClearFlag() : to clear the flags events. + + @note RNG_FLAG_DRDY can not be cleared by RNG_ClearFlag(). it is cleared only + by reading the Random number data. + + 2. In the Interrupt Mode it is advised to use the following functions: + - RNG_ITConfig() : to enable or disable the interrupt source. + - RNG_GetITStatus() : to check if Interrupt occurs. + - RNG_ClearITPendingBit() : to clear the Interrupt pending Bit + (corresponding Flag). + + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the RNG interrupt. + * @note The RNG provides 3 interrupt sources, + * - Computed data is ready event (DRDY), and + * - Seed error Interrupt (SEI) and + * - Clock error Interrupt (CEI), + * all these interrupts sources are enabled by setting the IE bit in + * CR register. However, each interrupt have its specific status bit + * (see RNG_GetITStatus() function) and clear bit except the DRDY event + * (see RNG_ClearITPendingBit() function). + * @param NewState: new state of the RNG interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RNG_ITConfig(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the RNG interrupt */ + RNG->CR |= RNG_CR_IE; + } + else + { + /* Disable the RNG interrupt */ + RNG->CR &= ~RNG_CR_IE; + } +} + +/** + * @brief Checks whether the specified RNG flag is set or not. + * @param RNG_FLAG: specifies the RNG flag to check. + * This parameter can be one of the following values: + * @arg RNG_FLAG_DRDY: Data Ready flag. + * @arg RNG_FLAG_CECS: Clock Error Current flag. + * @arg RNG_FLAG_SECS: Seed Error Current flag. + * @retval The new state of RNG_FLAG (SET or RESET). + */ +FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_RNG_GET_FLAG(RNG_FLAG)); + + /* Check the status of the specified RNG flag */ + if ((RNG->SR & RNG_FLAG) != (uint8_t)RESET) + { + /* RNG_FLAG is set */ + bitstatus = SET; + } + else + { + /* RNG_FLAG is reset */ + bitstatus = RESET; + } + /* Return the RNG_FLAG status */ + return bitstatus; +} + + +/** + * @brief Clears the RNG flags. + * @param RNG_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg RNG_FLAG_CECS: Clock Error Current flag. + * @arg RNG_FLAG_SECS: Seed Error Current flag. + * @note RNG_FLAG_DRDY can not be cleared by RNG_ClearFlag() function. + * This flag is cleared only by reading the Random number data (using + * RNG_GetRandomNumber() function). + * @retval None + */ +void RNG_ClearFlag(uint8_t RNG_FLAG) +{ + /* Check the parameters */ + assert_param(IS_RNG_CLEAR_FLAG(RNG_FLAG)); + /* Clear the selected RNG flags */ + RNG->SR = ~(uint32_t)(((uint32_t)RNG_FLAG) << 4); +} + +/** + * @brief Checks whether the specified RNG interrupt has occurred or not. + * @param RNG_IT: specifies the RNG interrupt source to check. + * This parameter can be one of the following values: + * @arg RNG_IT_CEI: Clock Error Interrupt. + * @arg RNG_IT_SEI: Seed Error Interrupt. + * @retval The new state of RNG_IT (SET or RESET). + */ +ITStatus RNG_GetITStatus(uint8_t RNG_IT) +{ + ITStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_RNG_GET_IT(RNG_IT)); + + /* Check the status of the specified RNG interrupt */ + if ((RNG->SR & RNG_IT) != (uint8_t)RESET) + { + /* RNG_IT is set */ + bitstatus = SET; + } + else + { + /* RNG_IT is reset */ + bitstatus = RESET; + } + /* Return the RNG_IT status */ + return bitstatus; +} + + +/** + * @brief Clears the RNG interrupt pending bit(s). + * @param RNG_IT: specifies the RNG interrupt pending bit(s) to clear. + * This parameter can be any combination of the following values: + * @arg RNG_IT_CEI: Clock Error Interrupt. + * @arg RNG_IT_SEI: Seed Error Interrupt. + * @retval None + */ +void RNG_ClearITPendingBit(uint8_t RNG_IT) +{ + /* Check the parameters */ + assert_param(IS_RNG_IT(RNG_IT)); + + /* Clear the selected RNG interrupt pending bit */ + RNG->SR = (uint8_t)~RNG_IT; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c new file mode 100644 index 0000000..159f0f3 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c @@ -0,0 +1,2732 @@ +/** + ****************************************************************************** + * @file stm32f4xx_rtc.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Real-Time Clock (RTC) peripheral: + * - Initialization + * - Calendar (Time and Date) configuration + * - Alarms (Alarm A and Alarm B) configuration + * - WakeUp Timer configuration + * - Daylight Saving configuration + * - Output pin Configuration + * - Coarse digital Calibration configuration + * - Smooth digital Calibration configuration + * - TimeStamp configuration + * - Tampers configuration + * - Backup Data Registers configuration + * - Shift control synchronisation + * - RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration + * - Interrupts and flags management + * + * @verbatim + * + * =================================================================== + * Backup Domain Operating Condition + * =================================================================== + * The real-time clock (RTC), the RTC backup registers, and the backup + * SRAM (BKP SRAM) can be powered from the VBAT voltage when the main + * VDD supply is powered off. + * To retain the content of the RTC backup registers, backup SRAM, + * and supply the RTC when VDD is turned off, VBAT pin can be connected + * to an optional standby voltage supplied by a battery or by another + * source. + * + * To allow the RTC to operate even when the main digital supply (VDD) + * is turned off, the VBAT pin powers the following blocks: + * 1 - The RTC + * 2 - The LSE oscillator + * 3 - The backup SRAM when the low power backup regulator is enabled + * 4 - PC13 to PC15 I/Os, plus PI8 I/O (when available) + * + * When the backup domain is supplied by VDD (analog switch connected + * to VDD), the following functions are available: + * 1 - PC14 and PC15 can be used as either GPIO or LSE pins + * 2 - PC13 can be used as a GPIO or as the RTC_AF1 pin + * 3 - PI8 can be used as a GPIO or as the RTC_AF2 pin + * + * When the backup domain is supplied by VBAT (analog switch connected + * to VBAT because VDD is not present), the following functions are available: + * 1 - PC14 and PC15 can be used as LSE pins only + * 2 - PC13 can be used as the RTC_AF1 pin + * 3 - PI8 can be used as the RTC_AF2 pin + * + * =================================================================== + * Backup Domain Reset + * =================================================================== + * The backup domain reset sets all RTC registers and the RCC_BDCR + * register to their reset values. The BKPSRAM is not affected by this + * reset. The only way of resetting the BKPSRAM is through the Flash + * interface by requesting a protection level change from 1 to 0. + * A backup domain reset is generated when one of the following events + * occurs: + * 1 - Software reset, triggered by setting the BDRST bit in the + * RCC Backup domain control register (RCC_BDCR). You can use the + * RCC_BackupResetCmd(). + * 2 - VDD or VBAT power on, if both supplies have previously been + * powered off. + * + * =================================================================== + * Backup Domain Access + * =================================================================== + * After reset, the backup domain (RTC registers, RTC backup data + * registers and backup SRAM) is protected against possible unwanted + * write accesses. + * To enable access to the RTC Domain and RTC registers, proceed as follows: + * - Enable the Power Controller (PWR) APB1 interface clock using the + * RCC_APB1PeriphClockCmd() function. + * - Enable access to RTC domain using the PWR_BackupAccessCmd() function. + * - Select the RTC clock source using the RCC_RTCCLKConfig() function. + * - Enable RTC Clock using the RCC_RTCCLKCmd() function. + * + * =================================================================== + * RTC Driver: how to use it + * =================================================================== + * - Enable the RTC domain access (see description in the section above) + * - Configure the RTC Prescaler (Asynchronous and Synchronous) and + * RTC hour format using the RTC_Init() function. + * + * Time and Date configuration + * =========================== + * - To configure the RTC Calendar (Time and Date) use the RTC_SetTime() + * and RTC_SetDate() functions. + * - To read the RTC Calendar, use the RTC_GetTime() and RTC_GetDate() + * functions. + * - Use the RTC_DayLightSavingConfig() function to add or sub one + * hour to the RTC Calendar. + * + * Alarm configuration + * =================== + * - To configure the RTC Alarm use the RTC_SetAlarm() function. + * - Enable the selected RTC Alarm using the RTC_AlarmCmd() function + * - To read the RTC Alarm, use the RTC_GetAlarm() function. + * - To read the RTC alarm SubSecond, use the RTC_GetAlarmSubSecond() function. + * + * RTC Wakeup configuration + * ======================== + * - Configure the RTC Wakeup Clock source use the RTC_WakeUpClockConfig() + * function. + * - Configure the RTC WakeUp Counter using the RTC_SetWakeUpCounter() + * function + * - Enable the RTC WakeUp using the RTC_WakeUpCmd() function + * - To read the RTC WakeUp Counter register, use the RTC_GetWakeUpCounter() + * function. + * + * Outputs configuration + * ===================== + * The RTC has 2 different outputs: + * - AFO_ALARM: this output is used to manage the RTC Alarm A, Alarm B + * and WaKeUp signals. + * To output the selected RTC signal on RTC_AF1 pin, use the + * RTC_OutputConfig() function. + * - AFO_CALIB: this output is 512Hz signal or 1Hz . + * To output the RTC Clock on RTC_AF1 pin, use the RTC_CalibOutputCmd() + * function. + * + * Smooth digital Calibration configuration + * ================================= + * - Configure the RTC Original Digital Calibration Value and the corresponding + * calibration cycle period (32s,16s and 8s) using the RTC_SmoothCalibConfig() + * function. + * + * Coarse digital Calibration configuration + * ================================= + * - Configure the RTC Coarse Calibration Value and the corresponding + * sign using the RTC_CoarseCalibConfig() function. + * - Enable the RTC Coarse Calibration using the RTC_CoarseCalibCmd() + * function + * + * TimeStamp configuration + * ======================= + * - Configure the RTC_AF1 trigger and enables the RTC TimeStamp + * using the RTC_TimeStampCmd() function. + * - To read the RTC TimeStamp Time and Date register, use the + * RTC_GetTimeStamp() function. + * - To read the RTC TimeStamp SubSecond register, use the + * RTC_GetTimeStampSubSecond() function. + * - The TAMPER1 alternate function can be mapped either to RTC_AF1(PC13) + * or RTC_AF2 (PI8) depending on the value of TAMP1INSEL bit in + * RTC_TAFCR register. You can use the RTC_TamperPinSelection() + * function to select the corresponding pin. + * + * Tamper configuration + * ==================== + * - Enable the RTC Tamper using the RTC_TamperCmd() function. + * - Configure the Tamper filter count using RTC_TamperFilterConfig() + * function. + * - Configure the RTC Tamper trigger Edge or Level according to the Tamper + * filter (if equal to 0 Edge else Level) value using the RTC_TamperConfig() function. + * - Configure the Tamper sampling frequency using RTC_TamperSamplingFreqConfig() + * function. + * - Configure the Tamper precharge or discharge duration using + * RTC_TamperPinsPrechargeDuration() function. + * - Enable the Tamper Pull-UP using RTC_TamperPullUpDisableCmd() function. + * - Enable the Time stamp on Tamper detection event using + * RTC_TSOnTamperDetecCmd() function. + * - The TIMESTAMP alternate function can be mapped to either RTC_AF1 + * or RTC_AF2 depending on the value of the TSINSEL bit in the + * RTC_TAFCR register. You can use the RTC_TimeStampPinSelection() + * function to select the corresponding pin. + * + * Backup Data Registers configuration + * =================================== + * - To write to the RTC Backup Data registers, use the RTC_WriteBackupRegister() + * function. + * - To read the RTC Backup Data registers, use the RTC_ReadBackupRegister() + * function. + * + * =================================================================== + * RTC and low power modes + * =================================================================== + * The MCU can be woken up from a low power mode by an RTC alternate + * function. + * The RTC alternate functions are the RTC alarms (Alarm A and Alarm B), + * RTC wakeup, RTC tamper event detection and RTC time stamp event detection. + * These RTC alternate functions can wake up the system from the Stop + * and Standby lowpower modes. + * The system can also wake up from low power modes without depending + * on an external interrupt (Auto-wakeup mode), by using the RTC alarm + * or the RTC wakeup events. + * The RTC provides a programmable time base for waking up from the + * Stop or Standby mode at regular intervals. + * Wakeup from STOP and Standby modes is possible only when the RTC + * clock source is LSE or LSI. + * + * =================================================================== + * Selection of RTC_AF1 alternate functions + * =================================================================== + * The RTC_AF1 pin (PC13) can be used for the following purposes: + * - AFO_ALARM output + * - AFO_CALIB output + * - AFI_TAMPER + * - AFI_TIMESTAMP + * + * +-------------------------------------------------------------------------------------------------------------+ + * | Pin |AFO_ALARM |AFO_CALIB |AFI_TAMPER |AFI_TIMESTAMP | TAMP1INSEL | TSINSEL |ALARMOUTTYPE | + * | configuration | ENABLED | ENABLED | ENABLED | ENABLED |TAMPER1 pin |TIMESTAMP pin | AFO_ALARM | + * | and function | | | | | selection | selection |Configuration | + * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| + * | Alarm out | | | | | Don't | Don't | | + * | output OD | 1 |Don't care|Don't care | Don't care | care | care | 0 | + * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| + * | Alarm out | | | | | Don't | Don't | | + * | output PP | 1 |Don't care|Don't care | Don't care | care | care | 1 | + * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| + * | Calibration out | | | | | Don't | Don't | | + * | output PP | 0 | 1 |Don't care | Don't care | care | care | Don't care | + * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| + * | TAMPER input | | | | | | Don't | | + * | floating | 0 | 0 | 1 | 0 | 0 | care | Don't care | + * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| + * | TIMESTAMP and | | | | | | | | + * | TAMPER input | 0 | 0 | 1 | 1 | 0 | 0 | Don't care | + * | floating | | | | | | | | + * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| + * | TIMESTAMP input | | | | | Don't | | | + * | floating | 0 | 0 | 0 | 1 | care | 0 | Don't care | + * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| + * | Standard GPIO | 0 | 0 | 0 | 0 | Don't care | Don't care | Don't care | + * +-------------------------------------------------------------------------------------------------------------+ + * + * + * =================================================================== + * Selection of RTC_AF2 alternate functions + * =================================================================== + * The RTC_AF2 pin (PI8) can be used for the following purposes: + * - AFI_TAMPER + * - AFI_TIMESTAMP + * + * +---------------------------------------------------------------------------------------+ + * | Pin |AFI_TAMPER |AFI_TIMESTAMP | TAMP1INSEL | TSINSEL |ALARMOUTTYPE | + * | configuration | ENABLED | ENABLED |TAMPER1 pin |TIMESTAMP pin | AFO_ALARM | + * | and function | | | selection | selection |Configuration | + * |-----------------|-----------|--------------|------------|--------------|--------------| + * | TAMPER input | | | | Don't | | + * | floating | 1 | 0 | 1 | care | Don't care | + * |-----------------|-----------|--------------|------------|--------------|--------------| + * | TIMESTAMP and | | | | | | + * | TAMPER input | 1 | 1 | 1 | 1 | Don't care | + * | floating | | | | | | + * |-----------------|-----------|--------------|------------|--------------|--------------| + * | TIMESTAMP input | | | Don't | | | + * | floating | 0 | 1 | care | 1 | Don't care | + * |-----------------|-----------|--------------|------------|--------------|--------------| + * | Standard GPIO | 0 | 0 | Don't care | Don't care | Don't care | + * +---------------------------------------------------------------------------------------+ + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_rtc.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup RTC + * @brief RTC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* Masks Definition */ +#define RTC_TR_RESERVED_MASK ((uint32_t)0x007F7F7F) +#define RTC_DR_RESERVED_MASK ((uint32_t)0x00FFFF3F) +#define RTC_INIT_MASK ((uint32_t)0xFFFFFFFF) +#define RTC_RSF_MASK ((uint32_t)0xFFFFFF5F) +#define RTC_FLAGS_MASK ((uint32_t)(RTC_FLAG_TSOVF | RTC_FLAG_TSF | RTC_FLAG_WUTF | \ + RTC_FLAG_ALRBF | RTC_FLAG_ALRAF | RTC_FLAG_INITF | \ + RTC_FLAG_RSF | RTC_FLAG_INITS | RTC_FLAG_WUTWF | \ + RTC_FLAG_ALRBWF | RTC_FLAG_ALRAWF | RTC_FLAG_TAMP1F )) + +#define INITMODE_TIMEOUT ((uint32_t) 0x00010000) +#define SYNCHRO_TIMEOUT ((uint32_t) 0x00020000) +#define RECALPF_TIMEOUT ((uint32_t) 0x00020000) +#define SHPF_TIMEOUT ((uint32_t) 0x00001000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static uint8_t RTC_ByteToBcd2(uint8_t Value); +static uint8_t RTC_Bcd2ToByte(uint8_t Value); + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RTC_Private_Functions + * @{ + */ + +/** @defgroup RTC_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + + This section provide functions allowing to initialize and configure the RTC + Prescaler (Synchronous and Asynchronous), RTC Hour format, disable RTC registers + Write protection, enter and exit the RTC initialization mode, RTC registers + synchronization check and reference clock detection enable. + + 1. The RTC Prescaler is programmed to generate the RTC 1Hz time base. It is + split into 2 programmable prescalers to minimize power consumption. + - A 7-bit asynchronous prescaler and A 13-bit synchronous prescaler. + - When both prescalers are used, it is recommended to configure the asynchronous + prescaler to a high value to minimize consumption. + + 2. All RTC registers are Write protected. Writing to the RTC registers + is enabled by writing a key into the Write Protection register, RTC_WPR. + + 3. To Configure the RTC Calendar, user application should enter initialization + mode. In this mode, the calendar counter is stopped and its value can be + updated. When the initialization sequence is complete, the calendar restarts + counting after 4 RTCCLK cycles. + + 4. To read the calendar through the shadow registers after Calendar initialization, + calendar update or after wakeup from low power modes the software must first + clear the RSF flag. The software must then wait until it is set again before + reading the calendar, which means that the calendar registers have been + correctly copied into the RTC_TR and RTC_DR shadow registers. + The RTC_WaitForSynchro() function implements the above software sequence + (RSF clear and RSF check). + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the RTC registers to their default reset values. + * @note This function doesn't reset the RTC Clock source and RTC Backup Data + * registers. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC registers are deinitialized + * - ERROR: RTC registers are not deinitialized + */ +ErrorStatus RTC_DeInit(void) +{ + __IO uint32_t wutcounter = 0x00; + uint32_t wutwfstatus = 0x00; + ErrorStatus status = ERROR; + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + /* Reset TR, DR and CR registers */ + RTC->TR = (uint32_t)0x00000000; + RTC->DR = (uint32_t)0x00002101; + /* Reset All CR bits except CR[2:0] */ + RTC->CR &= (uint32_t)0x00000007; + + /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ + do + { + wutwfstatus = RTC->ISR & RTC_ISR_WUTWF; + wutcounter++; + } while((wutcounter != INITMODE_TIMEOUT) && (wutwfstatus == 0x00)); + + if ((RTC->ISR & RTC_ISR_WUTWF) == RESET) + { + status = ERROR; + } + else + { + /* Reset all RTC CR register bits */ + RTC->CR &= (uint32_t)0x00000000; + RTC->WUTR = (uint32_t)0x0000FFFF; + RTC->PRER = (uint32_t)0x007F00FF; + RTC->CALIBR = (uint32_t)0x00000000; + RTC->ALRMAR = (uint32_t)0x00000000; + RTC->ALRMBR = (uint32_t)0x00000000; + + /* Reset ISR register and exit initialization mode */ + RTC->ISR = (uint32_t)0x00000000; + + /* Reset Tamper and alternate functions configuration register */ + RTC->TAFCR = 0x00000000; + + if(RTC_WaitForSynchro() == ERROR) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Initializes the RTC registers according to the specified parameters + * in RTC_InitStruct. + * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure that contains + * the configuration information for the RTC peripheral. + * @note The RTC Prescaler register is write protected and can be written in + * initialization mode only. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC registers are initialized + * - ERROR: RTC registers are not initialized + */ +ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_HOUR_FORMAT(RTC_InitStruct->RTC_HourFormat)); + assert_param(IS_RTC_ASYNCH_PREDIV(RTC_InitStruct->RTC_AsynchPrediv)); + assert_param(IS_RTC_SYNCH_PREDIV(RTC_InitStruct->RTC_SynchPrediv)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + /* Clear RTC CR FMT Bit */ + RTC->CR &= ((uint32_t)~(RTC_CR_FMT)); + /* Set RTC_CR register */ + RTC->CR |= ((uint32_t)(RTC_InitStruct->RTC_HourFormat)); + + /* Configure the RTC PRER */ + RTC->PRER = (uint32_t)(RTC_InitStruct->RTC_SynchPrediv); + RTC->PRER |= (uint32_t)(RTC_InitStruct->RTC_AsynchPrediv << 16); + + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + status = SUCCESS; + } + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Fills each RTC_InitStruct member with its default value. + * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure which will be + * initialized. + * @retval None + */ +void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct) +{ + /* Initialize the RTC_HourFormat member */ + RTC_InitStruct->RTC_HourFormat = RTC_HourFormat_24; + + /* Initialize the RTC_AsynchPrediv member */ + RTC_InitStruct->RTC_AsynchPrediv = (uint32_t)0x7F; + + /* Initialize the RTC_SynchPrediv member */ + RTC_InitStruct->RTC_SynchPrediv = (uint32_t)0xFF; +} + +/** + * @brief Enables or disables the RTC registers write protection. + * @note All the RTC registers are write protected except for RTC_ISR[13:8], + * RTC_TAFCR and RTC_BKPxR. + * @note Writing a wrong key reactivates the write protection. + * @note The protection mechanism is not affected by system reset. + * @param NewState: new state of the write protection. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_WriteProtectionCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + } + else + { + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + } +} + +/** + * @brief Enters the RTC Initialization mode. + * @note The RTC Initialization mode is write protected, use the + * RTC_WriteProtectionCmd(DISABLE) before calling this function. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC is in Init mode + * - ERROR: RTC is not in Init mode + */ +ErrorStatus RTC_EnterInitMode(void) +{ + __IO uint32_t initcounter = 0x00; + ErrorStatus status = ERROR; + uint32_t initstatus = 0x00; + + /* Check if the Initialization mode is set */ + if ((RTC->ISR & RTC_ISR_INITF) == (uint32_t)RESET) + { + /* Set the Initialization mode */ + RTC->ISR = (uint32_t)RTC_INIT_MASK; + + /* Wait till RTC is in INIT state and if Time out is reached exit */ + do + { + initstatus = RTC->ISR & RTC_ISR_INITF; + initcounter++; + } while((initcounter != INITMODE_TIMEOUT) && (initstatus == 0x00)); + + if ((RTC->ISR & RTC_ISR_INITF) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + } + else + { + status = SUCCESS; + } + + return (status); +} + +/** + * @brief Exits the RTC Initialization mode. + * @note When the initialization sequence is complete, the calendar restarts + * counting after 4 RTCCLK cycles. + * @note The RTC Initialization mode is write protected, use the + * RTC_WriteProtectionCmd(DISABLE) before calling this function. + * @param None + * @retval None + */ +void RTC_ExitInitMode(void) +{ + /* Exit Initialization mode */ + RTC->ISR &= (uint32_t)~RTC_ISR_INIT; +} + +/** + * @brief Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are + * synchronized with RTC APB clock. + * @note The RTC Resynchronization mode is write protected, use the + * RTC_WriteProtectionCmd(DISABLE) before calling this function. + * @note To read the calendar through the shadow registers after Calendar + * initialization, calendar update or after wakeup from low power modes + * the software must first clear the RSF flag. + * The software must then wait until it is set again before reading + * the calendar, which means that the calendar registers have been + * correctly copied into the RTC_TR and RTC_DR shadow registers. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC registers are synchronised + * - ERROR: RTC registers are not synchronised + */ +ErrorStatus RTC_WaitForSynchro(void) +{ + __IO uint32_t synchrocounter = 0; + ErrorStatus status = ERROR; + uint32_t synchrostatus = 0x00; + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Clear RSF flag */ + RTC->ISR &= (uint32_t)RTC_RSF_MASK; + + /* Wait the registers to be synchronised */ + do + { + synchrostatus = RTC->ISR & RTC_ISR_RSF; + synchrocounter++; + } while((synchrocounter != SYNCHRO_TIMEOUT) && (synchrostatus == 0x00)); + + if ((RTC->ISR & RTC_ISR_RSF) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return (status); +} + +/** + * @brief Enables or disables the RTC reference clock detection. + * @param NewState: new state of the RTC reference clock. + * This parameter can be: ENABLE or DISABLE. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC reference clock detection is enabled + * - ERROR: RTC reference clock detection is disabled + */ +ErrorStatus RTC_RefClockCmd(FunctionalState NewState) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + if (NewState != DISABLE) + { + /* Enable the RTC reference clock detection */ + RTC->CR |= RTC_CR_REFCKON; + } + else + { + /* Disable the RTC reference clock detection */ + RTC->CR &= ~RTC_CR_REFCKON; + } + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + status = SUCCESS; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Enables or Disables the Bypass Shadow feature. + * @note When the Bypass Shadow is enabled the calendar value are taken + * directly from the Calendar counter. + * @param NewState: new state of the Bypass Shadow feature. + * This parameter can be: ENABLE or DISABLE. + * @retval None +*/ +void RTC_BypassShadowCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + if (NewState != DISABLE) + { + /* Set the BYPSHAD bit */ + RTC->CR |= (uint8_t)RTC_CR_BYPSHAD; + } + else + { + /* Reset the BYPSHAD bit */ + RTC->CR &= (uint8_t)~RTC_CR_BYPSHAD; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @} + */ + +/** @defgroup RTC_Group2 Time and Date configuration functions + * @brief Time and Date configuration functions + * +@verbatim + =============================================================================== + Time and Date configuration functions + =============================================================================== + + This section provide functions allowing to program and read the RTC Calendar + (Time and Date). + +@endverbatim + * @{ + */ + +/** + * @brief Set the RTC current time. + * @param RTC_Format: specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that contains + * the time configuration information for the RTC. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Time register is configured + * - ERROR: RTC Time register is not configured + */ +ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) +{ + uint32_t tmpreg = 0; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + if (RTC_Format == RTC_Format_BIN) + { + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + assert_param(IS_RTC_HOUR12(RTC_TimeStruct->RTC_Hours)); + assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12)); + } + else + { + RTC_TimeStruct->RTC_H12 = 0x00; + assert_param(IS_RTC_HOUR24(RTC_TimeStruct->RTC_Hours)); + } + assert_param(IS_RTC_MINUTES(RTC_TimeStruct->RTC_Minutes)); + assert_param(IS_RTC_SECONDS(RTC_TimeStruct->RTC_Seconds)); + } + else + { + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + tmpreg = RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours); + assert_param(IS_RTC_HOUR12(tmpreg)); + assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12)); + } + else + { + RTC_TimeStruct->RTC_H12 = 0x00; + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours))); + } + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds))); + } + + /* Check the input parameters format */ + if (RTC_Format != RTC_Format_BIN) + { + tmpreg = (((uint32_t)(RTC_TimeStruct->RTC_Hours) << 16) | \ + ((uint32_t)(RTC_TimeStruct->RTC_Minutes) << 8) | \ + ((uint32_t)RTC_TimeStruct->RTC_Seconds) | \ + ((uint32_t)(RTC_TimeStruct->RTC_H12) << 16)); + } + else + { + tmpreg = (uint32_t)(((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Hours) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Minutes) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Seconds)) | \ + (((uint32_t)RTC_TimeStruct->RTC_H12) << 16)); + } + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + /* Set the RTC_TR register */ + RTC->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK); + + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + if(RTC_WaitForSynchro() == ERROR) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + + } + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Fills each RTC_TimeStruct member with its default value + * (Time = 00h:00min:00sec). + * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure which will be + * initialized. + * @retval None + */ +void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct) +{ + /* Time = 00h:00min:00sec */ + RTC_TimeStruct->RTC_H12 = RTC_H12_AM; + RTC_TimeStruct->RTC_Hours = 0; + RTC_TimeStruct->RTC_Minutes = 0; + RTC_TimeStruct->RTC_Seconds = 0; +} + +/** + * @brief Get the RTC current Time. + * @param RTC_Format: specifies the format of the returned parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that will + * contain the returned current time configuration. + * @retval None + */ +void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + /* Get the RTC_TR register */ + tmpreg = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK); + + /* Fill the structure fields with the read parameters */ + RTC_TimeStruct->RTC_Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16); + RTC_TimeStruct->RTC_Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8); + RTC_TimeStruct->RTC_Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)); + RTC_TimeStruct->RTC_H12 = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16); + + /* Check the input parameters format */ + if (RTC_Format == RTC_Format_BIN) + { + /* Convert the structure parameters to Binary format */ + RTC_TimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours); + RTC_TimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes); + RTC_TimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds); + } +} + +/** + * @brief Gets the RTC current Calendar Subseconds value. + * @note This function freeze the Time and Date registers after reading the + * SSR register. + * @param None + * @retval RTC current Calendar Subseconds value. + */ +uint32_t RTC_GetSubSecond(void) +{ + uint32_t tmpreg = 0; + + /* Get subseconds values from the correspondent registers*/ + tmpreg = (uint32_t)(RTC->SSR); + + /* Read DR register to unfroze calendar registers */ + (void) (RTC->DR); + + return (tmpreg); +} + +/** + * @brief Set the RTC current date. + * @param RTC_Format: specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that contains + * the date configuration information for the RTC. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Date register is configured + * - ERROR: RTC Date register is not configured + */ +ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct) +{ + uint32_t tmpreg = 0; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + if ((RTC_Format == RTC_Format_BIN) && ((RTC_DateStruct->RTC_Month & 0x10) == 0x10)) + { + RTC_DateStruct->RTC_Month = (RTC_DateStruct->RTC_Month & (uint32_t)~(0x10)) + 0x0A; + } + if (RTC_Format == RTC_Format_BIN) + { + assert_param(IS_RTC_YEAR(RTC_DateStruct->RTC_Year)); + assert_param(IS_RTC_MONTH(RTC_DateStruct->RTC_Month)); + assert_param(IS_RTC_DATE(RTC_DateStruct->RTC_Date)); + } + else + { + assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year))); + tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month); + assert_param(IS_RTC_MONTH(tmpreg)); + tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date); + assert_param(IS_RTC_DATE(tmpreg)); + } + assert_param(IS_RTC_WEEKDAY(RTC_DateStruct->RTC_WeekDay)); + + /* Check the input parameters format */ + if (RTC_Format != RTC_Format_BIN) + { + tmpreg = ((((uint32_t)RTC_DateStruct->RTC_Year) << 16) | \ + (((uint32_t)RTC_DateStruct->RTC_Month) << 8) | \ + ((uint32_t)RTC_DateStruct->RTC_Date) | \ + (((uint32_t)RTC_DateStruct->RTC_WeekDay) << 13)); + } + else + { + tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Year) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Month) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Date)) | \ + ((uint32_t)RTC_DateStruct->RTC_WeekDay << 13)); + } + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + /* Set the RTC_DR register */ + RTC->DR = (uint32_t)(tmpreg & RTC_DR_RESERVED_MASK); + + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + if(RTC_WaitForSynchro() == ERROR) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Fills each RTC_DateStruct member with its default value + * (Monday, January 01 xx00). + * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure which will be + * initialized. + * @retval None + */ +void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct) +{ + /* Monday, January 01 xx00 */ + RTC_DateStruct->RTC_WeekDay = RTC_Weekday_Monday; + RTC_DateStruct->RTC_Date = 1; + RTC_DateStruct->RTC_Month = RTC_Month_January; + RTC_DateStruct->RTC_Year = 0; +} + +/** + * @brief Get the RTC current date. + * @param RTC_Format: specifies the format of the returned parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that will + * contain the returned current date configuration. + * @retval None + */ +void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + /* Get the RTC_TR register */ + tmpreg = (uint32_t)(RTC->DR & RTC_DR_RESERVED_MASK); + + /* Fill the structure fields with the read parameters */ + RTC_DateStruct->RTC_Year = (uint8_t)((tmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16); + RTC_DateStruct->RTC_Month = (uint8_t)((tmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8); + RTC_DateStruct->RTC_Date = (uint8_t)(tmpreg & (RTC_DR_DT | RTC_DR_DU)); + RTC_DateStruct->RTC_WeekDay = (uint8_t)((tmpreg & (RTC_DR_WDU)) >> 13); + + /* Check the input parameters format */ + if (RTC_Format == RTC_Format_BIN) + { + /* Convert the structure parameters to Binary format */ + RTC_DateStruct->RTC_Year = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year); + RTC_DateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month); + RTC_DateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date); + } +} + +/** + * @} + */ + +/** @defgroup RTC_Group3 Alarms configuration functions + * @brief Alarms (Alarm A and Alarm B) configuration functions + * +@verbatim + =============================================================================== + Alarms (Alarm A and Alarm B) configuration functions + =============================================================================== + + This section provide functions allowing to program and read the RTC Alarms. + +@endverbatim + * @{ + */ + +/** + * @brief Set the specified RTC Alarm. + * @note The Alarm register can only be written when the corresponding Alarm + * is disabled (Use the RTC_AlarmCmd(DISABLE)). + * @param RTC_Format: specifies the format of the returned parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_Alarm: specifies the alarm to be configured. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A + * @arg RTC_Alarm_B: to select Alarm B + * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that + * contains the alarm configuration parameters. + * @retval None + */ +void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + assert_param(IS_RTC_ALARM(RTC_Alarm)); + assert_param(IS_ALARM_MASK(RTC_AlarmStruct->RTC_AlarmMask)); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel)); + + if (RTC_Format == RTC_Format_BIN) + { + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + assert_param(IS_RTC_HOUR12(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)); + assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12)); + } + else + { + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00; + assert_param(IS_RTC_HOUR24(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)); + } + assert_param(IS_RTC_MINUTES(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes)); + assert_param(IS_RTC_SECONDS(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)); + + if(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date) + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_AlarmStruct->RTC_AlarmDateWeekDay)); + } + else + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_AlarmStruct->RTC_AlarmDateWeekDay)); + } + } + else + { + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours); + assert_param(IS_RTC_HOUR12(tmpreg)); + assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12)); + } + else + { + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00; + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours))); + } + + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds))); + + if(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date) + { + tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(tmpreg)); + } + else + { + tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(tmpreg)); + } + } + + /* Check the input parameters format */ + if (RTC_Format != RTC_Format_BIN) + { + tmpreg = (((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 16) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask)); + } + else + { + tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask)); + } + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Configure the Alarm register */ + if (RTC_Alarm == RTC_Alarm_A) + { + RTC->ALRMAR = (uint32_t)tmpreg; + } + else + { + RTC->ALRMBR = (uint32_t)tmpreg; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Fills each RTC_AlarmStruct member with its default value + * (Time = 00h:00mn:00sec / Date = 1st day of the month/Mask = + * all fields are masked). + * @param RTC_AlarmStruct: pointer to a @ref RTC_AlarmTypeDef structure which + * will be initialized. + * @retval None + */ +void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct) +{ + /* Alarm Time Settings : Time = 00h:00mn:00sec */ + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = RTC_H12_AM; + RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = 0; + RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = 0; + RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = 0; + + /* Alarm Date Settings : Date = 1st day of the month */ + RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; + RTC_AlarmStruct->RTC_AlarmDateWeekDay = 1; + + /* Alarm Masks Settings : Mask = all fields are not masked */ + RTC_AlarmStruct->RTC_AlarmMask = RTC_AlarmMask_None; +} + +/** + * @brief Get the RTC Alarm value and masks. + * @param RTC_Format: specifies the format of the output parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_Alarm: specifies the alarm to be read. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A + * @arg RTC_Alarm_B: to select Alarm B + * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that will + * contains the output alarm configuration values. + * @retval None + */ +void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + assert_param(IS_RTC_ALARM(RTC_Alarm)); + + /* Get the RTC_ALRMxR register */ + if (RTC_Alarm == RTC_Alarm_A) + { + tmpreg = (uint32_t)(RTC->ALRMAR); + } + else + { + tmpreg = (uint32_t)(RTC->ALRMBR); + } + + /* Fill the structure with the read parameters */ + RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = (uint32_t)((tmpreg & (RTC_ALRMAR_HT | \ + RTC_ALRMAR_HU)) >> 16); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = (uint32_t)((tmpreg & (RTC_ALRMAR_MNT | \ + RTC_ALRMAR_MNU)) >> 8); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = (uint32_t)(tmpreg & (RTC_ALRMAR_ST | \ + RTC_ALRMAR_SU)); + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = (uint32_t)((tmpreg & RTC_ALRMAR_PM) >> 16); + RTC_AlarmStruct->RTC_AlarmDateWeekDay = (uint32_t)((tmpreg & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> 24); + RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = (uint32_t)(tmpreg & RTC_ALRMAR_WDSEL); + RTC_AlarmStruct->RTC_AlarmMask = (uint32_t)(tmpreg & RTC_AlarmMask_All); + + if (RTC_Format == RTC_Format_BIN) + { + RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ + RTC_AlarmTime.RTC_Hours); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ + RTC_AlarmTime.RTC_Minutes); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ + RTC_AlarmTime.RTC_Seconds); + RTC_AlarmStruct->RTC_AlarmDateWeekDay = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); + } +} + +/** + * @brief Enables or disables the specified RTC Alarm. + * @param RTC_Alarm: specifies the alarm to be configured. + * This parameter can be any combination of the following values: + * @arg RTC_Alarm_A: to select Alarm A + * @arg RTC_Alarm_B: to select Alarm B + * @param NewState: new state of the specified alarm. + * This parameter can be: ENABLE or DISABLE. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Alarm is enabled/disabled + * - ERROR: RTC Alarm is not enabled/disabled + */ +ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState) +{ + __IO uint32_t alarmcounter = 0x00; + uint32_t alarmstatus = 0x00; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_CMD_ALARM(RTC_Alarm)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Configure the Alarm state */ + if (NewState != DISABLE) + { + RTC->CR |= (uint32_t)RTC_Alarm; + + status = SUCCESS; + } + else + { + /* Disable the Alarm in RTC_CR register */ + RTC->CR &= (uint32_t)~RTC_Alarm; + + /* Wait till RTC ALRxWF flag is set and if Time out is reached exit */ + do + { + alarmstatus = RTC->ISR & (RTC_Alarm >> 8); + alarmcounter++; + } while((alarmcounter != INITMODE_TIMEOUT) && (alarmstatus == 0x00)); + + if ((RTC->ISR & (RTC_Alarm >> 8)) == RESET) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Configure the RTC AlarmA/B Subseconds value and mask.* + * @note This function is performed only when the Alarm is disabled. + * @param RTC_Alarm: specifies the alarm to be configured. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A + * @arg RTC_Alarm_B: to select Alarm B + * @param RTC_AlarmSubSecondValue: specifies the Subseconds value. + * This parameter can be a value from 0 to 0x00007FFF. + * @param RTC_AlarmSubSecondMask: specifies the Subseconds Mask. + * This parameter can be any combination of the following values: + * @arg RTC_AlarmSubSecondMask_All : All Alarm SS fields are masked. + * There is no comparison on sub seconds for Alarm. + * @arg RTC_AlarmSubSecondMask_SS14_1 : SS[14:1] are don't care in Alarm comparison. + * Only SS[0] is compared + * @arg RTC_AlarmSubSecondMask_SS14_2 : SS[14:2] are don't care in Alarm comparison. + * Only SS[1:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_3 : SS[14:3] are don't care in Alarm comparison. + * Only SS[2:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_4 : SS[14:4] are don't care in Alarm comparison. + * Only SS[3:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_5 : SS[14:5] are don't care in Alarm comparison. + * Only SS[4:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_6 : SS[14:6] are don't care in Alarm comparison. + * Only SS[5:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_7 : SS[14:7] are don't care in Alarm comparison. + * Only SS[6:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_8 : SS[14:8] are don't care in Alarm comparison. + * Only SS[7:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_9 : SS[14:9] are don't care in Alarm comparison. + * Only SS[8:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_10: SS[14:10] are don't care in Alarm comparison. + * Only SS[9:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_11: SS[14:11] are don't care in Alarm comparison. + * Only SS[10:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_12: SS[14:12] are don't care in Alarm comparison. + * Only SS[11:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_13: SS[14:13] are don't care in Alarm comparison. + * Only SS[12:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14 : SS[14] is don't care in Alarm comparison. + * Only SS[13:0] are compared + * @arg RTC_AlarmSubSecondMask_None : SS[14:0] are compared and must match + * to activate alarm + * @retval None + */ +void RTC_AlarmSubSecondConfig(uint32_t RTC_Alarm, uint32_t RTC_AlarmSubSecondValue, uint32_t RTC_AlarmSubSecondMask) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_ALARM(RTC_Alarm)); + assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(RTC_AlarmSubSecondValue)); + assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(RTC_AlarmSubSecondMask)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Configure the Alarm A or Alarm B SubSecond registers */ + tmpreg = (uint32_t) (uint32_t)(RTC_AlarmSubSecondValue) | (uint32_t)(RTC_AlarmSubSecondMask); + + if (RTC_Alarm == RTC_Alarm_A) + { + /* Configure the AlarmA SubSecond register */ + RTC->ALRMASSR = tmpreg; + } + else + { + /* Configure the Alarm B SubSecond register */ + RTC->ALRMBSSR = tmpreg; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + +} + +/** + * @brief Gets the RTC Alarm Subseconds value. + * @param RTC_Alarm: specifies the alarm to be read. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A + * @arg RTC_Alarm_B: to select Alarm B + * @param None + * @retval RTC Alarm Subseconds value. + */ +uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm) +{ + uint32_t tmpreg = 0; + + /* Get the RTC_ALRMxR register */ + if (RTC_Alarm == RTC_Alarm_A) + { + tmpreg = (uint32_t)((RTC->ALRMASSR) & RTC_ALRMASSR_SS); + } + else + { + tmpreg = (uint32_t)((RTC->ALRMBSSR) & RTC_ALRMBSSR_SS); + } + + return (tmpreg); +} + +/** + * @} + */ + +/** @defgroup RTC_Group4 WakeUp Timer configuration functions + * @brief WakeUp Timer configuration functions + * +@verbatim + =============================================================================== + WakeUp Timer configuration functions + =============================================================================== + + This section provide functions allowing to program and read the RTC WakeUp. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the RTC Wakeup clock source. + * @note The WakeUp Clock source can only be changed when the RTC WakeUp + * is disabled (Use the RTC_WakeUpCmd(DISABLE)). + * @param RTC_WakeUpClock: Wakeup Clock source. + * This parameter can be one of the following values: + * @arg RTC_WakeUpClock_RTCCLK_Div16: RTC Wakeup Counter Clock = RTCCLK/16 + * @arg RTC_WakeUpClock_RTCCLK_Div8: RTC Wakeup Counter Clock = RTCCLK/8 + * @arg RTC_WakeUpClock_RTCCLK_Div4: RTC Wakeup Counter Clock = RTCCLK/4 + * @arg RTC_WakeUpClock_RTCCLK_Div2: RTC Wakeup Counter Clock = RTCCLK/2 + * @arg RTC_WakeUpClock_CK_SPRE_16bits: RTC Wakeup Counter Clock = CK_SPRE + * @arg RTC_WakeUpClock_CK_SPRE_17bits: RTC Wakeup Counter Clock = CK_SPRE + * @retval None + */ +void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock) +{ + /* Check the parameters */ + assert_param(IS_RTC_WAKEUP_CLOCK(RTC_WakeUpClock)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Clear the Wakeup Timer clock source bits in CR register */ + RTC->CR &= (uint32_t)~RTC_CR_WUCKSEL; + + /* Configure the clock source */ + RTC->CR |= (uint32_t)RTC_WakeUpClock; + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Configures the RTC Wakeup counter. + * @note The RTC WakeUp counter can only be written when the RTC WakeUp + * is disabled (Use the RTC_WakeUpCmd(DISABLE)). + * @param RTC_WakeUpCounter: specifies the WakeUp counter. + * This parameter can be a value from 0x0000 to 0xFFFF. + * @retval None + */ +void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter) +{ + /* Check the parameters */ + assert_param(IS_RTC_WAKEUP_COUNTER(RTC_WakeUpCounter)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Configure the Wakeup Timer counter */ + RTC->WUTR = (uint32_t)RTC_WakeUpCounter; + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Returns the RTC WakeUp timer counter value. + * @param None + * @retval The RTC WakeUp Counter value. + */ +uint32_t RTC_GetWakeUpCounter(void) +{ + /* Get the counter value */ + return ((uint32_t)(RTC->WUTR & RTC_WUTR_WUT)); +} + +/** + * @brief Enables or Disables the RTC WakeUp timer. + * @param NewState: new state of the WakeUp timer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +ErrorStatus RTC_WakeUpCmd(FunctionalState NewState) +{ + __IO uint32_t wutcounter = 0x00; + uint32_t wutwfstatus = 0x00; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + if (NewState != DISABLE) + { + /* Enable the Wakeup Timer */ + RTC->CR |= (uint32_t)RTC_CR_WUTE; + status = SUCCESS; + } + else + { + /* Disable the Wakeup Timer */ + RTC->CR &= (uint32_t)~RTC_CR_WUTE; + /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ + do + { + wutwfstatus = RTC->ISR & RTC_ISR_WUTWF; + wutcounter++; + } while((wutcounter != INITMODE_TIMEOUT) && (wutwfstatus == 0x00)); + + if ((RTC->ISR & RTC_ISR_WUTWF) == RESET) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @} + */ + +/** @defgroup RTC_Group5 Daylight Saving configuration functions + * @brief Daylight Saving configuration functions + * +@verbatim + =============================================================================== + Daylight Saving configuration functions + =============================================================================== + + This section provide functions allowing to configure the RTC DayLight Saving. + +@endverbatim + * @{ + */ + +/** + * @brief Adds or substract one hour from the current time. + * @param RTC_DayLightSaveOperation: the value of hour adjustment. + * This parameter can be one of the following values: + * @arg RTC_DayLightSaving_SUB1H: Substract one hour (winter time) + * @arg RTC_DayLightSaving_ADD1H: Add one hour (summer time) + * @param RTC_StoreOperation: Specifies the value to be written in the BCK bit + * in CR register to store the operation. + * This parameter can be one of the following values: + * @arg RTC_StoreOperation_Reset: BCK Bit Reset + * @arg RTC_StoreOperation_Set: BCK Bit Set + * @retval None + */ +void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation) +{ + /* Check the parameters */ + assert_param(IS_RTC_DAYLIGHT_SAVING(RTC_DayLightSaving)); + assert_param(IS_RTC_STORE_OPERATION(RTC_StoreOperation)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Clear the bits to be configured */ + RTC->CR &= (uint32_t)~(RTC_CR_BCK); + + /* Configure the RTC_CR register */ + RTC->CR |= (uint32_t)(RTC_DayLightSaving | RTC_StoreOperation); + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Returns the RTC Day Light Saving stored operation. + * @param None + * @retval RTC Day Light Saving stored operation. + * - RTC_StoreOperation_Reset + * - RTC_StoreOperation_Set + */ +uint32_t RTC_GetStoreOperation(void) +{ + return (RTC->CR & RTC_CR_BCK); +} + +/** + * @} + */ + +/** @defgroup RTC_Group6 Output pin Configuration function + * @brief Output pin Configuration function + * +@verbatim + =============================================================================== + Output pin Configuration function + =============================================================================== + + This section provide functions allowing to configure the RTC Output source. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the RTC output source (AFO_ALARM). + * @param RTC_Output: Specifies which signal will be routed to the RTC output. + * This parameter can be one of the following values: + * @arg RTC_Output_Disable: No output selected + * @arg RTC_Output_AlarmA: signal of AlarmA mapped to output + * @arg RTC_Output_AlarmB: signal of AlarmB mapped to output + * @arg RTC_Output_WakeUp: signal of WakeUp mapped to output + * @param RTC_OutputPolarity: Specifies the polarity of the output signal. + * This parameter can be one of the following: + * @arg RTC_OutputPolarity_High: The output pin is high when the + * ALRAF/ALRBF/WUTF is high (depending on OSEL) + * @arg RTC_OutputPolarity_Low: The output pin is low when the + * ALRAF/ALRBF/WUTF is high (depending on OSEL) + * @retval None + */ +void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity) +{ + /* Check the parameters */ + assert_param(IS_RTC_OUTPUT(RTC_Output)); + assert_param(IS_RTC_OUTPUT_POL(RTC_OutputPolarity)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Clear the bits to be configured */ + RTC->CR &= (uint32_t)~(RTC_CR_OSEL | RTC_CR_POL); + + /* Configure the output selection and polarity */ + RTC->CR |= (uint32_t)(RTC_Output | RTC_OutputPolarity); + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @} + */ + +/** @defgroup RTC_Group7 Digital Calibration configuration functions + * @brief Coarse Calibration configuration functions + * +@verbatim + =============================================================================== + Digital Calibration configuration functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the Coarse calibration parameters. + * @param RTC_CalibSign: specifies the sign of the coarse calibration value. + * This parameter can be one of the following values: + * @arg RTC_CalibSign_Positive: The value sign is positive + * @arg RTC_CalibSign_Negative: The value sign is negative + * @param Value: value of coarse calibration expressed in ppm (coded on 5 bits). + * + * @note This Calibration value should be between 0 and 63 when using negative + * sign with a 2-ppm step. + * + * @note This Calibration value should be between 0 and 126 when using positive + * sign with a 4-ppm step. + * + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Coarse calibration are initialized + * - ERROR: RTC Coarse calibration are not initialized + */ +ErrorStatus RTC_CoarseCalibConfig(uint32_t RTC_CalibSign, uint32_t Value) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_CALIB_SIGN(RTC_CalibSign)); + assert_param(IS_RTC_CALIB_VALUE(Value)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + /* Set the coarse calibration value */ + RTC->CALIBR = (uint32_t)(RTC_CalibSign | Value); + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + status = SUCCESS; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Enables or disables the Coarse calibration process. + * @param NewState: new state of the Coarse calibration. + * This parameter can be: ENABLE or DISABLE. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Coarse calibration are enabled/disabled + * - ERROR: RTC Coarse calibration are not enabled/disabled + */ +ErrorStatus RTC_CoarseCalibCmd(FunctionalState NewState) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + if (NewState != DISABLE) + { + /* Enable the Coarse Calibration */ + RTC->CR |= (uint32_t)RTC_CR_DCE; + } + else + { + /* Disable the Coarse Calibration */ + RTC->CR &= (uint32_t)~RTC_CR_DCE; + } + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + status = SUCCESS; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Enables or disables the RTC clock to be output through the relative pin. + * @param NewState: new state of the digital calibration Output. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_CalibOutputCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + if (NewState != DISABLE) + { + /* Enable the RTC clock output */ + RTC->CR |= (uint32_t)RTC_CR_COE; + } + else + { + /* Disable the RTC clock output */ + RTC->CR &= (uint32_t)~RTC_CR_COE; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz). + * @param RTC_CalibOutput : Select the Calibration output Selection . + * This parameter can be one of the following values: + * @arg RTC_CalibOutput_512Hz: A signal has a regular waveform at 512Hz. + * @arg RTC_CalibOutput_1Hz : A signal has a regular waveform at 1Hz. + * @retval None +*/ +void RTC_CalibOutputConfig(uint32_t RTC_CalibOutput) +{ + /* Check the parameters */ + assert_param(IS_RTC_CALIB_OUTPUT(RTC_CalibOutput)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /*clear flags before config*/ + RTC->CR &= (uint32_t)~(RTC_CR_COSEL); + + /* Configure the RTC_CR register */ + RTC->CR |= (uint32_t)RTC_CalibOutput; + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Configures the Smooth Calibration Settings. + * @param RTC_SmoothCalibPeriod : Select the Smooth Calibration Period. + * This parameter can be can be one of the following values: + * @arg RTC_SmoothCalibPeriod_32sec : The smooth calibration periode is 32s. + * @arg RTC_SmoothCalibPeriod_16sec : The smooth calibration periode is 16s. + * @arg RTC_SmoothCalibPeriod_8sec : The smooth calibartion periode is 8s. + * @param RTC_SmoothCalibPlusPulses : Select to Set or reset the CALP bit. + * This parameter can be one of the following values: + * @arg RTC_SmoothCalibPlusPulses_Set : Add one RTCCLK puls every 2**11 pulses. + * @arg RTC_SmoothCalibPlusPulses_Reset: No RTCCLK pulses are added. + * @param RTC_SmouthCalibMinusPulsesValue: Select the value of CALM[8:0] bits. + * This parameter can be one any value from 0 to 0x000001FF. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Calib registers are configured + * - ERROR: RTC Calib registers are not configured +*/ +ErrorStatus RTC_SmoothCalibConfig(uint32_t RTC_SmoothCalibPeriod, + uint32_t RTC_SmoothCalibPlusPulses, + uint32_t RTC_SmouthCalibMinusPulsesValue) +{ + ErrorStatus status = ERROR; + uint32_t recalpfcount = 0; + + /* Check the parameters */ + assert_param(IS_RTC_SMOOTH_CALIB_PERIOD(RTC_SmoothCalibPeriod)); + assert_param(IS_RTC_SMOOTH_CALIB_PLUS(RTC_SmoothCalibPlusPulses)); + assert_param(IS_RTC_SMOOTH_CALIB_MINUS(RTC_SmouthCalibMinusPulsesValue)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* check if a calibration is pending*/ + if ((RTC->ISR & RTC_ISR_RECALPF) != RESET) + { + /* wait until the Calibration is completed*/ + while (((RTC->ISR & RTC_ISR_RECALPF) != RESET) && (recalpfcount != RECALPF_TIMEOUT)) + { + recalpfcount++; + } + } + + /* check if the calibration pending is completed or if there is no calibration operation at all*/ + if ((RTC->ISR & RTC_ISR_RECALPF) == RESET) + { + /* Configure the Smooth calibration settings */ + RTC->CALR = (uint32_t)((uint32_t)RTC_SmoothCalibPeriod | (uint32_t)RTC_SmoothCalibPlusPulses | (uint32_t)RTC_SmouthCalibMinusPulsesValue); + + status = SUCCESS; + } + else + { + status = ERROR; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return (ErrorStatus)(status); +} + +/** + * @} + */ + + +/** @defgroup RTC_Group8 TimeStamp configuration functions + * @brief TimeStamp configuration functions + * +@verbatim + =============================================================================== + TimeStamp configuration functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or Disables the RTC TimeStamp functionality with the + * specified time stamp pin stimulating edge. + * @param RTC_TimeStampEdge: Specifies the pin edge on which the TimeStamp is + * activated. + * This parameter can be one of the following: + * @arg RTC_TimeStampEdge_Rising: the Time stamp event occurs on the rising + * edge of the related pin. + * @arg RTC_TimeStampEdge_Falling: the Time stamp event occurs on the + * falling edge of the related pin. + * @param NewState: new state of the TimeStamp. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_TIMESTAMP_EDGE(RTC_TimeStampEdge)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Get the RTC_CR register and clear the bits to be configured */ + tmpreg = (uint32_t)(RTC->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE)); + + /* Get the new configuration */ + if (NewState != DISABLE) + { + tmpreg |= (uint32_t)(RTC_TimeStampEdge | RTC_CR_TSE); + } + else + { + tmpreg |= (uint32_t)(RTC_TimeStampEdge); + } + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Configure the Time Stamp TSEDGE and Enable bits */ + RTC->CR = (uint32_t)tmpreg; + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Get the RTC TimeStamp value and masks. + * @param RTC_Format: specifies the format of the output parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_StampTimeStruct: pointer to a RTC_TimeTypeDef structure that will + * contains the TimeStamp time values. + * @param RTC_StampDateStruct: pointer to a RTC_DateTypeDef structure that will + * contains the TimeStamp date values. + * @retval None + */ +void RTC_GetTimeStamp(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_StampTimeStruct, + RTC_DateTypeDef* RTC_StampDateStruct) +{ + uint32_t tmptime = 0, tmpdate = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + /* Get the TimeStamp time and date registers values */ + tmptime = (uint32_t)(RTC->TSTR & RTC_TR_RESERVED_MASK); + tmpdate = (uint32_t)(RTC->TSDR & RTC_DR_RESERVED_MASK); + + /* Fill the Time structure fields with the read parameters */ + RTC_StampTimeStruct->RTC_Hours = (uint8_t)((tmptime & (RTC_TR_HT | RTC_TR_HU)) >> 16); + RTC_StampTimeStruct->RTC_Minutes = (uint8_t)((tmptime & (RTC_TR_MNT | RTC_TR_MNU)) >> 8); + RTC_StampTimeStruct->RTC_Seconds = (uint8_t)(tmptime & (RTC_TR_ST | RTC_TR_SU)); + RTC_StampTimeStruct->RTC_H12 = (uint8_t)((tmptime & (RTC_TR_PM)) >> 16); + + /* Fill the Date structure fields with the read parameters */ + RTC_StampDateStruct->RTC_Year = 0; + RTC_StampDateStruct->RTC_Month = (uint8_t)((tmpdate & (RTC_DR_MT | RTC_DR_MU)) >> 8); + RTC_StampDateStruct->RTC_Date = (uint8_t)(tmpdate & (RTC_DR_DT | RTC_DR_DU)); + RTC_StampDateStruct->RTC_WeekDay = (uint8_t)((tmpdate & (RTC_DR_WDU)) >> 13); + + /* Check the input parameters format */ + if (RTC_Format == RTC_Format_BIN) + { + /* Convert the Time structure parameters to Binary format */ + RTC_StampTimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Hours); + RTC_StampTimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Minutes); + RTC_StampTimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Seconds); + + /* Convert the Date structure parameters to Binary format */ + RTC_StampDateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Month); + RTC_StampDateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Date); + RTC_StampDateStruct->RTC_WeekDay = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_WeekDay); + } +} + +/** + * @brief Get the RTC timestamp Subseconds value. + * @param None + * @retval RTC current timestamp Subseconds value. + */ +uint32_t RTC_GetTimeStampSubSecond(void) +{ + /* Get timestamp subseconds values from the correspondent registers */ + return (uint32_t)(RTC->TSSSR); +} + +/** + * @} + */ + +/** @defgroup RTC_Group9 Tampers configuration functions + * @brief Tampers configuration functions + * +@verbatim + =============================================================================== + Tampers configuration functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the select Tamper pin edge. + * @param RTC_Tamper: Selected tamper pin. + * This parameter can be RTC_Tamper_1. + * @param RTC_TamperTrigger: Specifies the trigger on the tamper pin that + * stimulates tamper event. + * This parameter can be one of the following values: + * @arg RTC_TamperTrigger_RisingEdge: Rising Edge of the tamper pin causes tamper event. + * @arg RTC_TamperTrigger_FallingEdge: Falling Edge of the tamper pin causes tamper event. + * @arg RTC_TamperTrigger_LowLevel: Low Level of the tamper pin causes tamper event. + * @arg RTC_TamperTrigger_HighLevel: High Level of the tamper pin causes tamper event. + * @retval None + */ +void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER(RTC_Tamper)); + assert_param(IS_RTC_TAMPER_TRIGGER(RTC_TamperTrigger)); + + if (RTC_TamperTrigger == RTC_TamperTrigger_RisingEdge) + { + /* Configure the RTC_TAFCR register */ + RTC->TAFCR &= (uint32_t)((uint32_t)~(RTC_Tamper << 1)); + } + else + { + /* Configure the RTC_TAFCR register */ + RTC->TAFCR |= (uint32_t)(RTC_Tamper << 1); + } +} + +/** + * @brief Enables or Disables the Tamper detection. + * @param RTC_Tamper: Selected tamper pin. + * This parameter can be RTC_Tamper_1. + * @param NewState: new state of the tamper pin. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER(RTC_Tamper)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected Tamper pin */ + RTC->TAFCR |= (uint32_t)RTC_Tamper; + } + else + { + /* Disable the selected Tamper pin */ + RTC->TAFCR &= (uint32_t)~RTC_Tamper; + } +} + +/** + * @brief Configures the Tampers Filter. + * @param RTC_TamperFilter: Specifies the tampers filter. + * This parameter can be one of the following values: + * @arg RTC_TamperFilter_Disable: Tamper filter is disabled. + * @arg RTC_TamperFilter_2Sample: Tamper is activated after 2 consecutive + * samples at the active level + * @arg RTC_TamperFilter_4Sample: Tamper is activated after 4 consecutive + * samples at the active level + * @arg RTC_TamperFilter_8Sample: Tamper is activated after 8 consecutive + * samples at the active level + * @retval None + */ +void RTC_TamperFilterConfig(uint32_t RTC_TamperFilter) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER_FILTER(RTC_TamperFilter)); + + /* Clear TAMPFLT[1:0] bits in the RTC_TAFCR register */ + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPFLT); + + /* Configure the RTC_TAFCR register */ + RTC->TAFCR |= (uint32_t)RTC_TamperFilter; +} + +/** + * @brief Configures the Tampers Sampling Frequency. + * @param RTC_TamperSamplingFreq: Specifies the tampers Sampling Frequency. + * This parameter can be one of the following values: + * @arg RTC_TamperSamplingFreq_RTCCLK_Div32768: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 32768 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div16384: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 16384 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div8192: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 8192 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div4096: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 4096 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div2048: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 2048 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div1024: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 1024 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div512: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 512 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div256: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 256 + * @retval None + */ +void RTC_TamperSamplingFreqConfig(uint32_t RTC_TamperSamplingFreq) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER_SAMPLING_FREQ(RTC_TamperSamplingFreq)); + + /* Clear TAMPFREQ[2:0] bits in the RTC_TAFCR register */ + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPFREQ); + + /* Configure the RTC_TAFCR register */ + RTC->TAFCR |= (uint32_t)RTC_TamperSamplingFreq; +} + +/** + * @brief Configures the Tampers Pins input Precharge Duration. + * @param RTC_TamperPrechargeDuration: Specifies the Tampers Pins input + * Precharge Duration. + * This parameter can be one of the following values: + * @arg RTC_TamperPrechargeDuration_1RTCCLK: Tamper pins are pre-charged before sampling during 1 RTCCLK cycle + * @arg RTC_TamperPrechargeDuration_2RTCCLK: Tamper pins are pre-charged before sampling during 2 RTCCLK cycle + * @arg RTC_TamperPrechargeDuration_4RTCCLK: Tamper pins are pre-charged before sampling during 4 RTCCLK cycle + * @arg RTC_TamperPrechargeDuration_8RTCCLK: Tamper pins are pre-charged before sampling during 8 RTCCLK cycle + * @retval None + */ +void RTC_TamperPinsPrechargeDuration(uint32_t RTC_TamperPrechargeDuration) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER_PRECHARGE_DURATION(RTC_TamperPrechargeDuration)); + + /* Clear TAMPPRCH[1:0] bits in the RTC_TAFCR register */ + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPPRCH); + + /* Configure the RTC_TAFCR register */ + RTC->TAFCR |= (uint32_t)RTC_TamperPrechargeDuration; +} + +/** + * @brief Enables or Disables the TimeStamp on Tamper Detection Event. + * @note The timestamp is valid even the TSE bit in tamper control register + * is reset. + * @param NewState: new state of the timestamp on tamper event. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TimeStampOnTamperDetectionCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Save timestamp on tamper detection event */ + RTC->TAFCR |= (uint32_t)RTC_TAFCR_TAMPTS; + } + else + { + /* Tamper detection does not cause a timestamp to be saved */ + RTC->TAFCR &= (uint32_t)~RTC_TAFCR_TAMPTS; + } +} + +/** + * @brief Enables or Disables the Precharge of Tamper pin. + * @param NewState: new state of tamper pull up. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TamperPullUpCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable precharge of the selected Tamper pin */ + RTC->TAFCR &= (uint32_t)~RTC_TAFCR_TAMPPUDIS; + } + else + { + /* Disable precharge of the selected Tamper pin */ + RTC->TAFCR |= (uint32_t)RTC_TAFCR_TAMPPUDIS; + } +} + +/** + * @} + */ + +/** @defgroup RTC_Group10 Backup Data Registers configuration functions + * @brief Backup Data Registers configuration functions + * +@verbatim + =============================================================================== + Backup Data Registers configuration functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Writes a data in a specified RTC Backup data register. + * @param RTC_BKP_DR: RTC Backup data Register number. + * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to + * specify the register. + * @param Data: Data to be written in the specified RTC Backup data register. + * @retval None + */ +void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_RTC_BKP(RTC_BKP_DR)); + + tmp = RTC_BASE + 0x50; + tmp += (RTC_BKP_DR * 4); + + /* Write the specified register */ + *(__IO uint32_t *)tmp = (uint32_t)Data; +} + +/** + * @brief Reads data from the specified RTC Backup data Register. + * @param RTC_BKP_DR: RTC Backup data Register number. + * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to + * specify the register. + * @retval None + */ +uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_RTC_BKP(RTC_BKP_DR)); + + tmp = RTC_BASE + 0x50; + tmp += (RTC_BKP_DR * 4); + + /* Read the specified register */ + return (*(__IO uint32_t *)tmp); +} + +/** + * @} + */ + +/** @defgroup RTC_Group11 RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration functions + * @brief RTC Tamper and TimeStamp Pins Selection and Output Type Config + * configuration functions + * +@verbatim + =============================================================================== + RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration + functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Selects the RTC Tamper Pin. + * @param RTC_TamperPin: specifies the RTC Tamper Pin. + * This parameter can be one of the following values: + * @arg RTC_TamperPin_PC13: PC13 is selected as RTC Tamper Pin. + * @arg RTC_TamperPin_PI8: PI8 is selected as RTC Tamper Pin. + * @retval None + */ +void RTC_TamperPinSelection(uint32_t RTC_TamperPin) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER_PIN(RTC_TamperPin)); + + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPINSEL); + RTC->TAFCR |= (uint32_t)(RTC_TamperPin); +} + +/** + * @brief Selects the RTC TimeStamp Pin. + * @param RTC_TimeStampPin: specifies the RTC TimeStamp Pin. + * This parameter can be one of the following values: + * @arg RTC_TimeStampPin_PC13: PC13 is selected as RTC TimeStamp Pin. + * @arg RTC_TimeStampPin_PI8: PI8 is selected as RTC TimeStamp Pin. + * @retval None + */ +void RTC_TimeStampPinSelection(uint32_t RTC_TimeStampPin) +{ + /* Check the parameters */ + assert_param(IS_RTC_TIMESTAMP_PIN(RTC_TimeStampPin)); + + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TSINSEL); + RTC->TAFCR |= (uint32_t)(RTC_TimeStampPin); +} + +/** + * @brief Configures the RTC Output Pin mode. + * @param RTC_OutputType: specifies the RTC Output (PC13) pin mode. + * This parameter can be one of the following values: + * @arg RTC_OutputType_OpenDrain: RTC Output (PC13) is configured in + * Open Drain mode. + * @arg RTC_OutputType_PushPull: RTC Output (PC13) is configured in + * Push Pull mode. + * @retval None + */ +void RTC_OutputTypeConfig(uint32_t RTC_OutputType) +{ + /* Check the parameters */ + assert_param(IS_RTC_OUTPUT_TYPE(RTC_OutputType)); + + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_ALARMOUTTYPE); + RTC->TAFCR |= (uint32_t)(RTC_OutputType); +} + +/** + * @} + */ + +/** @defgroup RTC_Group12 Shift control synchronisation functions + * @brief Shift control synchronisation functions + * +@verbatim + =============================================================================== + Shift control synchronisation functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the Synchronization Shift Control Settings. + * @note When REFCKON is set, firmware must not write to Shift control register + * @param RTC_ShiftAdd1S : Select to add or not 1 second to the time Calendar. + * This parameter can be one of the following values : + * @arg RTC_ShiftAdd1S_Set : Add one second to the clock calendar. + * @arg RTC_ShiftAdd1S_Reset: No effect. + * @param RTC_ShiftSubFS: Select the number of Second Fractions to Substitute. + * This parameter can be one any value from 0 to 0x7FFF. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Shift registers are configured + * - ERROR: RTC Shift registers are not configured +*/ +ErrorStatus RTC_SynchroShiftConfig(uint32_t RTC_ShiftAdd1S, uint32_t RTC_ShiftSubFS) +{ + ErrorStatus status = ERROR; + uint32_t shpfcount = 0; + + /* Check the parameters */ + assert_param(IS_RTC_SHIFT_ADD1S(RTC_ShiftAdd1S)); + assert_param(IS_RTC_SHIFT_SUBFS(RTC_ShiftSubFS)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Check if a Shift is pending*/ + if ((RTC->ISR & RTC_ISR_SHPF) != RESET) + { + /* Wait until the shift is completed*/ + while (((RTC->ISR & RTC_ISR_SHPF) != RESET) && (shpfcount != SHPF_TIMEOUT)) + { + shpfcount++; + } + } + + /* Check if the Shift pending is completed or if there is no Shift operation at all*/ + if ((RTC->ISR & RTC_ISR_SHPF) == RESET) + { + /* check if the reference clock detection is disabled */ + if((RTC->CR & RTC_CR_REFCKON) == RESET) + { + /* Configure the Shift settings */ + RTC->SHIFTR = (uint32_t)(uint32_t)(RTC_ShiftSubFS) | (uint32_t)(RTC_ShiftAdd1S); + + if(RTC_WaitForSynchro() == ERROR) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + else + { + status = ERROR; + } + } + else + { + status = ERROR; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return (ErrorStatus)(status); +} + +/** + * @} + */ + +/** @defgroup RTC_Group13 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + All RTC interrupts are connected to the EXTI controller. + + - To enable the RTC Alarm interrupt, the following sequence is required: + - Configure and enable the EXTI Line 17 in interrupt mode and select the rising + edge sensitivity using the EXTI_Init() function. + - Configure and enable the RTC_Alarm IRQ channel in the NVIC using the NVIC_Init() + function. + - Configure the RTC to generate RTC alarms (Alarm A and/or Alarm B) using + the RTC_SetAlarm() and RTC_AlarmCmd() functions. + + - To enable the RTC Wakeup interrupt, the following sequence is required: + - Configure and enable the EXTI Line 22 in interrupt mode and select the rising + edge sensitivity using the EXTI_Init() function. + - Configure and enable the RTC_WKUP IRQ channel in the NVIC using the NVIC_Init() + function. + - Configure the RTC to generate the RTC wakeup timer event using the + RTC_WakeUpClockConfig(), RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions. + + - To enable the RTC Tamper interrupt, the following sequence is required: + - Configure and enable the EXTI Line 21 in interrupt mode and select the rising + edge sensitivity using the EXTI_Init() function. + - Configure and enable the TAMP_STAMP IRQ channel in the NVIC using the NVIC_Init() + function. + - Configure the RTC to detect the RTC tamper event using the + RTC_TamperTriggerConfig() and RTC_TamperCmd() functions. + + - To enable the RTC TimeStamp interrupt, the following sequence is required: + - Configure and enable the EXTI Line 21 in interrupt mode and select the rising + edge sensitivity using the EXTI_Init() function. + - Configure and enable the TAMP_STAMP IRQ channel in the NVIC using the NVIC_Init() + function. + - Configure the RTC to detect the RTC time-stamp event using the + RTC_TimeStampCmd() functions. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified RTC interrupts. + * @param RTC_IT: specifies the RTC interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RTC_IT_TS: Time Stamp interrupt mask + * @arg RTC_IT_WUT: WakeUp Timer interrupt mask + * @arg RTC_IT_ALRB: Alarm B interrupt mask + * @arg RTC_IT_ALRA: Alarm A interrupt mask + * @arg RTC_IT_TAMP: Tamper event interrupt mask + * @param NewState: new state of the specified RTC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RTC_CONFIG_IT(RTC_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + if (NewState != DISABLE) + { + /* Configure the Interrupts in the RTC_CR register */ + RTC->CR |= (uint32_t)(RTC_IT & ~RTC_TAFCR_TAMPIE); + /* Configure the Tamper Interrupt in the RTC_TAFCR */ + RTC->TAFCR |= (uint32_t)(RTC_IT & RTC_TAFCR_TAMPIE); + } + else + { + /* Configure the Interrupts in the RTC_CR register */ + RTC->CR &= (uint32_t)~(RTC_IT & (uint32_t)~RTC_TAFCR_TAMPIE); + /* Configure the Tamper Interrupt in the RTC_TAFCR */ + RTC->TAFCR &= (uint32_t)~(RTC_IT & RTC_TAFCR_TAMPIE); + } + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Checks whether the specified RTC flag is set or not. + * @param RTC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag + * @arg RTC_FLAG_TSOVF: Time Stamp OverFlow flag + * @arg RTC_FLAG_TSF: Time Stamp event flag + * @arg RTC_FLAG_WUTF: WakeUp Timer flag + * @arg RTC_FLAG_ALRBF: Alarm B flag + * @arg RTC_FLAG_ALRAF: Alarm A flag + * @arg RTC_FLAG_INITF: Initialization mode flag + * @arg RTC_FLAG_RSF: Registers Synchronized flag + * @arg RTC_FLAG_INITS: Registers Configured flag + * @arg RTC_FLAG_WUTWF: WakeUp Timer Write flag + * @arg RTC_FLAG_ALRBWF: Alarm B Write flag + * @arg RTC_FLAG_ALRAWF: Alarm A write flag + * @retval The new state of RTC_FLAG (SET or RESET). + */ +FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_GET_FLAG(RTC_FLAG)); + + /* Get all the flags */ + tmpreg = (uint32_t)(RTC->ISR & RTC_FLAGS_MASK); + + /* Return the status of the flag */ + if ((tmpreg & RTC_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the RTC's pending flags. + * @param RTC_FLAG: specifies the RTC flag to clear. + * This parameter can be any combination of the following values: + * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag + * @arg RTC_FLAG_TSOVF: Time Stamp Overflow flag + * @arg RTC_FLAG_TSF: Time Stamp event flag + * @arg RTC_FLAG_WUTF: WakeUp Timer flag + * @arg RTC_FLAG_ALRBF: Alarm B flag + * @arg RTC_FLAG_ALRAF: Alarm A flag + * @arg RTC_FLAG_RSF: Registers Synchronized flag + * @retval None + */ +void RTC_ClearFlag(uint32_t RTC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_RTC_CLEAR_FLAG(RTC_FLAG)); + + /* Clear the Flags in the RTC_ISR register */ + RTC->ISR = (uint32_t)((uint32_t)(~((RTC_FLAG | RTC_ISR_INIT)& 0x0000FFFF) | (uint32_t)(RTC->ISR & RTC_ISR_INIT))); +} + +/** + * @brief Checks whether the specified RTC interrupt has occurred or not. + * @param RTC_IT: specifies the RTC interrupt source to check. + * This parameter can be one of the following values: + * @arg RTC_IT_TS: Time Stamp interrupt + * @arg RTC_IT_WUT: WakeUp Timer interrupt + * @arg RTC_IT_ALRB: Alarm B interrupt + * @arg RTC_IT_ALRA: Alarm A interrupt + * @arg RTC_IT_TAMP1: Tamper 1 event interrupt + * @retval The new state of RTC_IT (SET or RESET). + */ +ITStatus RTC_GetITStatus(uint32_t RTC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t tmpreg = 0, enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_RTC_GET_IT(RTC_IT)); + + /* Get the TAMPER Interrupt enable bit and pending bit */ + tmpreg = (uint32_t)(RTC->TAFCR & (RTC_TAFCR_TAMPIE)); + + /* Get the Interrupt enable Status */ + enablestatus = (uint32_t)((RTC->CR & RTC_IT) | (tmpreg & (RTC_IT >> 15))); + + /* Get the Interrupt pending bit */ + tmpreg = (uint32_t)((RTC->ISR & (uint32_t)(RTC_IT >> 4))); + + /* Get the status of the Interrupt */ + if ((enablestatus != (uint32_t)RESET) && ((tmpreg & 0x0000FFFF) != (uint32_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the RTC's interrupt pending bits. + * @param RTC_IT: specifies the RTC interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg RTC_IT_TS: Time Stamp interrupt + * @arg RTC_IT_WUT: WakeUp Timer interrupt + * @arg RTC_IT_ALRB: Alarm B interrupt + * @arg RTC_IT_ALRA: Alarm A interrupt + * @arg RTC_IT_TAMP1: Tamper 1 event interrupt + * @retval None + */ +void RTC_ClearITPendingBit(uint32_t RTC_IT) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_CLEAR_IT(RTC_IT)); + + /* Get the RTC_ISR Interrupt pending bits mask */ + tmpreg = (uint32_t)(RTC_IT >> 4); + + /* Clear the interrupt pending bits in the RTC_ISR register */ + RTC->ISR = (uint32_t)((uint32_t)(~((tmpreg | RTC_ISR_INIT)& 0x0000FFFF) | (uint32_t)(RTC->ISR & RTC_ISR_INIT))); +} + +/** + * @} + */ + +/** + * @brief Converts a 2 digit decimal to BCD format. + * @param Value: Byte to be converted. + * @retval Converted byte + */ +static uint8_t RTC_ByteToBcd2(uint8_t Value) +{ + uint8_t bcdhigh = 0; + + while (Value >= 10) + { + bcdhigh++; + Value -= 10; + } + + return ((uint8_t)(bcdhigh << 4) | Value); +} + +/** + * @brief Convert from 2 digit BCD to Binary. + * @param Value: BCD value to be converted. + * @retval Converted word + */ +static uint8_t RTC_Bcd2ToByte(uint8_t Value) +{ + uint8_t tmp = 0; + tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10; + return (tmp + (Value & (uint8_t)0x0F)); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_sdio.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_sdio.c new file mode 100644 index 0000000..24a6c5e --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_sdio.c @@ -0,0 +1,1004 @@ +/** + ****************************************************************************** + * @file stm32f4xx_sdio.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Secure digital input/output interface (SDIO) + * peripheral: + * - Initialization and Configuration + * - Command path state machine (CPSM) management + * - Data path state machine (DPSM) management + * - SDIO IO Cards mode management + * - CE-ATA mode management + * - DMA transfers management + * - Interrupts and flags management + * + * @verbatim + * + * + * =================================================================== + * How to use this driver + * =================================================================== + * 1. The SDIO clock (SDIOCLK = 48 MHz) is coming from a specific output + * of PLL (PLL48CLK). Before to start working with SDIO peripheral + * make sure that the PLL is well configured. + * The SDIO peripheral uses two clock signals: + * - SDIO adapter clock (SDIOCLK = 48 MHz) + * - APB2 bus clock (PCLK2) + * PCLK2 and SDIO_CK clock frequencies must respect the following condition: + * Frequenc(PCLK2) >= (3 / 8 x Frequency(SDIO_CK)) + * + * 2. Enable peripheral clock using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE). + * + * 3. According to the SDIO mode, enable the GPIO clocks using + * RCC_AHB1PeriphClockCmd() function. + * The I/O can be one of the following configurations: + * - 1-bit data length: SDIO_CMD, SDIO_CK and D0. + * - 4-bit data length: SDIO_CMD, SDIO_CK and D[3:0]. + * - 8-bit data length: SDIO_CMD, SDIO_CK and D[7:0]. + * + * 4. Peripheral's alternate function: + * - Connect the pin to the desired peripherals' Alternate + * Function (AF) using GPIO_PinAFConfig() function + * - Configure the desired pin in alternate function by: + * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF + * - Select the type, pull-up/pull-down and output speed via + * GPIO_PuPd, GPIO_OType and GPIO_Speed members + * - Call GPIO_Init() function + * + * 5. Program the Clock Edge, Clock Bypass, Clock Power Save, Bus Wide, + * hardware, flow control and the Clock Divider using the SDIO_Init() + * function. + * + * 6. Enable the Power ON State using the SDIO_SetPowerState(SDIO_PowerState_ON) + * function. + * + * 7. Enable the clock using the SDIO_ClockCmd() function. + * + * 8. Enable the NVIC and the corresponding interrupt using the function + * SDIO_ITConfig() if you need to use interrupt mode. + * + * 9. When using the DMA mode + * - Configure the DMA using DMA_Init() function + * - Active the needed channel Request using SDIO_DMACmd() function + * + * 10. Enable the DMA using the DMA_Cmd() function, when using DMA mode. + * + * 11. To control the CPSM (Command Path State Machine) and send + * commands to the card use the SDIO_SendCommand(), + * SDIO_GetCommandResponse() and SDIO_GetResponse() functions. + * First, user has to fill the command structure (pointer to + * SDIO_CmdInitTypeDef) according to the selected command to be sent. + * The parameters that should be filled are: + * - Command Argument + * - Command Index + * - Command Response type + * - Command Wait + * - CPSM Status (Enable or Disable) + * + * To check if the command is well received, read the SDIO_CMDRESP + * register using the SDIO_GetCommandResponse(). + * The SDIO responses registers (SDIO_RESP1 to SDIO_RESP2), use the + * SDIO_GetResponse() function. + * + * 12. To control the DPSM (Data Path State Machine) and send/receive + * data to/from the card use the SDIO_DataConfig(), SDIO_GetDataCounter(), + * SDIO_ReadData(), SDIO_WriteData() and SDIO_GetFIFOCount() functions. + * + * Read Operations + * --------------- + * a) First, user has to fill the data structure (pointer to + * SDIO_DataInitTypeDef) according to the selected data type to + * be received. + * The parameters that should be filled are: + * - Data TimeOut + * - Data Length + * - Data Block size + * - Data Transfer direction: should be from card (To SDIO) + * - Data Transfer mode + * - DPSM Status (Enable or Disable) + * + * b) Configure the SDIO resources to receive the data from the card + * according to selected transfer mode (Refer to Step 8, 9 and 10). + * + * c) Send the selected Read command (refer to step 11). + * + * d) Use the SDIO flags/interrupts to check the transfer status. + * + * Write Operations + * --------------- + * a) First, user has to fill the data structure (pointer to + * SDIO_DataInitTypeDef) according to the selected data type to + * be received. + * The parameters that should be filled are: + * - Data TimeOut + * - Data Length + * - Data Block size + * - Data Transfer direction: should be to card (To CARD) + * - Data Transfer mode + * - DPSM Status (Enable or Disable) + * + * b) Configure the SDIO resources to send the data to the card + * according to selected transfer mode (Refer to Step 8, 9 and 10). + * + * c) Send the selected Write command (refer to step 11). + * + * d) Use the SDIO flags/interrupts to check the transfer status. + * + * + * @endverbatim + * + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_sdio.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup SDIO + * @brief SDIO driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* ------------ SDIO registers bit address in the alias region ----------- */ +#define SDIO_OFFSET (SDIO_BASE - PERIPH_BASE) + +/* --- CLKCR Register ---*/ +/* Alias word address of CLKEN bit */ +#define CLKCR_OFFSET (SDIO_OFFSET + 0x04) +#define CLKEN_BitNumber 0x08 +#define CLKCR_CLKEN_BB (PERIPH_BB_BASE + (CLKCR_OFFSET * 32) + (CLKEN_BitNumber * 4)) + +/* --- CMD Register ---*/ +/* Alias word address of SDIOSUSPEND bit */ +#define CMD_OFFSET (SDIO_OFFSET + 0x0C) +#define SDIOSUSPEND_BitNumber 0x0B +#define CMD_SDIOSUSPEND_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (SDIOSUSPEND_BitNumber * 4)) + +/* Alias word address of ENCMDCOMPL bit */ +#define ENCMDCOMPL_BitNumber 0x0C +#define CMD_ENCMDCOMPL_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ENCMDCOMPL_BitNumber * 4)) + +/* Alias word address of NIEN bit */ +#define NIEN_BitNumber 0x0D +#define CMD_NIEN_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (NIEN_BitNumber * 4)) + +/* Alias word address of ATACMD bit */ +#define ATACMD_BitNumber 0x0E +#define CMD_ATACMD_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ATACMD_BitNumber * 4)) + +/* --- DCTRL Register ---*/ +/* Alias word address of DMAEN bit */ +#define DCTRL_OFFSET (SDIO_OFFSET + 0x2C) +#define DMAEN_BitNumber 0x03 +#define DCTRL_DMAEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (DMAEN_BitNumber * 4)) + +/* Alias word address of RWSTART bit */ +#define RWSTART_BitNumber 0x08 +#define DCTRL_RWSTART_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTART_BitNumber * 4)) + +/* Alias word address of RWSTOP bit */ +#define RWSTOP_BitNumber 0x09 +#define DCTRL_RWSTOP_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTOP_BitNumber * 4)) + +/* Alias word address of RWMOD bit */ +#define RWMOD_BitNumber 0x0A +#define DCTRL_RWMOD_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWMOD_BitNumber * 4)) + +/* Alias word address of SDIOEN bit */ +#define SDIOEN_BitNumber 0x0B +#define DCTRL_SDIOEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (SDIOEN_BitNumber * 4)) + +/* ---------------------- SDIO registers bit mask ------------------------ */ +/* --- CLKCR Register ---*/ +/* CLKCR register clear mask */ +#define CLKCR_CLEAR_MASK ((uint32_t)0xFFFF8100) + +/* --- PWRCTRL Register ---*/ +/* SDIO PWRCTRL Mask */ +#define PWR_PWRCTRL_MASK ((uint32_t)0xFFFFFFFC) + +/* --- DCTRL Register ---*/ +/* SDIO DCTRL Clear Mask */ +#define DCTRL_CLEAR_MASK ((uint32_t)0xFFFFFF08) + +/* --- CMD Register ---*/ +/* CMD Register clear mask */ +#define CMD_CLEAR_MASK ((uint32_t)0xFFFFF800) + +/* SDIO RESP Registers Address */ +#define SDIO_RESP_ADDR ((uint32_t)(SDIO_BASE + 0x14)) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup SDIO_Private_Functions + * @{ + */ + +/** @defgroup SDIO_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the SDIO peripheral registers to their default reset values. + * @param None + * @retval None + */ +void SDIO_DeInit(void) +{ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, DISABLE); +} + +/** + * @brief Initializes the SDIO peripheral according to the specified + * parameters in the SDIO_InitStruct. + * @param SDIO_InitStruct : pointer to a SDIO_InitTypeDef structure + * that contains the configuration information for the SDIO peripheral. + * @retval None + */ +void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_CLOCK_EDGE(SDIO_InitStruct->SDIO_ClockEdge)); + assert_param(IS_SDIO_CLOCK_BYPASS(SDIO_InitStruct->SDIO_ClockBypass)); + assert_param(IS_SDIO_CLOCK_POWER_SAVE(SDIO_InitStruct->SDIO_ClockPowerSave)); + assert_param(IS_SDIO_BUS_WIDE(SDIO_InitStruct->SDIO_BusWide)); + assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(SDIO_InitStruct->SDIO_HardwareFlowControl)); + +/*---------------------------- SDIO CLKCR Configuration ------------------------*/ + /* Get the SDIO CLKCR value */ + tmpreg = SDIO->CLKCR; + + /* Clear CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, HWFC_EN bits */ + tmpreg &= CLKCR_CLEAR_MASK; + + /* Set CLKDIV bits according to SDIO_ClockDiv value */ + /* Set PWRSAV bit according to SDIO_ClockPowerSave value */ + /* Set BYPASS bit according to SDIO_ClockBypass value */ + /* Set WIDBUS bits according to SDIO_BusWide value */ + /* Set NEGEDGE bits according to SDIO_ClockEdge value */ + /* Set HWFC_EN bits according to SDIO_HardwareFlowControl value */ + tmpreg |= (SDIO_InitStruct->SDIO_ClockDiv | SDIO_InitStruct->SDIO_ClockPowerSave | + SDIO_InitStruct->SDIO_ClockBypass | SDIO_InitStruct->SDIO_BusWide | + SDIO_InitStruct->SDIO_ClockEdge | SDIO_InitStruct->SDIO_HardwareFlowControl); + + /* Write to SDIO CLKCR */ + SDIO->CLKCR = tmpreg; +} + +/** + * @brief Fills each SDIO_InitStruct member with its default value. + * @param SDIO_InitStruct: pointer to an SDIO_InitTypeDef structure which + * will be initialized. + * @retval None + */ +void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct) +{ + /* SDIO_InitStruct members default value */ + SDIO_InitStruct->SDIO_ClockDiv = 0x00; + SDIO_InitStruct->SDIO_ClockEdge = SDIO_ClockEdge_Rising; + SDIO_InitStruct->SDIO_ClockBypass = SDIO_ClockBypass_Disable; + SDIO_InitStruct->SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; + SDIO_InitStruct->SDIO_BusWide = SDIO_BusWide_1b; + SDIO_InitStruct->SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; +} + +/** + * @brief Enables or disables the SDIO Clock. + * @param NewState: new state of the SDIO Clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_ClockCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CLKCR_CLKEN_BB = (uint32_t)NewState; +} + +/** + * @brief Sets the power status of the controller. + * @param SDIO_PowerState: new state of the Power state. + * This parameter can be one of the following values: + * @arg SDIO_PowerState_OFF: SDIO Power OFF + * @arg SDIO_PowerState_ON: SDIO Power ON + * @retval None + */ +void SDIO_SetPowerState(uint32_t SDIO_PowerState) +{ + /* Check the parameters */ + assert_param(IS_SDIO_POWER_STATE(SDIO_PowerState)); + + SDIO->POWER = SDIO_PowerState; +} + +/** + * @brief Gets the power status of the controller. + * @param None + * @retval Power status of the controller. The returned value can be one of the + * following values: + * - 0x00: Power OFF + * - 0x02: Power UP + * - 0x03: Power ON + */ +uint32_t SDIO_GetPowerState(void) +{ + return (SDIO->POWER & (~PWR_PWRCTRL_MASK)); +} + +/** + * @} + */ + +/** @defgroup SDIO_Group2 Command path state machine (CPSM) management functions + * @brief Command path state machine (CPSM) management functions + * +@verbatim + =============================================================================== + Command path state machine (CPSM) management functions + =============================================================================== + + This section provide functions allowing to program and read the Command path + state machine (CPSM). + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the SDIO Command according to the specified + * parameters in the SDIO_CmdInitStruct and send the command. + * @param SDIO_CmdInitStruct : pointer to a SDIO_CmdInitTypeDef + * structure that contains the configuration information for the SDIO + * command. + * @retval None + */ +void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_CMD_INDEX(SDIO_CmdInitStruct->SDIO_CmdIndex)); + assert_param(IS_SDIO_RESPONSE(SDIO_CmdInitStruct->SDIO_Response)); + assert_param(IS_SDIO_WAIT(SDIO_CmdInitStruct->SDIO_Wait)); + assert_param(IS_SDIO_CPSM(SDIO_CmdInitStruct->SDIO_CPSM)); + +/*---------------------------- SDIO ARG Configuration ------------------------*/ + /* Set the SDIO Argument value */ + SDIO->ARG = SDIO_CmdInitStruct->SDIO_Argument; + +/*---------------------------- SDIO CMD Configuration ------------------------*/ + /* Get the SDIO CMD value */ + tmpreg = SDIO->CMD; + /* Clear CMDINDEX, WAITRESP, WAITINT, WAITPEND, CPSMEN bits */ + tmpreg &= CMD_CLEAR_MASK; + /* Set CMDINDEX bits according to SDIO_CmdIndex value */ + /* Set WAITRESP bits according to SDIO_Response value */ + /* Set WAITINT and WAITPEND bits according to SDIO_Wait value */ + /* Set CPSMEN bits according to SDIO_CPSM value */ + tmpreg |= (uint32_t)SDIO_CmdInitStruct->SDIO_CmdIndex | SDIO_CmdInitStruct->SDIO_Response + | SDIO_CmdInitStruct->SDIO_Wait | SDIO_CmdInitStruct->SDIO_CPSM; + + /* Write to SDIO CMD */ + SDIO->CMD = tmpreg; +} + +/** + * @brief Fills each SDIO_CmdInitStruct member with its default value. + * @param SDIO_CmdInitStruct: pointer to an SDIO_CmdInitTypeDef + * structure which will be initialized. + * @retval None + */ +void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct) +{ + /* SDIO_CmdInitStruct members default value */ + SDIO_CmdInitStruct->SDIO_Argument = 0x00; + SDIO_CmdInitStruct->SDIO_CmdIndex = 0x00; + SDIO_CmdInitStruct->SDIO_Response = SDIO_Response_No; + SDIO_CmdInitStruct->SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStruct->SDIO_CPSM = SDIO_CPSM_Disable; +} + +/** + * @brief Returns command index of last command for which response received. + * @param None + * @retval Returns the command index of the last command response received. + */ +uint8_t SDIO_GetCommandResponse(void) +{ + return (uint8_t)(SDIO->RESPCMD); +} + +/** + * @brief Returns response received from the card for the last command. + * @param SDIO_RESP: Specifies the SDIO response register. + * This parameter can be one of the following values: + * @arg SDIO_RESP1: Response Register 1 + * @arg SDIO_RESP2: Response Register 2 + * @arg SDIO_RESP3: Response Register 3 + * @arg SDIO_RESP4: Response Register 4 + * @retval The Corresponding response register value. + */ +uint32_t SDIO_GetResponse(uint32_t SDIO_RESP) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_RESP(SDIO_RESP)); + + tmp = SDIO_RESP_ADDR + SDIO_RESP; + + return (*(__IO uint32_t *) tmp); +} + +/** + * @} + */ + +/** @defgroup SDIO_Group3 Data path state machine (DPSM) management functions + * @brief Data path state machine (DPSM) management functions + * +@verbatim + =============================================================================== + Data path state machine (DPSM) management functions + =============================================================================== + + This section provide functions allowing to program and read the Data path + state machine (DPSM). + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the SDIO data path according to the specified + * parameters in the SDIO_DataInitStruct. + * @param SDIO_DataInitStruct : pointer to a SDIO_DataInitTypeDef structure + * that contains the configuration information for the SDIO command. + * @retval None + */ +void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_DATA_LENGTH(SDIO_DataInitStruct->SDIO_DataLength)); + assert_param(IS_SDIO_BLOCK_SIZE(SDIO_DataInitStruct->SDIO_DataBlockSize)); + assert_param(IS_SDIO_TRANSFER_DIR(SDIO_DataInitStruct->SDIO_TransferDir)); + assert_param(IS_SDIO_TRANSFER_MODE(SDIO_DataInitStruct->SDIO_TransferMode)); + assert_param(IS_SDIO_DPSM(SDIO_DataInitStruct->SDIO_DPSM)); + +/*---------------------------- SDIO DTIMER Configuration ---------------------*/ + /* Set the SDIO Data TimeOut value */ + SDIO->DTIMER = SDIO_DataInitStruct->SDIO_DataTimeOut; + +/*---------------------------- SDIO DLEN Configuration -----------------------*/ + /* Set the SDIO DataLength value */ + SDIO->DLEN = SDIO_DataInitStruct->SDIO_DataLength; + +/*---------------------------- SDIO DCTRL Configuration ----------------------*/ + /* Get the SDIO DCTRL value */ + tmpreg = SDIO->DCTRL; + /* Clear DEN, DTMODE, DTDIR and DBCKSIZE bits */ + tmpreg &= DCTRL_CLEAR_MASK; + /* Set DEN bit according to SDIO_DPSM value */ + /* Set DTMODE bit according to SDIO_TransferMode value */ + /* Set DTDIR bit according to SDIO_TransferDir value */ + /* Set DBCKSIZE bits according to SDIO_DataBlockSize value */ + tmpreg |= (uint32_t)SDIO_DataInitStruct->SDIO_DataBlockSize | SDIO_DataInitStruct->SDIO_TransferDir + | SDIO_DataInitStruct->SDIO_TransferMode | SDIO_DataInitStruct->SDIO_DPSM; + + /* Write to SDIO DCTRL */ + SDIO->DCTRL = tmpreg; +} + +/** + * @brief Fills each SDIO_DataInitStruct member with its default value. + * @param SDIO_DataInitStruct: pointer to an SDIO_DataInitTypeDef structure + * which will be initialized. + * @retval None + */ +void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct) +{ + /* SDIO_DataInitStruct members default value */ + SDIO_DataInitStruct->SDIO_DataTimeOut = 0xFFFFFFFF; + SDIO_DataInitStruct->SDIO_DataLength = 0x00; + SDIO_DataInitStruct->SDIO_DataBlockSize = SDIO_DataBlockSize_1b; + SDIO_DataInitStruct->SDIO_TransferDir = SDIO_TransferDir_ToCard; + SDIO_DataInitStruct->SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStruct->SDIO_DPSM = SDIO_DPSM_Disable; +} + +/** + * @brief Returns number of remaining data bytes to be transferred. + * @param None + * @retval Number of remaining data bytes to be transferred + */ +uint32_t SDIO_GetDataCounter(void) +{ + return SDIO->DCOUNT; +} + +/** + * @brief Read one data word from Rx FIFO. + * @param None + * @retval Data received + */ +uint32_t SDIO_ReadData(void) +{ + return SDIO->FIFO; +} + +/** + * @brief Write one data word to Tx FIFO. + * @param Data: 32-bit data word to write. + * @retval None + */ +void SDIO_WriteData(uint32_t Data) +{ + SDIO->FIFO = Data; +} + +/** + * @brief Returns the number of words left to be written to or read from FIFO. + * @param None + * @retval Remaining number of words. + */ +uint32_t SDIO_GetFIFOCount(void) +{ + return SDIO->FIFOCNT; +} + +/** + * @} + */ + +/** @defgroup SDIO_Group4 SDIO IO Cards mode management functions + * @brief SDIO IO Cards mode management functions + * +@verbatim + =============================================================================== + SDIO IO Cards mode management functions + =============================================================================== + + This section provide functions allowing to program and read the SDIO IO Cards. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the SD I/O Read Wait operation. + * @param NewState: new state of the Start SDIO Read Wait operation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_StartSDIOReadWait(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_RWSTART_BB = (uint32_t) NewState; +} + +/** + * @brief Stops the SD I/O Read Wait operation. + * @param NewState: new state of the Stop SDIO Read Wait operation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_StopSDIOReadWait(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_RWSTOP_BB = (uint32_t) NewState; +} + +/** + * @brief Sets one of the two options of inserting read wait interval. + * @param SDIO_ReadWaitMode: SD I/O Read Wait operation mode. + * This parameter can be: + * @arg SDIO_ReadWaitMode_CLK: Read Wait control by stopping SDIOCLK + * @arg SDIO_ReadWaitMode_DATA2: Read Wait control using SDIO_DATA2 + * @retval None + */ +void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode) +{ + /* Check the parameters */ + assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode)); + + *(__IO uint32_t *) DCTRL_RWMOD_BB = SDIO_ReadWaitMode; +} + +/** + * @brief Enables or disables the SD I/O Mode Operation. + * @param NewState: new state of SDIO specific operation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_SetSDIOOperation(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_SDIOEN_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the SD I/O Mode suspend command sending. + * @param NewState: new state of the SD I/O Mode suspend command. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_SendSDIOSuspendCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_SDIOSUSPEND_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup SDIO_Group5 CE-ATA mode management functions + * @brief CE-ATA mode management functions + * +@verbatim + =============================================================================== + CE-ATA mode management functions + =============================================================================== + + This section provide functions allowing to program and read the CE-ATA card. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the command completion signal. + * @param NewState: new state of command completion signal. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_CommandCompletionCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_ENCMDCOMPL_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the CE-ATA interrupt. + * @param NewState: new state of CE-ATA interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_CEATAITCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)((~((uint32_t)NewState)) & ((uint32_t)0x1)); +} + +/** + * @brief Sends CE-ATA command (CMD61). + * @param NewState: new state of CE-ATA command. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_SendCEATACmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_ATACMD_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup SDIO_Group6 DMA transfers management functions + * @brief DMA transfers management functions + * +@verbatim + =============================================================================== + DMA transfers management functions + =============================================================================== + + This section provide functions allowing to program SDIO DMA transfer. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the SDIO DMA request. + * @param NewState: new state of the selected SDIO DMA request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_DMACmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_DMAEN_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup SDIO_Group7 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the SDIO interrupts. + * @param SDIO_IT: specifies the SDIO interrupt sources to be enabled or disabled. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt + * @arg SDIO_IT_RXACT: Data receive in progress interrupt + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt + * @param NewState: new state of the specified SDIO interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SDIO_IT(SDIO_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the SDIO interrupts */ + SDIO->MASK |= SDIO_IT; + } + else + { + /* Disable the SDIO interrupts */ + SDIO->MASK &= ~SDIO_IT; + } +} + +/** + * @brief Checks whether the specified SDIO flag is set or not. + * @param SDIO_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDIO_FLAG_CTIMEOUT: Command response timeout + * @arg SDIO_FLAG_DTIMEOUT: Data timeout + * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) + * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) + * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode. + * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDIO_FLAG_CMDACT: Command transfer in progress + * @arg SDIO_FLAG_TXACT: Data transmit in progress + * @arg SDIO_FLAG_RXACT: Data receive in progress + * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty + * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full + * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full + * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full + * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty + * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty + * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO + * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO + * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received + * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval The new state of SDIO_FLAG (SET or RESET). + */ +FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_SDIO_FLAG(SDIO_FLAG)); + + if ((SDIO->STA & SDIO_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the SDIO's pending flags. + * @param SDIO_FLAG: specifies the flag to clear. + * This parameter can be one or a combination of the following values: + * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDIO_FLAG_CTIMEOUT: Command response timeout + * @arg SDIO_FLAG_DTIMEOUT: Data timeout + * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) + * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) + * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode + * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received + * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval None + */ +void SDIO_ClearFlag(uint32_t SDIO_FLAG) +{ + /* Check the parameters */ + assert_param(IS_SDIO_CLEAR_FLAG(SDIO_FLAG)); + + SDIO->ICR = SDIO_FLAG; +} + +/** + * @brief Checks whether the specified SDIO interrupt has occurred or not. + * @param SDIO_IT: specifies the SDIO interrupt source to check. + * This parameter can be one of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt + * @arg SDIO_IT_RXACT: Data receive in progress interrupt + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt + * @retval The new state of SDIO_IT (SET or RESET). + */ +ITStatus SDIO_GetITStatus(uint32_t SDIO_IT) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_SDIO_GET_IT(SDIO_IT)); + if ((SDIO->STA & SDIO_IT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the SDIO's interrupt pending bits. + * @param SDIO_IT: specifies the interrupt pending bit to clear. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIO_DCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval None + */ +void SDIO_ClearITPendingBit(uint32_t SDIO_IT) +{ + /* Check the parameters */ + assert_param(IS_SDIO_CLEAR_IT(SDIO_IT)); + + SDIO->ICR = SDIO_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c new file mode 100644 index 0000000..d02193e --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c @@ -0,0 +1,1286 @@ +/** + ****************************************************************************** + * @file stm32f4xx_spi.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Serial peripheral interface (SPI): + * - Initialization and Configuration + * - Data transfers functions + * - Hardware CRC Calculation + * - DMA transfers management + * - Interrupts and flags management + * + * @verbatim + * + * + * =================================================================== + * How to use this driver + * =================================================================== + * + * 1. Enable peripheral clock using the following functions + * RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE) for SPI1 + * RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE) for SPI2 + * RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE) for SPI3. + * + * 2. Enable SCK, MOSI, MISO and NSS GPIO clocks using RCC_AHB1PeriphClockCmd() + * function. + * In I2S mode, if an external clock source is used then the I2S CKIN pin GPIO + * clock should also be enabled. + * + * 3. Peripherals alternate function: + * - Connect the pin to the desired peripherals' Alternate + * Function (AF) using GPIO_PinAFConfig() function + * - Configure the desired pin in alternate function by: + * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF + * - Select the type, pull-up/pull-down and output speed via + * GPIO_PuPd, GPIO_OType and GPIO_Speed members + * - Call GPIO_Init() function + * In I2S mode, if an external clock source is used then the I2S CKIN pin + * should be also configured in Alternate function Push-pull pull-up mode. + * + * 4. Program the Polarity, Phase, First Data, Baud Rate Prescaler, Slave + * Management, Peripheral Mode and CRC Polynomial values using the SPI_Init() + * function. + * In I2S mode, program the Mode, Standard, Data Format, MCLK Output, Audio + * frequency and Polarity using I2S_Init() function. + * For I2S mode, make sure that either: + * - I2S PLL is configured using the functions RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S), + * RCC_PLLI2SCmd(ENABLE) and RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY). + * or + * - External clock source is configured using the function + * RCC_I2SCLKConfig(RCC_I2S2CLKSource_Ext) and after setting correctly the define constant + * I2S_EXTERNAL_CLOCK_VAL in the stm32f4xx_conf.h file. + * + * 5. Enable the NVIC and the corresponding interrupt using the function + * SPI_ITConfig() if you need to use interrupt mode. + * + * 6. When using the DMA mode + * - Configure the DMA using DMA_Init() function + * - Active the needed channel Request using SPI_I2S_DMACmd() function + * + * 7. Enable the SPI using the SPI_Cmd() function or enable the I2S using + * I2S_Cmd(). + * + * 8. Enable the DMA using the DMA_Cmd() function when using DMA mode. + * + * 9. Optionally, you can enable/configure the following parameters without + * re-initialization (i.e there is no need to call again SPI_Init() function): + * - When bidirectional mode (SPI_Direction_1Line_Rx or SPI_Direction_1Line_Tx) + * is programmed as Data direction parameter using the SPI_Init() function + * it can be possible to switch between SPI_Direction_Tx or SPI_Direction_Rx + * using the SPI_BiDirectionalLineConfig() function. + * - When SPI_NSS_Soft is selected as Slave Select Management parameter + * using the SPI_Init() function it can be possible to manage the + * NSS internal signal using the SPI_NSSInternalSoftwareConfig() function. + * - Reconfigure the data size using the SPI_DataSizeConfig() function + * - Enable or disable the SS output using the SPI_SSOutputCmd() function + * + * 10. To use the CRC Hardware calculation feature refer to the Peripheral + * CRC hardware Calculation subsection. + * + * + * It is possible to use SPI in I2S full duplex mode, in this case, each SPI + * peripheral is able to manage sending and receiving data simultaneously + * using two data lines. Each SPI peripheral has an extended block called I2Sxext + * (ie. I2S2ext for SPI2 and I2S3ext for SPI3). + * The extension block is not a full SPI IP, it is used only as I2S slave to + * implement full duplex mode. The extension block uses the same clock sources + * as its master. + * To configure I2S full duplex you have to: + * + * 1. Configure SPIx in I2S mode (I2S_Init() function) as described above. + * + * 2. Call the I2S_FullDuplexConfig() function using the same strucutre passed to + * I2S_Init() function. + * + * 3. Call I2S_Cmd() for SPIx then for its extended block. + * + * 4. To configure interrupts or DMA requests and to get/clear flag status, + * use I2Sxext instance for the extension block. + * + * Functions that can be called with I2Sxext instances are: + * I2S_Cmd(), I2S_FullDuplexConfig(), SPI_I2S_ReceiveData(), SPI_I2S_SendData(), + * SPI_I2S_DMACmd(), SPI_I2S_ITConfig(), SPI_I2S_GetFlagStatus(), SPI_I2S_ClearFlag(), + * SPI_I2S_GetITStatus() and SPI_I2S_ClearITPendingBit(). + * + * Example: To use SPI3 in Full duplex mode (SPI3 is Master Tx, I2S3ext is Slave Rx): + * + * RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); + * I2S_StructInit(&I2SInitStruct); + * I2SInitStruct.Mode = I2S_Mode_MasterTx; + * I2S_Init(SPI3, &I2SInitStruct); + * I2S_FullDuplexConfig(SPI3ext, &I2SInitStruct) + * I2S_Cmd(SPI3, ENABLE); + * I2S_Cmd(SPI3ext, ENABLE); + * ... + * while (SPI_I2S_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET) + * {} + * SPI_I2S_SendData(SPI3, txdata[i]); + * ... + * while (SPI_I2S_GetFlagStatus(I2S3ext, SPI_FLAG_RXNE) == RESET) + * {} + * rxdata[i] = SPI_I2S_ReceiveData(I2S3ext); + * ... + * + * + * @note In I2S mode: if an external clock is used as source clock for the I2S, + * then the define I2S_EXTERNAL_CLOCK_VAL in file stm32f4xx_conf.h should + * be enabled and set to the value of the source clock frequency (in Hz). + * + * @note In SPI mode: To use the SPI TI mode, call the function SPI_TIModeCmd() + * just after calling the function SPI_Init(). + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_spi.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup SPI + * @brief SPI driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* SPI registers Masks */ +#define CR1_CLEAR_MASK ((uint16_t)0x3040) +#define I2SCFGR_CLEAR_MASK ((uint16_t)0xF040) + +/* RCC PLLs masks */ +#define PLLCFGR_PPLR_MASK ((uint32_t)0x70000000) +#define PLLCFGR_PPLN_MASK ((uint32_t)0x00007FC0) + +#define SPI_CR2_FRF ((uint16_t)0x0010) +#define SPI_SR_TIFRFE ((uint16_t)0x0100) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup SPI_Private_Functions + * @{ + */ + +/** @defgroup SPI_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + + This section provides a set of functions allowing to initialize the SPI Direction, + SPI Mode, SPI Data Size, SPI Polarity, SPI Phase, SPI NSS Management, SPI Baud + Rate Prescaler, SPI First Bit and SPI CRC Polynomial. + + The SPI_Init() function follows the SPI configuration procedures for Master mode + and Slave mode (details for these procedures are available in reference manual + (RM0090)). + +@endverbatim + * @{ + */ + +/** + * @brief Deinitialize the SPIx peripheral registers to their default reset values. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode. + * + * @note The extended I2S blocks (ie. I2S2ext and I2S3ext blocks) are deinitialized + * when the relative I2S peripheral is deinitialized (the extended block's clock + * is managed by the I2S peripheral clock). + * + * @retval None + */ +void SPI_I2S_DeInit(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + if (SPIx == SPI1) + { + /* Enable SPI1 reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE); + /* Release SPI1 from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE); + } + else if (SPIx == SPI2) + { + /* Enable SPI2 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); + /* Release SPI2 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE); + } + else + { + if (SPIx == SPI3) + { + /* Enable SPI3 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE); + /* Release SPI3 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE); + } + } +} + +/** + * @brief Initializes the SPIx peripheral according to the specified + * parameters in the SPI_InitStruct. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that + * contains the configuration information for the specified SPI peripheral. + * @retval None + */ +void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct) +{ + uint16_t tmpreg = 0; + + /* check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Check the SPI parameters */ + assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction)); + assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode)); + assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize)); + assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); + assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA)); + assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS)); + assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler)); + assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit)); + assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial)); + +/*---------------------------- SPIx CR1 Configuration ------------------------*/ + /* Get the SPIx CR1 value */ + tmpreg = SPIx->CR1; + /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */ + tmpreg &= CR1_CLEAR_MASK; + /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler + master/salve mode, CPOL and CPHA */ + /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */ + /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */ + /* Set LSBFirst bit according to SPI_FirstBit value */ + /* Set BR bits according to SPI_BaudRatePrescaler value */ + /* Set CPOL bit according to SPI_CPOL value */ + /* Set CPHA bit according to SPI_CPHA value */ + tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode | + SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL | + SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS | + SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit); + /* Write to SPIx CR1 */ + SPIx->CR1 = tmpreg; + + /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */ + SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD); +/*---------------------------- SPIx CRCPOLY Configuration --------------------*/ + /* Write to SPIx CRCPOLY */ + SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial; +} + +/** + * @brief Initializes the SPIx peripheral according to the specified + * parameters in the I2S_InitStruct. + * @param SPIx: where x can be 2 or 3 to select the SPI peripheral (configured in I2S mode). + * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure that + * contains the configuration information for the specified SPI peripheral + * configured in I2S mode. + * + * @note The function calculates the optimal prescaler needed to obtain the most + * accurate audio frequency (depending on the I2S clock source, the PLL values + * and the product configuration). But in case the prescaler value is greater + * than 511, the default value (0x02) will be configured instead. + * + * @note if an external clock is used as source clock for the I2S, then the define + * I2S_EXTERNAL_CLOCK_VAL in file stm32f4xx_conf.h should be enabled and set + * to the value of the the source clock frequency (in Hz). + * + * @retval None + */ +void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct) +{ + uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1; + uint32_t tmp = 0, i2sclk = 0; +#ifndef I2S_EXTERNAL_CLOCK_VAL + uint32_t pllm = 0, plln = 0, pllr = 0; +#endif /* I2S_EXTERNAL_CLOCK_VAL */ + + /* Check the I2S parameters */ + assert_param(IS_SPI_23_PERIPH(SPIx)); + assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode)); + assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard)); + assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat)); + assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput)); + assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq)); + assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL)); + +/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/ + /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ + SPIx->I2SCFGR &= I2SCFGR_CLEAR_MASK; + SPIx->I2SPR = 0x0002; + + /* Get the I2SCFGR register value */ + tmpreg = SPIx->I2SCFGR; + + /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/ + if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default) + { + i2sodd = (uint16_t)0; + i2sdiv = (uint16_t)2; + } + /* If the requested audio frequency is not the default, compute the prescaler */ + else + { + /* Check the frame length (For the Prescaler computing) *******************/ + if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b) + { + /* Packet length is 16 bits */ + packetlength = 1; + } + else + { + /* Packet length is 32 bits */ + packetlength = 2; + } + + /* Get I2S source Clock frequency ****************************************/ + + /* If an external I2S clock has to be used, this define should be set + in the project configuration or in the stm32f4xx_conf.h file */ + #ifdef I2S_EXTERNAL_CLOCK_VAL + /* Set external clock as I2S clock source */ + if ((RCC->CFGR & RCC_CFGR_I2SSRC) == 0) + { + RCC->CFGR |= (uint32_t)RCC_CFGR_I2SSRC; + } + + /* Set the I2S clock to the external clock value */ + i2sclk = I2S_EXTERNAL_CLOCK_VAL; + + #else /* There is no define for External I2S clock source */ + /* Set PLLI2S as I2S clock source */ + if ((RCC->CFGR & RCC_CFGR_I2SSRC) != 0) + { + RCC->CFGR &= ~(uint32_t)RCC_CFGR_I2SSRC; + } + + /* Get the PLLI2SN value */ + plln = (uint32_t)(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6) & \ + (RCC_PLLI2SCFGR_PLLI2SN >> 6)); + + /* Get the PLLI2SR value */ + pllr = (uint32_t)(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28) & \ + (RCC_PLLI2SCFGR_PLLI2SR >> 28)); + + /* Get the PLLM value */ + pllm = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM); + + /* Get the I2S source clock value */ + i2sclk = (uint32_t)(((HSE_VALUE / pllm) * plln) / pllr); + #endif /* I2S_EXTERNAL_CLOCK_VAL */ + + /* Compute the Real divider depending on the MCLK output state, with a floating point */ + if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable) + { + /* MCLK output is enabled */ + tmp = (uint16_t)(((((i2sclk / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5); + } + else + { + /* MCLK output is disabled */ + tmp = (uint16_t)(((((i2sclk / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5); + } + + /* Remove the flatting point */ + tmp = tmp / 10; + + /* Check the parity of the divider */ + i2sodd = (uint16_t)(tmp & (uint16_t)0x0001); + + /* Compute the i2sdiv prescaler */ + i2sdiv = (uint16_t)((tmp - i2sodd) / 2); + + /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */ + i2sodd = (uint16_t) (i2sodd << 8); + } + + /* Test if the divider is 1 or 0 or greater than 0xFF */ + if ((i2sdiv < 2) || (i2sdiv > 0xFF)) + { + /* Set the default values */ + i2sdiv = 2; + i2sodd = 0; + } + + /* Write to SPIx I2SPR register the computed value */ + SPIx->I2SPR = (uint16_t)((uint16_t)i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput)); + + /* Configure the I2S with the SPI_InitStruct values */ + tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(I2S_InitStruct->I2S_Mode | \ + (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \ + (uint16_t)I2S_InitStruct->I2S_CPOL)))); + + /* Write to SPIx I2SCFGR */ + SPIx->I2SCFGR = tmpreg; +} + +/** + * @brief Fills each SPI_InitStruct member with its default value. + * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure which will be initialized. + * @retval None + */ +void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct) +{ +/*--------------- Reset SPI init structure parameters values -----------------*/ + /* Initialize the SPI_Direction member */ + SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex; + /* initialize the SPI_Mode member */ + SPI_InitStruct->SPI_Mode = SPI_Mode_Slave; + /* initialize the SPI_DataSize member */ + SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b; + /* Initialize the SPI_CPOL member */ + SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low; + /* Initialize the SPI_CPHA member */ + SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge; + /* Initialize the SPI_NSS member */ + SPI_InitStruct->SPI_NSS = SPI_NSS_Hard; + /* Initialize the SPI_BaudRatePrescaler member */ + SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; + /* Initialize the SPI_FirstBit member */ + SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB; + /* Initialize the SPI_CRCPolynomial member */ + SPI_InitStruct->SPI_CRCPolynomial = 7; +} + +/** + * @brief Fills each I2S_InitStruct member with its default value. + * @param I2S_InitStruct: pointer to a I2S_InitTypeDef structure which will be initialized. + * @retval None + */ +void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct) +{ +/*--------------- Reset I2S init structure parameters values -----------------*/ + /* Initialize the I2S_Mode member */ + I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx; + + /* Initialize the I2S_Standard member */ + I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips; + + /* Initialize the I2S_DataFormat member */ + I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b; + + /* Initialize the I2S_MCLKOutput member */ + I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable; + + /* Initialize the I2S_AudioFreq member */ + I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default; + + /* Initialize the I2S_CPOL member */ + I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low; +} + +/** + * @brief Enables or disables the specified SPI peripheral. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected SPI peripheral */ + SPIx->CR1 |= SPI_CR1_SPE; + } + else + { + /* Disable the selected SPI peripheral */ + SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE); + } +} + +/** + * @brief Enables or disables the specified SPI peripheral (in I2S mode). + * @param SPIx: where x can be 2 or 3 to select the SPI peripheral (or I2Sxext + * for full duplex mode). + * @param NewState: new state of the SPIx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_23_PERIPH_EXT(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected SPI peripheral (in I2S mode) */ + SPIx->I2SCFGR |= SPI_I2SCFGR_I2SE; + } + else + { + /* Disable the selected SPI peripheral in I2S mode */ + SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SE); + } +} + +/** + * @brief Configures the data size for the selected SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_DataSize: specifies the SPI data size. + * This parameter can be one of the following values: + * @arg SPI_DataSize_16b: Set data frame format to 16bit + * @arg SPI_DataSize_8b: Set data frame format to 8bit + * @retval None + */ +void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_DATASIZE(SPI_DataSize)); + /* Clear DFF bit */ + SPIx->CR1 &= (uint16_t)~SPI_DataSize_16b; + /* Set new DFF bit value */ + SPIx->CR1 |= SPI_DataSize; +} + +/** + * @brief Selects the data transfer direction in bidirectional mode for the specified SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_Direction: specifies the data transfer direction in bidirectional mode. + * This parameter can be one of the following values: + * @arg SPI_Direction_Tx: Selects Tx transmission direction + * @arg SPI_Direction_Rx: Selects Rx receive direction + * @retval None + */ +void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_DIRECTION(SPI_Direction)); + if (SPI_Direction == SPI_Direction_Tx) + { + /* Set the Tx only mode */ + SPIx->CR1 |= SPI_Direction_Tx; + } + else + { + /* Set the Rx only mode */ + SPIx->CR1 &= SPI_Direction_Rx; + } +} + +/** + * @brief Configures internally by software the NSS pin for the selected SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_NSSInternalSoft: specifies the SPI NSS internal state. + * This parameter can be one of the following values: + * @arg SPI_NSSInternalSoft_Set: Set NSS pin internally + * @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally + * @retval None + */ +void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft)); + if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset) + { + /* Set NSS pin internally by software */ + SPIx->CR1 |= SPI_NSSInternalSoft_Set; + } + else + { + /* Reset NSS pin internally by software */ + SPIx->CR1 &= SPI_NSSInternalSoft_Reset; + } +} + +/** + * @brief Enables or disables the SS output for the selected SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx SS output. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected SPI SS output */ + SPIx->CR2 |= (uint16_t)SPI_CR2_SSOE; + } + else + { + /* Disable the selected SPI SS output */ + SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE); + } +} + +/** + * @brief Enables or disables the SPIx/I2Sx DMA interface. + * + * @note This function can be called only after the SPI_Init() function has + * been called. + * @note When TI mode is selected, the control bits SSM, SSI, CPOL and CPHA + * are not taken into consideration and are configured by hardware + * respectively to the TI mode requirements. + * + * @param SPIx: where x can be 1, 2 or 3 + * @param NewState: new state of the selected SPI TI communication mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TI mode for the selected SPI peripheral */ + SPIx->CR2 |= SPI_CR2_FRF; + } + else + { + /* Disable the TI mode for the selected SPI peripheral */ + SPIx->CR2 &= (uint16_t)~SPI_CR2_FRF; + } +} + +/** + * @brief Configures the full duplex mode for the I2Sx peripheral using its + * extension I2Sxext according to the specified parameters in the + * I2S_InitStruct. + * @param I2Sxext: where x can be 2 or 3 to select the I2S peripheral extension block. + * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure that + * contains the configuration information for the specified I2S peripheral + * extension. + * + * @note The structure pointed by I2S_InitStruct parameter should be the same + * used for the master I2S peripheral. In this case, if the master is + * configured as transmitter, the slave will be receiver and vice versa. + * Or you can force a different mode by modifying the field I2S_Mode to the + * value I2S_SlaveRx or I2S_SlaveTx indepedently of the master configuration. + * + * @note The I2S full duplex extension can be configured in slave mode only. + * + * @retval None + */ +void I2S_FullDuplexConfig(SPI_TypeDef* I2Sxext, I2S_InitTypeDef* I2S_InitStruct) +{ + uint16_t tmpreg = 0, tmp = 0; + + /* Check the I2S parameters */ + assert_param(IS_I2S_EXT_PERIPH(I2Sxext)); + assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode)); + assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard)); + assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat)); + assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL)); + +/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/ + /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ + I2Sxext->I2SCFGR &= I2SCFGR_CLEAR_MASK; + I2Sxext->I2SPR = 0x0002; + + /* Get the I2SCFGR register value */ + tmpreg = I2Sxext->I2SCFGR; + + /* Get the mode to be configured for the extended I2S */ + if ((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterTx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_SlaveTx)) + { + tmp = I2S_Mode_SlaveRx; + } + else + { + if ((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterRx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_SlaveRx)) + { + tmp = I2S_Mode_SlaveTx; + } + } + + + /* Configure the I2S with the SPI_InitStruct values */ + tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(tmp | \ + (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \ + (uint16_t)I2S_InitStruct->I2S_CPOL)))); + + /* Write to SPIx I2SCFGR */ + I2Sxext->I2SCFGR = tmpreg; +} + +/** + * @} + */ + +/** @defgroup SPI_Group2 Data transfers functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + Data transfers functions + =============================================================================== + + This section provides a set of functions allowing to manage the SPI data transfers + + In reception, data are received and then stored into an internal Rx buffer while + In transmission, data are first stored into an internal Tx buffer before being + transmitted. + + The read access of the SPI_DR register can be done using the SPI_I2S_ReceiveData() + function and returns the Rx buffered value. Whereas a write access to the SPI_DR + can be done using SPI_I2S_SendData() function and stores the written data into + Tx buffer. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the most recent received data by the SPIx/I2Sx peripheral. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. + * @retval The value of the received data. + */ +uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); + + /* Return the data in the DR register */ + return SPIx->DR; +} + +/** + * @brief Transmits a Data through the SPIx/I2Sx peripheral. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. + * @param Data: Data to be transmitted. + * @retval None + */ +void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); + + /* Write in the DR register the data to be sent */ + SPIx->DR = Data; +} + +/** + * @} + */ + +/** @defgroup SPI_Group3 Hardware CRC Calculation functions + * @brief Hardware CRC Calculation functions + * +@verbatim + =============================================================================== + Hardware CRC Calculation functions + =============================================================================== + + This section provides a set of functions allowing to manage the SPI CRC hardware + calculation + + SPI communication using CRC is possible through the following procedure: + 1. Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler, + Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init() + function. + 2. Enable the CRC calculation using the SPI_CalculateCRC() function. + 3. Enable the SPI using the SPI_Cmd() function + 4. Before writing the last data to the TX buffer, set the CRCNext bit using the + SPI_TransmitCRC() function to indicate that after transmission of the last + data, the CRC should be transmitted. + 5. After transmitting the last data, the SPI transmits the CRC. The SPI_CR1_CRCNEXT + bit is reset. The CRC is also received and compared against the SPI_RXCRCR + value. + If the value does not match, the SPI_FLAG_CRCERR flag is set and an interrupt + can be generated when the SPI_I2S_IT_ERR interrupt is enabled. + +@note It is advised not to read the calculated CRC values during the communication. + +@note When the SPI is in slave mode, be careful to enable CRC calculation only + when the clock is stable, that is, when the clock is in the steady state. + If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive + to the SCK slave input clock as soon as CRCEN is set, and this, whatever + the value of the SPE bit. + +@note With high bitrate frequencies, be careful when transmitting the CRC. + As the number of used CPU cycles has to be as low as possible in the CRC + transfer phase, it is forbidden to call software functions in the CRC + transmission sequence to avoid errors in the last data and CRC reception. + In fact, CRCNEXT bit has to be written before the end of the transmission/reception + of the last data. + +@note For high bit rate frequencies, it is advised to use the DMA mode to avoid the + degradation of the SPI speed performance due to CPU accesses impacting the + SPI bandwidth. + +@note When the STM32F4xx is configured as slave and the NSS hardware mode is + used, the NSS pin needs to be kept low between the data phase and the CRC + phase. + +@note When the SPI is configured in slave mode with the CRC feature enabled, CRC + calculation takes place even if a high level is applied on the NSS pin. + This may happen for example in case of a multi-slave environment where the + communication master addresses slaves alternately. + +@note Between a slave de-selection (high level on NSS) and a new slave selection + (low level on NSS), the CRC value should be cleared on both master and slave + sides in order to resynchronize the master and slave for their respective + CRC calculation. + +@note To clear the CRC, follow the procedure below: + 1. Disable SPI using the SPI_Cmd() function + 2. Disable the CRC calculation using the SPI_CalculateCRC() function. + 3. Enable the CRC calculation using the SPI_CalculateCRC() function. + 4. Enable SPI using the SPI_Cmd() function. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the CRC value calculation of the transferred bytes. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx CRC value calculation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected SPI CRC calculation */ + SPIx->CR1 |= SPI_CR1_CRCEN; + } + else + { + /* Disable the selected SPI CRC calculation */ + SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN); + } +} + +/** + * @brief Transmit the SPIx CRC value. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @retval None + */ +void SPI_TransmitCRC(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Enable the selected SPI CRC transmission */ + SPIx->CR1 |= SPI_CR1_CRCNEXT; +} + +/** + * @brief Returns the transmit or the receive CRC register value for the specified SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_CRC: specifies the CRC register to be read. + * This parameter can be one of the following values: + * @arg SPI_CRC_Tx: Selects Tx CRC register + * @arg SPI_CRC_Rx: Selects Rx CRC register + * @retval The selected CRC register value.. + */ +uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC) +{ + uint16_t crcreg = 0; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_CRC(SPI_CRC)); + if (SPI_CRC != SPI_CRC_Rx) + { + /* Get the Tx CRC register */ + crcreg = SPIx->TXCRCR; + } + else + { + /* Get the Rx CRC register */ + crcreg = SPIx->RXCRCR; + } + /* Return the selected CRC register */ + return crcreg; +} + +/** + * @brief Returns the CRC Polynomial register value for the specified SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @retval The CRC Polynomial register value. + */ +uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Return the CRC polynomial register */ + return SPIx->CRCPR; +} + +/** + * @} + */ + +/** @defgroup SPI_Group4 DMA transfers management functions + * @brief DMA transfers management functions + * +@verbatim + =============================================================================== + DMA transfers management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the SPIx/I2Sx DMA interface. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. + * @param SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request + * @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request + * @param NewState: new state of the selected SPI DMA transfer request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq)); + + if (NewState != DISABLE) + { + /* Enable the selected SPI DMA requests */ + SPIx->CR2 |= SPI_I2S_DMAReq; + } + else + { + /* Disable the selected SPI DMA requests */ + SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq; + } +} + +/** + * @} + */ + +/** @defgroup SPI_Group5 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + + This section provides a set of functions allowing to configure the SPI Interrupts + sources and check or clear the flags or pending bits status. + The user should identify which mode will be used in his application to manage + the communication: Polling mode, Interrupt mode or DMA mode. + + Polling Mode + ============= + In Polling Mode, the SPI/I2S communication can be managed by 9 flags: + 1. SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer register + 2. SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer register + 3. SPI_I2S_FLAG_BSY : to indicate the state of the communication layer of the SPI. + 4. SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur + 5. SPI_FLAG_MODF : to indicate if a Mode Fault error occur + 6. SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur + 7. I2S_FLAG_TIFRFE: to indicate a Frame Format error occurs. + 8. I2S_FLAG_UDR: to indicate an Underrun error occurs. + 9. I2S_FLAG_CHSIDE: to indicate Channel Side. + +@note Do not use the BSY flag to handle each data transmission or reception. It is + better to use the TXE and RXNE flags instead. + + In this Mode it is advised to use the following functions: + - FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); + - void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); + + Interrupt Mode + =============== + In Interrupt Mode, the SPI communication can be managed by 3 interrupt sources + and 7 pending bits: + Pending Bits: + ------------- + 1. SPI_I2S_IT_TXE : to indicate the status of the transmit buffer register + 2. SPI_I2S_IT_RXNE : to indicate the status of the receive buffer register + 3. SPI_IT_CRCERR : to indicate if a CRC Calculation error occur (available in SPI mode only) + 4. SPI_IT_MODF : to indicate if a Mode Fault error occur (available in SPI mode only) + 5. SPI_I2S_IT_OVR : to indicate if an Overrun error occur + 6. I2S_IT_UDR : to indicate an Underrun Error occurs (available in I2S mode only). + 7. I2S_FLAG_TIFRFE : to indicate a Frame Format error occurs (available in TI mode only). + + Interrupt Source: + ----------------- + 1. SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty + interrupt. + 2. SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not + empty interrupt. + 3. SPI_I2S_IT_ERR : specifies the interrupt source for the errors interrupt. + + In this Mode it is advised to use the following functions: + - void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState); + - ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); + - void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); + + DMA Mode + ======== + In DMA Mode, the SPI communication can be managed by 2 DMA Channel requests: + 1. SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request + 2. SPI_I2S_DMAReq_Rx: specifies the Rx buffer DMA transfer request + + In this Mode it is advised to use the following function: + - void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified SPI/I2S interrupts. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. + * @param SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled. + * This parameter can be one of the following values: + * @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask + * @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask + * @arg SPI_I2S_IT_ERR: Error interrupt mask + * @param NewState: new state of the specified SPI interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState) +{ + uint16_t itpos = 0, itmask = 0 ; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT)); + + /* Get the SPI IT index */ + itpos = SPI_I2S_IT >> 4; + + /* Set the IT mask */ + itmask = (uint16_t)1 << (uint16_t)itpos; + + if (NewState != DISABLE) + { + /* Enable the selected SPI interrupt */ + SPIx->CR2 |= itmask; + } + else + { + /* Disable the selected SPI interrupt */ + SPIx->CR2 &= (uint16_t)~itmask; + } +} + +/** + * @brief Checks whether the specified SPIx/I2Sx flag is set or not. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. + * @param SPI_I2S_FLAG: specifies the SPI flag to check. + * This parameter can be one of the following values: + * @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag. + * @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag. + * @arg SPI_I2S_FLAG_BSY: Busy flag. + * @arg SPI_I2S_FLAG_OVR: Overrun flag. + * @arg SPI_FLAG_MODF: Mode Fault flag. + * @arg SPI_FLAG_CRCERR: CRC Error flag. + * @arg SPI_I2S_FLAG_TIFRFE: Format Error. + * @arg I2S_FLAG_UDR: Underrun Error flag. + * @arg I2S_FLAG_CHSIDE: Channel Side flag. + * @retval The new state of SPI_I2S_FLAG (SET or RESET). + */ +FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); + assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG)); + + /* Check the status of the specified SPI flag */ + if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET) + { + /* SPI_I2S_FLAG is set */ + bitstatus = SET; + } + else + { + /* SPI_I2S_FLAG is reset */ + bitstatus = RESET; + } + /* Return the SPI_I2S_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the SPIx CRC Error (CRCERR) flag. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. + * @param SPI_I2S_FLAG: specifies the SPI flag to clear. + * This function clears only CRCERR flag. + * @arg SPI_FLAG_CRCERR: CRC Error flag. + * + * @note OVR (OverRun error) flag is cleared by software sequence: a read + * operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read + * operation to SPI_SR register (SPI_I2S_GetFlagStatus()). + * @note UDR (UnderRun error) flag is cleared by a read operation to + * SPI_SR register (SPI_I2S_GetFlagStatus()). + * @note MODF (Mode Fault) flag is cleared by software sequence: a read/write + * operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a + * write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI). + * + * @retval None + */ +void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); + assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG)); + + /* Clear the selected SPI CRC Error (CRCERR) flag */ + SPIx->SR = (uint16_t)~SPI_I2S_FLAG; +} + +/** + * @brief Checks whether the specified SPIx/I2Sx interrupt has occurred or not. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. + * @param SPI_I2S_IT: specifies the SPI interrupt source to check. + * This parameter can be one of the following values: + * @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt. + * @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt. + * @arg SPI_I2S_IT_OVR: Overrun interrupt. + * @arg SPI_IT_MODF: Mode Fault interrupt. + * @arg SPI_IT_CRCERR: CRC Error interrupt. + * @arg I2S_IT_UDR: Underrun interrupt. + * @arg SPI_I2S_IT_TIFRFE: Format Error interrupt. + * @retval The new state of SPI_I2S_IT (SET or RESET). + */ +ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) +{ + ITStatus bitstatus = RESET; + uint16_t itpos = 0, itmask = 0, enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); + assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT)); + + /* Get the SPI_I2S_IT index */ + itpos = 0x01 << (SPI_I2S_IT & 0x0F); + + /* Get the SPI_I2S_IT IT mask */ + itmask = SPI_I2S_IT >> 4; + + /* Set the IT mask */ + itmask = 0x01 << itmask; + + /* Get the SPI_I2S_IT enable bit status */ + enablestatus = (SPIx->CR2 & itmask) ; + + /* Check the status of the specified SPI interrupt */ + if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus) + { + /* SPI_I2S_IT is set */ + bitstatus = SET; + } + else + { + /* SPI_I2S_IT is reset */ + bitstatus = RESET; + } + /* Return the SPI_I2S_IT status */ + return bitstatus; +} + +/** + * @brief Clears the SPIx CRC Error (CRCERR) interrupt pending bit. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. + * @param SPI_I2S_IT: specifies the SPI interrupt pending bit to clear. + * This function clears only CRCERR interrupt pending bit. + * @arg SPI_IT_CRCERR: CRC Error interrupt. + * + * @note OVR (OverRun Error) interrupt pending bit is cleared by software + * sequence: a read operation to SPI_DR register (SPI_I2S_ReceiveData()) + * followed by a read operation to SPI_SR register (SPI_I2S_GetITStatus()). + * @note UDR (UnderRun Error) interrupt pending bit is cleared by a read + * operation to SPI_SR register (SPI_I2S_GetITStatus()). + * @note MODF (Mode Fault) interrupt pending bit is cleared by software sequence: + * a read/write operation to SPI_SR register (SPI_I2S_GetITStatus()) + * followed by a write operation to SPI_CR1 register (SPI_Cmd() to enable + * the SPI). + * @retval None + */ +void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) +{ + uint16_t itpos = 0; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); + assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT)); + + /* Get the SPI_I2S IT index */ + itpos = 0x01 << (SPI_I2S_IT & 0x0F); + + /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */ + SPIx->SR = (uint16_t)~itpos; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c new file mode 100644 index 0000000..2625cfe --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c @@ -0,0 +1,197 @@ +/** + ****************************************************************************** + * @file stm32f4xx_syscfg.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the SYSCFG peripheral. + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + * + * This driver provides functions for: + * + * 1. Remapping the memory accessible in the code area using SYSCFG_MemoryRemapConfig() + * + * 2. Manage the EXTI lines connection to the GPIOs using SYSCFG_EXTILineConfig() + * + * 3. Select the ETHERNET media interface (RMII/RII) using SYSCFG_ETH_MediaInterfaceConfig() + * + * @note SYSCFG APB clock must be enabled to get write access to SYSCFG registers, + * using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_syscfg.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup SYSCFG + * @brief SYSCFG driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* ------------ RCC registers bit address in the alias region ----------- */ +#define SYSCFG_OFFSET (SYSCFG_BASE - PERIPH_BASE) +/* --- PMC Register ---*/ +/* Alias word address of MII_RMII_SEL bit */ +#define PMC_OFFSET (SYSCFG_OFFSET + 0x04) +#define MII_RMII_SEL_BitNumber ((uint8_t)0x17) +#define PMC_MII_RMII_SEL_BB (PERIPH_BB_BASE + (PMC_OFFSET * 32) + (MII_RMII_SEL_BitNumber * 4)) + +/* --- CMPCR Register ---*/ +/* Alias word address of CMP_PD bit */ +#define CMPCR_OFFSET (SYSCFG_OFFSET + 0x20) +#define CMP_PD_BitNumber ((uint8_t)0x00) +#define CMPCR_CMP_PD_BB (PERIPH_BB_BASE + (CMPCR_OFFSET * 32) + (CMP_PD_BitNumber * 4)) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup SYSCFG_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the Alternate Functions (remap and EXTI configuration) + * registers to their default reset values. + * @param None + * @retval None + */ +void SYSCFG_DeInit(void) +{ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, DISABLE); +} + +/** + * @brief Changes the mapping of the specified pin. + * @param SYSCFG_Memory: selects the memory remapping. + * This parameter can be one of the following values: + * @arg SYSCFG_MemoryRemap_Flash: Main Flash memory mapped at 0x00000000 + * @arg SYSCFG_MemoryRemap_SystemFlash: System Flash memory mapped at 0x00000000 + * @arg SYSCFG_MemoryRemap_FSMC: FSMC (Bank1 (NOR/PSRAM 1 and 2) mapped at 0x00000000 + * @arg SYSCFG_MemoryRemap_SRAM: Embedded SRAM (112kB) mapped at 0x00000000 + * @retval None + */ +void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap) +{ + /* Check the parameters */ + assert_param(IS_SYSCFG_MEMORY_REMAP_CONFING(SYSCFG_MemoryRemap)); + + SYSCFG->MEMRMP = SYSCFG_MemoryRemap; +} + +/** + * @brief Selects the GPIO pin used as EXTI Line. + * @param EXTI_PortSourceGPIOx : selects the GPIO port to be used as source for + * EXTI lines where x can be (A..I). + * @param EXTI_PinSourcex: specifies the EXTI line to be configured. + * This parameter can be EXTI_PinSourcex where x can be (0..15, except + * for EXTI_PortSourceGPIOI x can be (0..11). + * @retval None + */ +void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex) +{ + uint32_t tmp = 0x00; + + /* Check the parameters */ + assert_param(IS_EXTI_PORT_SOURCE(EXTI_PortSourceGPIOx)); + assert_param(IS_EXTI_PIN_SOURCE(EXTI_PinSourcex)); + + tmp = ((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03)); + SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] &= ~tmp; + SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] |= (((uint32_t)EXTI_PortSourceGPIOx) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03))); +} + +/** + * @brief Selects the ETHERNET media interface + * @param SYSCFG_ETH_MediaInterface: specifies the Media Interface mode. + * This parameter can be one of the following values: + * @arg SYSCFG_ETH_MediaInterface_MII: MII mode selected + * @arg SYSCFG_ETH_MediaInterface_RMII: RMII mode selected + * @retval None + */ +void SYSCFG_ETH_MediaInterfaceConfig(uint32_t SYSCFG_ETH_MediaInterface) +{ + assert_param(IS_SYSCFG_ETH_MEDIA_INTERFACE(SYSCFG_ETH_MediaInterface)); + /* Configure MII_RMII selection bit */ + *(__IO uint32_t *) PMC_MII_RMII_SEL_BB = SYSCFG_ETH_MediaInterface; +} + +/** + * @brief Enables or disables the I/O Compensation Cell. + * @note The I/O compensation cell can be used only when the device supply + * voltage ranges from 2.4 to 3.6 V. + * @param NewState: new state of the I/O Compensation Cell. + * This parameter can be one of the following values: + * @arg ENABLE: I/O compensation cell enabled + * @arg DISABLE: I/O compensation cell power-down mode + * @retval None + */ +void SYSCFG_CompensationCellCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMPCR_CMP_PD_BB = (uint32_t)NewState; +} + +/** + * @brief Checks whether the I/O Compensation Cell ready flag is set or not. + * @param None + * @retval The new state of the I/O Compensation Cell ready flag (SET or RESET) + */ +FlagStatus SYSCFG_GetCompensationCellStatus(void) +{ + FlagStatus bitstatus = RESET; + + if ((SYSCFG->CMPCR & SYSCFG_CMPCR_READY ) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c new file mode 100644 index 0000000..02982f8 --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c @@ -0,0 +1,3352 @@ +/** + ****************************************************************************** + * @file stm32f4xx_tim.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the TIM peripheral: + * - TimeBase management + * - Output Compare management + * - Input Capture management + * - Advanced-control timers (TIM1 and TIM8) specific features + * - Interrupts, DMA and flags management + * - Clocks management + * - Synchronization management + * - Specific interface management + * - Specific remapping management + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + * This driver provides functions to configure and program the TIM + * of all STM32F4xx devices. + * These functions are split in 9 groups: + * + * 1. TIM TimeBase management: this group includes all needed functions + * to configure the TM Timebase unit: + * - Set/Get Prescaler + * - Set/Get Autoreload + * - Counter modes configuration + * - Set Clock division + * - Select the One Pulse mode + * - Update Request Configuration + * - Update Disable Configuration + * - Auto-Preload Configuration + * - Enable/Disable the counter + * + * 2. TIM Output Compare management: this group includes all needed + * functions to configure the Capture/Compare unit used in Output + * compare mode: + * - Configure each channel, independently, in Output Compare mode + * - Select the output compare modes + * - Select the Polarities of each channel + * - Set/Get the Capture/Compare register values + * - Select the Output Compare Fast mode + * - Select the Output Compare Forced mode + * - Output Compare-Preload Configuration + * - Clear Output Compare Reference + * - Select the OCREF Clear signal + * - Enable/Disable the Capture/Compare Channels + * + * 3. TIM Input Capture management: this group includes all needed + * functions to configure the Capture/Compare unit used in + * Input Capture mode: + * - Configure each channel in input capture mode + * - Configure Channel1/2 in PWM Input mode + * - Set the Input Capture Prescaler + * - Get the Capture/Compare values + * + * 4. Advanced-control timers (TIM1 and TIM8) specific features + * - Configures the Break input, dead time, Lock level, the OSSI, + * the OSSR State and the AOE(automatic output enable) + * - Enable/Disable the TIM peripheral Main Outputs + * - Select the Commutation event + * - Set/Reset the Capture Compare Preload Control bit + * + * 5. TIM interrupts, DMA and flags management + * - Enable/Disable interrupt sources + * - Get flags status + * - Clear flags/ Pending bits + * - Enable/Disable DMA requests + * - Configure DMA burst mode + * - Select CaptureCompare DMA request + * + * 6. TIM clocks management: this group includes all needed functions + * to configure the clock controller unit: + * - Select internal/External clock + * - Select the external clock mode: ETR(Mode1/Mode2), TIx or ITRx + * + * 7. TIM synchronization management: this group includes all needed + * functions to configure the Synchronization unit: + * - Select Input Trigger + * - Select Output Trigger + * - Select Master Slave Mode + * - ETR Configuration when used as external trigger + * + * 8. TIM specific interface management, this group includes all + * needed functions to use the specific TIM interface: + * - Encoder Interface Configuration + * - Select Hall Sensor + * + * 9. TIM specific remapping management includes the Remapping + * configuration of specific timers + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_tim.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup TIM + * @brief TIM driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* ---------------------- TIM registers bit mask ------------------------ */ +#define SMCR_ETR_MASK ((uint16_t)0x00FF) +#define CCMR_OFFSET ((uint16_t)0x0018) +#define CCER_CCE_SET ((uint16_t)0x0001) +#define CCER_CCNE_SET ((uint16_t)0x0004) +#define CCMR_OC13M_MASK ((uint16_t)0xFF8F) +#define CCMR_OC24M_MASK ((uint16_t)0x8FFF) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup TIM_Private_Functions + * @{ + */ + +/** @defgroup TIM_Group1 TimeBase management functions + * @brief TimeBase management functions + * +@verbatim + =============================================================================== + TimeBase management functions + =============================================================================== + + =================================================================== + TIM Driver: how to use it in Timing(Time base) Mode + =================================================================== + To use the Timer in Timing(Time base) mode, the following steps are mandatory: + + 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function + + 2. Fill the TIM_TimeBaseInitStruct with the desired parameters. + + 3. Call TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruct) to configure the Time Base unit + with the corresponding configuration + + 4. Enable the NVIC if you need to generate the update interrupt. + + 5. Enable the corresponding interrupt using the function TIM_ITConfig(TIMx, TIM_IT_Update) + + 6. Call the TIM_Cmd(ENABLE) function to enable the TIM counter. + + Note1: All other functions can be used separately to modify, if needed, + a specific feature of the Timer. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the TIMx peripheral registers to their default reset values. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @retval None + + */ +void TIM_DeInit(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + if (TIMx == TIM1) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE); + } + else if (TIMx == TIM2) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE); + } + else if (TIMx == TIM3) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE); + } + else if (TIMx == TIM4) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE); + } + else if (TIMx == TIM5) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE); + } + else if (TIMx == TIM6) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE); + } + else if (TIMx == TIM7) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, DISABLE); + } + else if (TIMx == TIM8) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, DISABLE); + } + else if (TIMx == TIM9) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, DISABLE); + } + else if (TIMx == TIM10) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, DISABLE); + } + else if (TIMx == TIM11) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, DISABLE); + } + else if (TIMx == TIM12) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, DISABLE); + } + else if (TIMx == TIM13) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, DISABLE); + } + else + { + if (TIMx == TIM14) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, DISABLE); + } + } +} + +/** + * @brief Initializes the TIMx Time Base Unit peripheral according to + * the specified parameters in the TIM_TimeBaseInitStruct. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef structure + * that contains the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) +{ + uint16_t tmpcr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode)); + assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision)); + + tmpcr1 = TIMx->CR1; + + if((TIMx == TIM1) || (TIMx == TIM8)|| + (TIMx == TIM2) || (TIMx == TIM3)|| + (TIMx == TIM4) || (TIMx == TIM5)) + { + /* Select the Counter Mode */ + tmpcr1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS)); + tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode; + } + + if((TIMx != TIM6) && (TIMx != TIM7)) + { + /* Set the clock division */ + tmpcr1 &= (uint16_t)(~TIM_CR1_CKD); + tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision; + } + + TIMx->CR1 = tmpcr1; + + /* Set the Autoreload value */ + TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ; + + /* Set the Prescaler value */ + TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler; + + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + /* Set the Repetition Counter value */ + TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter; + } + + /* Generate an update event to reload the Prescaler + and the repetition counter(only for TIM1 and TIM8) value immediatly */ + TIMx->EGR = TIM_PSCReloadMode_Immediate; +} + +/** + * @brief Fills each TIM_TimeBaseInitStruct member with its default value. + * @param TIM_TimeBaseInitStruct : pointer to a TIM_TimeBaseInitTypeDef + * structure which will be initialized. + * @retval None + */ +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) +{ + /* Set the default configuration */ + TIM_TimeBaseInitStruct->TIM_Period = 0xFFFFFFFF; + TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000; + TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1; + TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInitStruct->TIM_RepetitionCounter = 0x0000; +} + +/** + * @brief Configures the TIMx Prescaler. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param Prescaler: specifies the Prescaler Register value + * @param TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode + * This parameter can be one of the following values: + * @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event. + * @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediatly. + * @retval None + */ +void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode)); + /* Set the Prescaler value */ + TIMx->PSC = Prescaler; + /* Set or reset the UG Bit */ + TIMx->EGR = TIM_PSCReloadMode; +} + +/** + * @brief Specifies the TIMx Counter Mode to be used. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_CounterMode: specifies the Counter Mode to be used + * This parameter can be one of the following values: + * @arg TIM_CounterMode_Up: TIM Up Counting Mode + * @arg TIM_CounterMode_Down: TIM Down Counting Mode + * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1 + * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2 + * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3 + * @retval None + */ +void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode) +{ + uint16_t tmpcr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode)); + + tmpcr1 = TIMx->CR1; + + /* Reset the CMS and DIR Bits */ + tmpcr1 &= (uint16_t)~(TIM_CR1_DIR | TIM_CR1_CMS); + + /* Set the Counter Mode */ + tmpcr1 |= TIM_CounterMode; + + /* Write to TIMx CR1 register */ + TIMx->CR1 = tmpcr1; +} + +/** + * @brief Sets the TIMx Counter Register value + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param Counter: specifies the Counter register new value. + * @retval None + */ +void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Set the Counter Register value */ + TIMx->CNT = Counter; +} + +/** + * @brief Sets the TIMx Autoreload Register value + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param Autoreload: specifies the Autoreload register new value. + * @retval None + */ +void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Set the Autoreload Register value */ + TIMx->ARR = Autoreload; +} + +/** + * @brief Gets the TIMx Counter value. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @retval Counter Register value + */ +uint32_t TIM_GetCounter(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Get the Counter Register value */ + return TIMx->CNT; +} + +/** + * @brief Gets the TIMx Prescaler value. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @retval Prescaler Register value. + */ +uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Get the Prescaler Register value */ + return TIMx->PSC; +} + +/** + * @brief Enables or Disables the TIMx Update event. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param NewState: new state of the TIMx UDIS bit + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the Update Disable Bit */ + TIMx->CR1 |= TIM_CR1_UDIS; + } + else + { + /* Reset the Update Disable Bit */ + TIMx->CR1 &= (uint16_t)~TIM_CR1_UDIS; + } +} + +/** + * @brief Configures the TIMx Update Request Interrupt source. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_UpdateSource: specifies the Update source. + * This parameter can be one of the following values: + * @arg TIM_UpdateSource_Global: Source of update is the counter + * overflow/underflow or the setting of UG bit, or an update + * generation through the slave mode controller. + * @arg TIM_UpdateSource_Regular: Source of update is counter overflow/underflow. + * @retval None + */ +void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource)); + + if (TIM_UpdateSource != TIM_UpdateSource_Global) + { + /* Set the URS Bit */ + TIMx->CR1 |= TIM_CR1_URS; + } + else + { + /* Reset the URS Bit */ + TIMx->CR1 &= (uint16_t)~TIM_CR1_URS; + } +} + +/** + * @brief Enables or disables TIMx peripheral Preload register on ARR. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param NewState: new state of the TIMx peripheral Preload register + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the ARR Preload Bit */ + TIMx->CR1 |= TIM_CR1_ARPE; + } + else + { + /* Reset the ARR Preload Bit */ + TIMx->CR1 &= (uint16_t)~TIM_CR1_ARPE; + } +} + +/** + * @brief Selects the TIMx's One Pulse Mode. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_OPMode: specifies the OPM Mode to be used. + * This parameter can be one of the following values: + * @arg TIM_OPMode_Single + * @arg TIM_OPMode_Repetitive + * @retval None + */ +void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_OPM_MODE(TIM_OPMode)); + + /* Reset the OPM Bit */ + TIMx->CR1 &= (uint16_t)~TIM_CR1_OPM; + + /* Configure the OPM Mode */ + TIMx->CR1 |= TIM_OPMode; +} + +/** + * @brief Sets the TIMx Clock Division value. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_CKD: specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CKD_DIV1: TDTS = Tck_tim + * @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim + * @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim + * @retval None + */ +void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_CKD_DIV(TIM_CKD)); + + /* Reset the CKD Bits */ + TIMx->CR1 &= (uint16_t)(~TIM_CR1_CKD); + + /* Set the CKD value */ + TIMx->CR1 |= TIM_CKD; +} + +/** + * @brief Enables or disables the specified TIM peripheral. + * @param TIMx: where x can be 1 to 14 to select the TIMx peripheral. + * @param NewState: new state of the TIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TIM Counter */ + TIMx->CR1 |= TIM_CR1_CEN; + } + else + { + /* Disable the TIM Counter */ + TIMx->CR1 &= (uint16_t)~TIM_CR1_CEN; + } +} +/** + * @} + */ + +/** @defgroup TIM_Group2 Output Compare management functions + * @brief Output Compare management functions + * +@verbatim + =============================================================================== + Output Compare management functions + =============================================================================== + + =================================================================== + TIM Driver: how to use it in Output Compare Mode + =================================================================== + To use the Timer in Output Compare mode, the following steps are mandatory: + + 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function + + 2. Configure the TIM pins by configuring the corresponding GPIO pins + + 2. Configure the Time base unit as described in the first part of this driver, + if needed, else the Timer will run with the default configuration: + - Autoreload value = 0xFFFF + - Prescaler value = 0x0000 + - Counter mode = Up counting + - Clock Division = TIM_CKD_DIV1 + + 3. Fill the TIM_OCInitStruct with the desired parameters including: + - The TIM Output Compare mode: TIM_OCMode + - TIM Output State: TIM_OutputState + - TIM Pulse value: TIM_Pulse + - TIM Output Compare Polarity : TIM_OCPolarity + + 4. Call TIM_OCxInit(TIMx, &TIM_OCInitStruct) to configure the desired channel with the + corresponding configuration + + 5. Call the TIM_Cmd(ENABLE) function to enable the TIM counter. + + Note1: All other functions can be used separately to modify, if needed, + a specific feature of the Timer. + + Note2: In case of PWM mode, this function is mandatory: + TIM_OCxPreloadConfig(TIMx, TIM_OCPreload_ENABLE); + + Note3: If the corresponding interrupt or DMA request are needed, the user should: + 1. Enable the NVIC (or the DMA) to use the TIM interrupts (or DMA requests). + 2. Enable the corresponding interrupt (or DMA request) using the function + TIM_ITConfig(TIMx, TIM_IT_CCx) (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)) + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the TIMx Channel1 according to the specified parameters in + * the TIM_OCInitStruct. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC1E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= (uint16_t)~TIM_CCMR1_OC1M; + tmpccmrx &= (uint16_t)~TIM_CCMR1_CC1S; + /* Select the Output Compare Mode */ + tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC1P; + /* Set the Output Compare Polarity */ + tmpccer |= TIM_OCInitStruct->TIM_OCPolarity; + + /* Set the Output State */ + tmpccer |= TIM_OCInitStruct->TIM_OutputState; + + if((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC1NP; + /* Set the Output N Polarity */ + tmpccer |= TIM_OCInitStruct->TIM_OCNPolarity; + /* Reset the Output N State */ + tmpccer &= (uint16_t)~TIM_CCER_CC1NE; + + /* Set the Output N State */ + tmpccer |= TIM_OCInitStruct->TIM_OutputNState; + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= (uint16_t)~TIM_CR2_OIS1; + tmpcr2 &= (uint16_t)~TIM_CR2_OIS1N; + /* Set the Output Idle state */ + tmpcr2 |= TIM_OCInitStruct->TIM_OCIdleState; + /* Set the Output N Idle state */ + tmpcr2 |= TIM_OCInitStruct->TIM_OCNIdleState; + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel2 according to the specified parameters + * in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC2E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= (uint16_t)~TIM_CCMR1_OC2M; + tmpccmrx &= (uint16_t)~TIM_CCMR1_CC2S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC2P; + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4); + + if((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC2NP; + /* Set the Output N Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 4); + /* Reset the Output N State */ + tmpccer &= (uint16_t)~TIM_CCER_CC2NE; + + /* Set the Output N State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 4); + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= (uint16_t)~TIM_CR2_OIS2; + tmpcr2 &= (uint16_t)~TIM_CR2_OIS2N; + /* Set the Output Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 2); + /* Set the Output N Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 2); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel3 according to the specified parameters + * in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 3: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC3E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= (uint16_t)~TIM_CCMR2_OC3M; + tmpccmrx &= (uint16_t)~TIM_CCMR2_CC3S; + /* Select the Output Compare Mode */ + tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC3P; + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 8); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 8); + + if((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC3NP; + /* Set the Output N Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 8); + /* Reset the Output N State */ + tmpccer &= (uint16_t)~TIM_CCER_CC3NE; + + /* Set the Output N State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 8); + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= (uint16_t)~TIM_CR2_OIS3; + tmpcr2 &= (uint16_t)~TIM_CR2_OIS3N; + /* Set the Output Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 4); + /* Set the Output N Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 4); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel4 according to the specified parameters + * in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC4E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= (uint16_t)~TIM_CCMR2_OC4M; + tmpccmrx &= (uint16_t)~TIM_CCMR2_CC4S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC4P; + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 12); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 12); + + if((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + /* Reset the Output Compare IDLE State */ + tmpcr2 &=(uint16_t) ~TIM_CR2_OIS4; + /* Set the Output Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 6); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Fills each TIM_OCInitStruct member with its default value. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure which will + * be initialized. + * @retval None + */ +void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + /* Set the default configuration */ + TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing; + TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStruct->TIM_OutputNState = TIM_OutputNState_Disable; + TIM_OCInitStruct->TIM_Pulse = 0x00000000; + TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct->TIM_OCNPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct->TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct->TIM_OCNIdleState = TIM_OCNIdleState_Reset; +} + +/** + * @brief Selects the TIM Output Compare Mode. + * @note This function disables the selected channel before changing the Output + * Compare Mode. If needed, user has to enable this channel using + * TIM_CCxCmd() and TIM_CCxNCmd() functions. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @param TIM_OCMode: specifies the TIM Output Compare Mode. + * This parameter can be one of the following values: + * @arg TIM_OCMode_Timing + * @arg TIM_OCMode_Active + * @arg TIM_OCMode_Toggle + * @arg TIM_OCMode_PWM1 + * @arg TIM_OCMode_PWM2 + * @arg TIM_ForcedAction_Active + * @arg TIM_ForcedAction_InActive + * @retval None + */ +void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode) +{ + uint32_t tmp = 0; + uint16_t tmp1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_CHANNEL(TIM_Channel)); + assert_param(IS_TIM_OCM(TIM_OCMode)); + + tmp = (uint32_t) TIMx; + tmp += CCMR_OFFSET; + + tmp1 = CCER_CCE_SET << (uint16_t)TIM_Channel; + + /* Disable the Channel: Reset the CCxE Bit */ + TIMx->CCER &= (uint16_t) ~tmp1; + + if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) + { + tmp += (TIM_Channel>>1); + + /* Reset the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp &= CCMR_OC13M_MASK; + + /* Configure the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp |= TIM_OCMode; + } + else + { + tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1; + + /* Reset the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp &= CCMR_OC24M_MASK; + + /* Configure the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8); + } +} + +/** + * @brief Sets the TIMx Capture Compare1 Register value + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param Compare1: specifies the Capture Compare1 register new value. + * @retval None + */ +void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + + /* Set the Capture Compare1 Register value */ + TIMx->CCR1 = Compare1; +} + +/** + * @brief Sets the TIMx Capture Compare2 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param Compare2: specifies the Capture Compare2 register new value. + * @retval None + */ +void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Set the Capture Compare2 Register value */ + TIMx->CCR2 = Compare2; +} + +/** + * @brief Sets the TIMx Capture Compare3 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param Compare3: specifies the Capture Compare3 register new value. + * @retval None + */ +void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Set the Capture Compare3 Register value */ + TIMx->CCR3 = Compare3; +} + +/** + * @brief Sets the TIMx Capture Compare4 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param Compare4: specifies the Capture Compare4 register new value. + * @retval None + */ +void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Set the Capture Compare4 Register value */ + TIMx->CCR4 = Compare4; +} + +/** + * @brief Forces the TIMx output 1 waveform to active or inactive level. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC1REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF. + * @retval None + */ +void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1M Bits */ + tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1M; + + /* Configure The Forced output Mode */ + tmpccmr1 |= TIM_ForcedAction; + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Forces the TIMx output 2 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC2REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF. + * @retval None + */ +void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2M Bits */ + tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC2M; + + /* Configure The Forced output Mode */ + tmpccmr1 |= (uint16_t)(TIM_ForcedAction << 8); + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Forces the TIMx output 3 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC3REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF. + * @retval None + */ +void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC1M Bits */ + tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3M; + + /* Configure The Forced output Mode */ + tmpccmr2 |= TIM_ForcedAction; + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Forces the TIMx output 4 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC4REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF. + * @retval None + */ +void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC2M Bits */ + tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC4M; + + /* Configure The Forced output Mode */ + tmpccmr2 |= (uint16_t)(TIM_ForcedAction << 8); + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR1. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1PE Bit */ + tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC1PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr1 |= TIM_OCPreload; + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR2. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2PE Bit */ + tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC2PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr1 |= (uint16_t)(TIM_OCPreload << 8); + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR3. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC3PE Bit */ + tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC3PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr2 |= TIM_OCPreload; + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR4. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC4PE Bit */ + tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC4PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr2 |= (uint16_t)(TIM_OCPreload << 8); + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx Output Compare 1 Fast feature. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1FE Bit */ + tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1FE; + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr1 |= TIM_OCFast; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Configures the TIMx Output Compare 2 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2FE Bit */ + tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC2FE); + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr1 |= (uint16_t)(TIM_OCFast << 8); + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Configures the TIMx Output Compare 3 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC3FE Bit */ + tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3FE; + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr2 |= TIM_OCFast; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx Output Compare 4 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC4FE Bit */ + tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC4FE); + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr2 |= (uint16_t)(TIM_OCFast << 8); + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Clears or safeguards the OCREF1 signal on an external event + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1CE Bit */ + tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1CE; + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr1 |= TIM_OCClear; + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Clears or safeguards the OCREF2 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2CE Bit */ + tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC2CE; + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr1 |= (uint16_t)(TIM_OCClear << 8); + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Clears or safeguards the OCREF3 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC3CE Bit */ + tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3CE; + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr2 |= TIM_OCClear; + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Clears or safeguards the OCREF4 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC4CE Bit */ + tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC4CE; + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr2 |= (uint16_t)(TIM_OCClear << 8); + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx channel 1 polarity. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC1 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC1P Bit */ + tmpccer &= (uint16_t)(~TIM_CCER_CC1P); + tmpccer |= TIM_OCPolarity; + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 1N polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC1N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) +{ + uint16_t tmpccer = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC1NP Bit */ + tmpccer &= (uint16_t)~TIM_CCER_CC1NP; + tmpccer |= TIM_OCNPolarity; + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 2 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_OCPolarity: specifies the OC2 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC2P Bit */ + tmpccer &= (uint16_t)(~TIM_CCER_CC2P); + tmpccer |= (uint16_t)(TIM_OCPolarity << 4); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 2N polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC2N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC2NP Bit */ + tmpccer &= (uint16_t)~TIM_CCER_CC2NP; + tmpccer |= (uint16_t)(TIM_OCNPolarity << 4); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 3 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC3 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC3P Bit */ + tmpccer &= (uint16_t)~TIM_CCER_CC3P; + tmpccer |= (uint16_t)(TIM_OCPolarity << 8); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 3N polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC3N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC3NP Bit */ + tmpccer &= (uint16_t)~TIM_CCER_CC3NP; + tmpccer |= (uint16_t)(TIM_OCNPolarity << 8); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 4 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC4 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC4P Bit */ + tmpccer &= (uint16_t)~TIM_CCER_CC4P; + tmpccer |= (uint16_t)(TIM_OCPolarity << 12); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel x. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @param TIM_CCx: specifies the TIM Channel CCxE bit new state. + * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable. + * @retval None + */ +void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx) +{ + uint16_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_CHANNEL(TIM_Channel)); + assert_param(IS_TIM_CCX(TIM_CCx)); + + tmp = CCER_CCE_SET << TIM_Channel; + + /* Reset the CCxE Bit */ + TIMx->CCER &= (uint16_t)~ tmp; + + /* Set or reset the CCxE Bit */ + TIMx->CCER |= (uint16_t)(TIM_CCx << TIM_Channel); +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel xN. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @param TIM_CCxN: specifies the TIM Channel CCxNE bit new state. + * This parameter can be: TIM_CCxN_Enable or TIM_CCxN_Disable. + * @retval None + */ +void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN) +{ + uint16_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_COMPLEMENTARY_CHANNEL(TIM_Channel)); + assert_param(IS_TIM_CCXN(TIM_CCxN)); + + tmp = CCER_CCNE_SET << TIM_Channel; + + /* Reset the CCxNE Bit */ + TIMx->CCER &= (uint16_t) ~tmp; + + /* Set or reset the CCxNE Bit */ + TIMx->CCER |= (uint16_t)(TIM_CCxN << TIM_Channel); +} +/** + * @} + */ + +/** @defgroup TIM_Group3 Input Capture management functions + * @brief Input Capture management functions + * +@verbatim + =============================================================================== + Input Capture management functions + =============================================================================== + + =================================================================== + TIM Driver: how to use it in Input Capture Mode + =================================================================== + To use the Timer in Input Capture mode, the following steps are mandatory: + + 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function + + 2. Configure the TIM pins by configuring the corresponding GPIO pins + + 2. Configure the Time base unit as described in the first part of this driver, + if needed, else the Timer will run with the default configuration: + - Autoreload value = 0xFFFF + - Prescaler value = 0x0000 + - Counter mode = Up counting + - Clock Division = TIM_CKD_DIV1 + + 3. Fill the TIM_ICInitStruct with the desired parameters including: + - TIM Channel: TIM_Channel + - TIM Input Capture polarity: TIM_ICPolarity + - TIM Input Capture selection: TIM_ICSelection + - TIM Input Capture Prescaler: TIM_ICPrescaler + - TIM Input CApture filter value: TIM_ICFilter + + 4. Call TIM_ICInit(TIMx, &TIM_ICInitStruct) to configure the desired channel with the + corresponding configuration and to measure only frequency or duty cycle of the input signal, + or, + Call TIM_PWMIConfig(TIMx, &TIM_ICInitStruct) to configure the desired channels with the + corresponding configuration and to measure the frequency and the duty cycle of the input signal + + 5. Enable the NVIC or the DMA to read the measured frequency. + + 6. Enable the corresponding interrupt (or DMA request) to read the Captured value, + using the function TIM_ITConfig(TIMx, TIM_IT_CCx) (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)) + + 7. Call the TIM_Cmd(ENABLE) function to enable the TIM counter. + + 8. Use TIM_GetCapturex(TIMx); to read the captured value. + + Note1: All other functions can be used separately to modify, if needed, + a specific feature of the Timer. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the TIM peripheral according to the specified parameters + * in the TIM_ICInitStruct. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity)); + assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler)); + assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter)); + + if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) + { + /* TI1 Configuration */ + TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2) + { + /* TI2 Configuration */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3) + { + /* TI3 Configuration */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + TI3_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else + { + /* TI4 Configuration */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } +} + +/** + * @brief Fills each TIM_ICInitStruct member with its default value. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure which will + * be initialized. + * @retval None + */ +void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + /* Set the default configuration */ + TIM_ICInitStruct->TIM_Channel = TIM_Channel_1; + TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising; + TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI; + TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1; + TIM_ICInitStruct->TIM_ICFilter = 0x00; +} + +/** + * @brief Configures the TIM peripheral according to the specified parameters + * in the TIM_ICInitStruct to measure an external PWM signal. + * @param TIMx: where x can be 1, 2, 3, 4, 5,8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + uint16_t icoppositepolarity = TIM_ICPolarity_Rising; + uint16_t icoppositeselection = TIM_ICSelection_DirectTI; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Select the Opposite Input Polarity */ + if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising) + { + icoppositepolarity = TIM_ICPolarity_Falling; + } + else + { + icoppositepolarity = TIM_ICPolarity_Rising; + } + /* Select the Opposite Input */ + if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI) + { + icoppositeselection = TIM_ICSelection_IndirectTI; + } + else + { + icoppositeselection = TIM_ICSelection_DirectTI; + } + if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) + { + /* TI1 Configuration */ + TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + /* TI2 Configuration */ + TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else + { + /* TI2 Configuration */ + TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + /* TI1 Configuration */ + TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } +} + +/** + * @brief Gets the TIMx Input Capture 1 value. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @retval Capture Compare 1 Register value. + */ +uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + + /* Get the Capture 1 Register value */ + return TIMx->CCR1; +} + +/** + * @brief Gets the TIMx Input Capture 2 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @retval Capture Compare 2 Register value. + */ +uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Get the Capture 2 Register value */ + return TIMx->CCR2; +} + +/** + * @brief Gets the TIMx Input Capture 3 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @retval Capture Compare 3 Register value. + */ +uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Get the Capture 3 Register value */ + return TIMx->CCR3; +} + +/** + * @brief Gets the TIMx Input Capture 4 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @retval Capture Compare 4 Register value. + */ +uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Get the Capture 4 Register value */ + return TIMx->CCR4; +} + +/** + * @brief Sets the TIMx Input Capture 1 prescaler. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture1 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC1PSC Bits */ + TIMx->CCMR1 &= (uint16_t)~TIM_CCMR1_IC1PSC; + + /* Set the IC1PSC value */ + TIMx->CCMR1 |= TIM_ICPSC; +} + +/** + * @brief Sets the TIMx Input Capture 2 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_ICPSC: specifies the Input Capture2 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC2PSC Bits */ + TIMx->CCMR1 &= (uint16_t)~TIM_CCMR1_IC2PSC; + + /* Set the IC2PSC value */ + TIMx->CCMR1 |= (uint16_t)(TIM_ICPSC << 8); +} + +/** + * @brief Sets the TIMx Input Capture 3 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture3 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC3PSC Bits */ + TIMx->CCMR2 &= (uint16_t)~TIM_CCMR2_IC3PSC; + + /* Set the IC3PSC value */ + TIMx->CCMR2 |= TIM_ICPSC; +} + +/** + * @brief Sets the TIMx Input Capture 4 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture4 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC4PSC Bits */ + TIMx->CCMR2 &= (uint16_t)~TIM_CCMR2_IC4PSC; + + /* Set the IC4PSC value */ + TIMx->CCMR2 |= (uint16_t)(TIM_ICPSC << 8); +} +/** + * @} + */ + +/** @defgroup TIM_Group4 Advanced-control timers (TIM1 and TIM8) specific features + * @brief Advanced-control timers (TIM1 and TIM8) specific features + * +@verbatim + =============================================================================== + Advanced-control timers (TIM1 and TIM8) specific features + =============================================================================== + + =================================================================== + TIM Driver: how to use the Break feature + =================================================================== + After configuring the Timer channel(s) in the appropriate Output Compare mode: + + 1. Fill the TIM_BDTRInitStruct with the desired parameters for the Timer + Break Polarity, dead time, Lock level, the OSSI/OSSR State and the + AOE(automatic output enable). + + 2. Call TIM_BDTRConfig(TIMx, &TIM_BDTRInitStruct) to configure the Timer + + 3. Enable the Main Output using TIM_CtrlPWMOutputs(TIM1, ENABLE) + + 4. Once the break even occurs, the Timer's output signals are put in reset + state or in a known state (according to the configuration made in + TIM_BDTRConfig() function). + +@endverbatim + * @{ + */ + +/** + * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State + * and the AOE(automatic output enable). + * @param TIMx: where x can be 1 or 8 to select the TIM + * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure that + * contains the BDTR Register configuration information for the TIM peripheral. + * @retval None + */ +void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OSSR_STATE(TIM_BDTRInitStruct->TIM_OSSRState)); + assert_param(IS_TIM_OSSI_STATE(TIM_BDTRInitStruct->TIM_OSSIState)); + assert_param(IS_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->TIM_LOCKLevel)); + assert_param(IS_TIM_BREAK_STATE(TIM_BDTRInitStruct->TIM_Break)); + assert_param(IS_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->TIM_BreakPolarity)); + assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_AutomaticOutput)); + + /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State, + the OSSI State, the dead time value and the Automatic Output Enable Bit */ + TIMx->BDTR = (uint32_t)TIM_BDTRInitStruct->TIM_OSSRState | TIM_BDTRInitStruct->TIM_OSSIState | + TIM_BDTRInitStruct->TIM_LOCKLevel | TIM_BDTRInitStruct->TIM_DeadTime | + TIM_BDTRInitStruct->TIM_Break | TIM_BDTRInitStruct->TIM_BreakPolarity | + TIM_BDTRInitStruct->TIM_AutomaticOutput; +} + +/** + * @brief Fills each TIM_BDTRInitStruct member with its default value. + * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure which + * will be initialized. + * @retval None + */ +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct) +{ + /* Set the default configuration */ + TIM_BDTRInitStruct->TIM_OSSRState = TIM_OSSRState_Disable; + TIM_BDTRInitStruct->TIM_OSSIState = TIM_OSSIState_Disable; + TIM_BDTRInitStruct->TIM_LOCKLevel = TIM_LOCKLevel_OFF; + TIM_BDTRInitStruct->TIM_DeadTime = 0x00; + TIM_BDTRInitStruct->TIM_Break = TIM_Break_Disable; + TIM_BDTRInitStruct->TIM_BreakPolarity = TIM_BreakPolarity_Low; + TIM_BDTRInitStruct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; +} + +/** + * @brief Enables or disables the TIM peripheral Main Outputs. + * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral. + * @param NewState: new state of the TIM peripheral Main Outputs. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TIM Main Output */ + TIMx->BDTR |= TIM_BDTR_MOE; + } + else + { + /* Disable the TIM Main Output */ + TIMx->BDTR &= (uint16_t)~TIM_BDTR_MOE; + } +} + +/** + * @brief Selects the TIM peripheral Commutation event. + * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral + * @param NewState: new state of the Commutation event. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the COM Bit */ + TIMx->CR2 |= TIM_CR2_CCUS; + } + else + { + /* Reset the COM Bit */ + TIMx->CR2 &= (uint16_t)~TIM_CR2_CCUS; + } +} + +/** + * @brief Sets or Resets the TIM peripheral Capture Compare Preload Control bit. + * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral + * @param NewState: new state of the Capture Compare Preload Control bit + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Set the CCPC Bit */ + TIMx->CR2 |= TIM_CR2_CCPC; + } + else + { + /* Reset the CCPC Bit */ + TIMx->CR2 &= (uint16_t)~TIM_CR2_CCPC; + } +} +/** + * @} + */ + +/** @defgroup TIM_Group5 Interrupts DMA and flags management functions + * @brief Interrupts, DMA and flags management functions + * +@verbatim + =============================================================================== + Interrupts, DMA and flags management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified TIM interrupts. + * @param TIMx: where x can be 1 to 14 to select the TIMx peripheral. + * @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * + * @note For TIM6 and TIM7 only the parameter TIM_IT_Update can be used + * @note For TIM9 and TIM12 only one of the following parameters can be used: TIM_IT_Update, + * TIM_IT_CC1, TIM_IT_CC2 or TIM_IT_Trigger. + * @note For TIM10, TIM11, TIM13 and TIM14 only one of the following parameters can + * be used: TIM_IT_Update or TIM_IT_CC1 + * @note TIM_IT_COM and TIM_IT_Break can be used only with TIM1 and TIM8 + * + * @param NewState: new state of the TIM interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_IT(TIM_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Interrupt sources */ + TIMx->DIER |= TIM_IT; + } + else + { + /* Disable the Interrupt sources */ + TIMx->DIER &= (uint16_t)~TIM_IT; + } +} + +/** + * @brief Configures the TIMx event to be generate by software. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_EventSource: specifies the event source. + * This parameter can be one or more of the following values: + * @arg TIM_EventSource_Update: Timer update Event source + * @arg TIM_EventSource_CC1: Timer Capture Compare 1 Event source + * @arg TIM_EventSource_CC2: Timer Capture Compare 2 Event source + * @arg TIM_EventSource_CC3: Timer Capture Compare 3 Event source + * @arg TIM_EventSource_CC4: Timer Capture Compare 4 Event source + * @arg TIM_EventSource_COM: Timer COM event source + * @arg TIM_EventSource_Trigger: Timer Trigger Event source + * @arg TIM_EventSource_Break: Timer Break event source + * + * @note TIM6 and TIM7 can only generate an update event. + * @note TIM_EventSource_COM and TIM_EventSource_Break are used only with TIM1 and TIM8. + * + * @retval None + */ +void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource)); + + /* Set the event sources */ + TIMx->EGR = TIM_EventSource; +} + +/** + * @brief Checks whether the specified TIM flag is set or not. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg TIM_FLAG_Update: TIM update Flag + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag + * @arg TIM_FLAG_COM: TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break: TIM Break Flag + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 over capture Flag + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 over capture Flag + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 over capture Flag + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 over capture Flag + * + * @note TIM6 and TIM7 can have only one update flag. + * @note TIM_FLAG_COM and TIM_FLAG_Break are used only with TIM1 and TIM8. + * + * @retval The new state of TIM_FLAG (SET or RESET). + */ +FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) +{ + ITStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_GET_FLAG(TIM_FLAG)); + + + if ((TIMx->SR & TIM_FLAG) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the TIMx's pending flags. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_FLAG: specifies the flag bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_FLAG_Update: TIM update Flag + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag + * @arg TIM_FLAG_COM: TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break: TIM Break Flag + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 over capture Flag + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 over capture Flag + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 over capture Flag + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 over capture Flag + * + * @note TIM6 and TIM7 can have only one update flag. + * @note TIM_FLAG_COM and TIM_FLAG_Break are used only with TIM1 and TIM8. + * + * @retval None + */ +void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Clear the flags */ + TIMx->SR = (uint16_t)~TIM_FLAG; +} + +/** + * @brief Checks whether the TIM interrupt has occurred or not. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_IT: specifies the TIM interrupt source to check. + * This parameter can be one of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * + * @note TIM6 and TIM7 can generate only an update interrupt. + * @note TIM_IT_COM and TIM_IT_Break are used only with TIM1 and TIM8. + * + * @retval The new state of the TIM_IT(SET or RESET). + */ +ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT) +{ + ITStatus bitstatus = RESET; + uint16_t itstatus = 0x0, itenable = 0x0; + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_GET_IT(TIM_IT)); + + itstatus = TIMx->SR & TIM_IT; + + itenable = TIMx->DIER & TIM_IT; + if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the TIMx's interrupt pending bits. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_IT: specifies the pending bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM1 update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * + * @note TIM6 and TIM7 can generate only an update interrupt. + * @note TIM_IT_COM and TIM_IT_Break are used only with TIM1 and TIM8. + * + * @retval None + */ +void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Clear the IT pending Bit */ + TIMx->SR = (uint16_t)~TIM_IT; +} + +/** + * @brief Configures the TIMx's DMA interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_DMABase: DMA Base address. + * This parameter can be one of the following values: + * @arg TIM_DMABase_CR1 + * @arg TIM_DMABase_CR2 + * @arg TIM_DMABase_SMCR + * @arg TIM_DMABase_DIER + * @arg TIM1_DMABase_SR + * @arg TIM_DMABase_EGR + * @arg TIM_DMABase_CCMR1 + * @arg TIM_DMABase_CCMR2 + * @arg TIM_DMABase_CCER + * @arg TIM_DMABase_CNT + * @arg TIM_DMABase_PSC + * @arg TIM_DMABase_ARR + * @arg TIM_DMABase_RCR + * @arg TIM_DMABase_CCR1 + * @arg TIM_DMABase_CCR2 + * @arg TIM_DMABase_CCR3 + * @arg TIM_DMABase_CCR4 + * @arg TIM_DMABase_BDTR + * @arg TIM_DMABase_DCR + * @param TIM_DMABurstLength: DMA Burst length. This parameter can be one value + * between: TIM_DMABurstLength_1Transfer and TIM_DMABurstLength_18Transfers. + * @retval None + */ +void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_DMA_BASE(TIM_DMABase)); + assert_param(IS_TIM_DMA_LENGTH(TIM_DMABurstLength)); + + /* Set the DMA Base and the DMA Burst Length */ + TIMx->DCR = TIM_DMABase | TIM_DMABurstLength; +} + +/** + * @brief Enables or disables the TIMx's DMA Requests. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the TIM peripheral. + * @param TIM_DMASource: specifies the DMA Request sources. + * This parameter can be any combination of the following values: + * @arg TIM_DMA_Update: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_Trigger: TIM Trigger DMA source + * @param NewState: new state of the DMA Request sources. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_DMA_SOURCE(TIM_DMASource)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DMA sources */ + TIMx->DIER |= TIM_DMASource; + } + else + { + /* Disable the DMA sources */ + TIMx->DIER &= (uint16_t)~TIM_DMASource; + } +} + +/** + * @brief Selects the TIMx peripheral Capture Compare DMA source. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param NewState: new state of the Capture Compare DMA source + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the CCDS Bit */ + TIMx->CR2 |= TIM_CR2_CCDS; + } + else + { + /* Reset the CCDS Bit */ + TIMx->CR2 &= (uint16_t)~TIM_CR2_CCDS; + } +} +/** + * @} + */ + +/** @defgroup TIM_Group6 Clocks management functions + * @brief Clocks management functions + * +@verbatim + =============================================================================== + Clocks management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the TIMx internal Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @retval None + */ +void TIM_InternalClockConfig(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Disable slave mode to clock the prescaler directly with the internal clock */ + TIMx->SMCR &= (uint16_t)~TIM_SMCR_SMS; +} + +/** + * @brief Configures the TIMx Internal Trigger as External Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_InputTriggerSource: Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @retval None + */ +void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource)); + + /* Select the Internal Trigger */ + TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource); + + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the TIMx Trigger as External Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIM peripheral. + * @param TIM_TIxExternalCLKSource: Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector + * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1 + * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2 + * @param TIM_ICPolarity: specifies the TIx Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @param ICFilter: specifies the filter value. + * This parameter must be a value between 0x0 and 0xF. + * @retval None + */ +void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, + uint16_t TIM_ICPolarity, uint16_t ICFilter) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity)); + assert_param(IS_TIM_IC_FILTER(ICFilter)); + + /* Configure the Timer Input Clock Source */ + if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2) + { + TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); + } + else + { + TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); + } + /* Select the Trigger source */ + TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource); + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the External clock Mode1 + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + uint16_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + + /* Reset the SMS Bits */ + tmpsmcr &= (uint16_t)~TIM_SMCR_SMS; + + /* Select the External clock mode1 */ + tmpsmcr |= TIM_SlaveMode_External1; + + /* Select the Trigger selection : ETRF */ + tmpsmcr &= (uint16_t)~TIM_SMCR_TS; + tmpsmcr |= TIM_TS_ETRF; + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Configures the External clock Mode2 + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + + /* Enable the External clock mode2 */ + TIMx->SMCR |= TIM_SMCR_ECE; +} +/** + * @} + */ + +/** @defgroup TIM_Group7 Synchronization management functions + * @brief Synchronization management functions + * +@verbatim + =============================================================================== + Synchronization management functions + =============================================================================== + + =================================================================== + TIM Driver: how to use it in synchronization Mode + =================================================================== + Case of two/several Timers + ************************** + 1. Configure the Master Timers using the following functions: + - void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); + - void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode); + 2. Configure the Slave Timers using the following functions: + - void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); + - void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); + + Case of Timers and external trigger(ETR pin) + ******************************************** + 1. Configure the External trigger using this function: + - void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter); + 2. Configure the Slave Timers using the following functions: + - void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); + - void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); + +@endverbatim + * @{ + */ + +/** + * @brief Selects the Input Trigger source + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIM peripheral. + * @param TIM_InputTriggerSource: The Input Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @arg TIM_TS_TI1F_ED: TI1 Edge Detector + * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 + * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 + * @arg TIM_TS_ETRF: External Trigger input + * @retval None + */ +void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) +{ + uint16_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource)); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + + /* Reset the TS Bits */ + tmpsmcr &= (uint16_t)~TIM_SMCR_TS; + + /* Set the Input Trigger source */ + tmpsmcr |= TIM_InputTriggerSource; + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Selects the TIMx Trigger Output Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the TIM peripheral. + * + * @param TIM_TRGOSource: specifies the Trigger Output source. + * This parameter can be one of the following values: + * + * - For all TIMx + * @arg TIM_TRGOSource_Reset: The UG bit in the TIM_EGR register is used as the trigger output(TRGO) + * @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output(TRGO) + * @arg TIM_TRGOSource_Update: The update event is selected as the trigger output(TRGO) + * + * - For all TIMx except TIM6 and TIM7 + * @arg TIM_TRGOSource_OC1: The trigger output sends a positive pulse when the CC1IF flag + * is to be set, as soon as a capture or compare match occurs(TRGO) + * @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output(TRGO) + * @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output(TRGO) + * @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output(TRGO) + * @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output(TRGO) + * + * @retval None + */ +void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource)); + + /* Reset the MMS Bits */ + TIMx->CR2 &= (uint16_t)~TIM_CR2_MMS; + /* Select the TRGO source */ + TIMx->CR2 |= TIM_TRGOSource; +} + +/** + * @brief Selects the TIMx Slave Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral. + * @param TIM_SlaveMode: specifies the Timer Slave Mode. + * This parameter can be one of the following values: + * @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal(TRGI) reinitialize + * the counter and triggers an update of the registers + * @arg TIM_SlaveMode_Gated: The counter clock is enabled when the trigger signal (TRGI) is high + * @arg TIM_SlaveMode_Trigger: The counter starts at a rising edge of the trigger TRGI + * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter + * @retval None + */ +void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode)); + + /* Reset the SMS Bits */ + TIMx->SMCR &= (uint16_t)~TIM_SMCR_SMS; + + /* Select the Slave Mode */ + TIMx->SMCR |= TIM_SlaveMode; +} + +/** + * @brief Sets or Resets the TIMx Master/Slave Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral. + * @param TIM_MasterSlaveMode: specifies the Timer Master Slave Mode. + * This parameter can be one of the following values: + * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer + * and its slaves (through TRGO) + * @arg TIM_MasterSlaveMode_Disable: No action + * @retval None + */ +void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode)); + + /* Reset the MSM Bit */ + TIMx->SMCR &= (uint16_t)~TIM_SMCR_MSM; + + /* Set or Reset the MSM Bit */ + TIMx->SMCR |= TIM_MasterSlaveMode; +} + +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + uint16_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + + tmpsmcr = TIMx->SMCR; + + /* Reset the ETR Bits */ + tmpsmcr &= SMCR_ETR_MASK; + + /* Set the Prescaler, the Filter value and the Polarity */ + tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8))); + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} +/** + * @} + */ + +/** @defgroup TIM_Group8 Specific interface management functions + * @brief Specific interface management functions + * +@verbatim + =============================================================================== + Specific interface management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the TIMx Encoder Interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_EncoderMode: specifies the TIMx Encoder Mode. + * This parameter can be one of the following values: + * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level. + * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level. + * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending + * on the level of the other input. + * @param TIM_IC1Polarity: specifies the IC1 Polarity + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @param TIM_IC2Polarity: specifies the IC2 Polarity + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @retval None + */ +void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, + uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity) +{ + uint16_t tmpsmcr = 0; + uint16_t tmpccmr1 = 0; + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode)); + assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity)); + assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity)); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Set the encoder Mode */ + tmpsmcr &= (uint16_t)~TIM_SMCR_SMS; + tmpsmcr |= TIM_EncoderMode; + + /* Select the Capture Compare 1 and the Capture Compare 2 as input */ + tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR1_CC2S); + tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; + + /* Set the TI1 and the TI2 Polarities */ + tmpccer &= ((uint16_t)~TIM_CCER_CC1P) & ((uint16_t)~TIM_CCER_CC2P); + tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4)); + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Enables or disables the TIMx's Hall sensor interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param NewState: new state of the TIMx Hall sensor interface. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the TI1S Bit */ + TIMx->CR2 |= TIM_CR2_TI1S; + } + else + { + /* Reset the TI1S Bit */ + TIMx->CR2 &= (uint16_t)~TIM_CR2_TI1S; + } +} +/** + * @} + */ + +/** @defgroup TIM_Group9 Specific remapping management function + * @brief Specific remapping management function + * +@verbatim + =============================================================================== + Specific remapping management function + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the TIM2, TIM5 and TIM11 Remapping input capabilities. + * @param TIMx: where x can be 2, 5 or 11 to select the TIM peripheral. + * @param TIM_Remap: specifies the TIM input remapping source. + * This parameter can be one of the following values: + * @arg TIM2_TIM8_TRGO: TIM2 ITR1 input is connected to TIM8 Trigger output(default) + * @arg TIM2_ETH_PTP: TIM2 ITR1 input is connected to ETH PTP trogger output. + * @arg TIM2_USBFS_SOF: TIM2 ITR1 input is connected to USB FS SOF. + * @arg TIM2_USBHS_SOF: TIM2 ITR1 input is connected to USB HS SOF. + * @arg TIM5_GPIO: TIM5 CH4 input is connected to dedicated Timer pin(default) + * @arg TIM5_LSI: TIM5 CH4 input is connected to LSI clock. + * @arg TIM5_LSE: TIM5 CH4 input is connected to LSE clock. + * @arg TIM5_RTC: TIM5 CH4 input is connected to RTC Output event. + * @arg TIM11_GPIO: TIM11 CH4 input is connected to dedicated Timer pin(default) + * @arg TIM11_HSE: TIM11 CH4 input is connected to HSE_RTC clock + * (HSE divided by a programmable prescaler) + * @retval None + */ +void TIM_RemapConfig(TIM_TypeDef* TIMx, uint16_t TIM_Remap) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_REMAP(TIM_Remap)); + + /* Set the Timer remapping configuration */ + TIMx->OR = TIM_Remap; +} +/** + * @} + */ + +/** + * @brief Configure the TI1 as Input. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1. + * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2. + * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr1 = 0, tmpccer = 0; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC1E; + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + + /* Select the Input and set the filter */ + tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR1_IC1F); + tmpccmr1 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); + + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= (uint16_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP); + tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI2 as Input. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2. + * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1. + * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr1 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC2E; + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 4); + + /* Select the Input and set the filter */ + tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC2S) & ((uint16_t)~TIM_CCMR1_IC2F); + tmpccmr1 |= (uint16_t)(TIM_ICFilter << 12); + tmpccmr1 |= (uint16_t)(TIM_ICSelection << 8); + + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= (uint16_t)~(TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC2E); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI3 as Input. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3. + * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4. + * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC3E; + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 8); + + /* Select the Input and set the filter */ + tmpccmr2 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR2_IC3F); + tmpccmr2 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); + + /* Select the Polarity and set the CC3E Bit */ + tmpccer &= (uint16_t)~(TIM_CCER_CC3P | TIM_CCER_CC3NP); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC3E); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI4 as Input. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4. + * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3. + * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC4E; + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 12); + + /* Select the Input and set the filter */ + tmpccmr2 &= ((uint16_t)~TIM_CCMR1_CC2S) & ((uint16_t)~TIM_CCMR1_IC2F); + tmpccmr2 |= (uint16_t)(TIM_ICSelection << 8); + tmpccmr2 |= (uint16_t)(TIM_ICFilter << 12); + + /* Select the Polarity and set the CC4E Bit */ + tmpccer &= (uint16_t)~(TIM_CCER_CC4P | TIM_CCER_CC4NP); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC4E); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer ; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c new file mode 100644 index 0000000..1bb99ad --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c @@ -0,0 +1,1463 @@ +/** + ****************************************************************************** + * @file stm32f4xx_usart.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Universal synchronous asynchronous receiver + * transmitter (USART): + * - Initialization and Configuration + * - Data transfers + * - Multi-Processor Communication + * - LIN mode + * - Half-duplex mode + * - Smartcard mode + * - IrDA mode + * - DMA transfers management + * - Interrupts and flags management + * + * @verbatim + * + * =================================================================== + * How to use this driver + * =================================================================== + * 1. Enable peripheral clock using the follwoing functions + * RCC_APB2PeriphClockCmd(RCC_APB2Periph_USARTx, ENABLE) for USART1 and USART6 + * RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) for USART2, USART3, UART4 or UART5. + * + * 2. According to the USART mode, enable the GPIO clocks using + * RCC_AHB1PeriphClockCmd() function. (The I/O can be TX, RX, CTS, + * or/and SCLK). + * + * 3. Peripheral's alternate function: + * - Connect the pin to the desired peripherals' Alternate + * Function (AF) using GPIO_PinAFConfig() function + * - Configure the desired pin in alternate function by: + * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF + * - Select the type, pull-up/pull-down and output speed via + * GPIO_PuPd, GPIO_OType and GPIO_Speed members + * - Call GPIO_Init() function + * + * 4. Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware + * flow control and Mode(Receiver/Transmitter) using the USART_Init() + * function. + * + * 5. For synchronous mode, enable the clock and program the polarity, + * phase and last bit using the USART_ClockInit() function. + * + * 5. Enable the NVIC and the corresponding interrupt using the function + * USART_ITConfig() if you need to use interrupt mode. + * + * 6. When using the DMA mode + * - Configure the DMA using DMA_Init() function + * - Active the needed channel Request using USART_DMACmd() function + * + * 7. Enable the USART using the USART_Cmd() function. + * + * 8. Enable the DMA using the DMA_Cmd() function, when using DMA mode. + * + * Refer to Multi-Processor, LIN, half-duplex, Smartcard, IrDA sub-sections + * for more details + * + * In order to reach higher communication baudrates, it is possible to + * enable the oversampling by 8 mode using the function USART_OverSampling8Cmd(). + * This function should be called after enabling the USART clock (RCC_APBxPeriphClockCmd()) + * and before calling the function USART_Init(). + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_usart.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup USART + * @brief USART driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/*!< USART CR1 register clear Mask ((~(uint16_t)0xE9F3)) */ +#define CR1_CLEAR_MASK ((uint16_t)(USART_CR1_M | USART_CR1_PCE | \ + USART_CR1_PS | USART_CR1_TE | \ + USART_CR1_RE)) + +/*!< USART CR2 register clock bits clear Mask ((~(uint16_t)0xF0FF)) */ +#define CR2_CLOCK_CLEAR_MASK ((uint16_t)(USART_CR2_CLKEN | USART_CR2_CPOL | \ + USART_CR2_CPHA | USART_CR2_LBCL)) + +/*!< USART CR3 register clear Mask ((~(uint16_t)0xFCFF)) */ +#define CR3_CLEAR_MASK ((uint16_t)(USART_CR3_RTSE | USART_CR3_CTSE)) + +/*!< USART Interrupts mask */ +#define IT_MASK ((uint16_t)0x001F) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup USART_Private_Functions + * @{ + */ + +/** @defgroup USART_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + Initialization and Configuration functions + =============================================================================== + + This subsection provides a set of functions allowing to initialize the USART + in asynchronous and in synchronous modes. + - For the asynchronous mode only these parameters can be configured: + - Baud Rate + - Word Length + - Stop Bit + - Parity: If the parity is enabled, then the MSB bit of the data written + in the data register is transmitted but is changed by the parity bit. + Depending on the frame length defined by the M bit (8-bits or 9-bits), + the possible USART frame formats are as listed in the following table: + +-------------------------------------------------------------+ + | M bit | PCE bit | USART frame | + |---------------------|---------------------------------------| + | 0 | 0 | | SB | 8 bit data | STB | | + |---------|-----------|---------------------------------------| + | 0 | 1 | | SB | 7 bit data | PB | STB | | + |---------|-----------|---------------------------------------| + | 1 | 0 | | SB | 9 bit data | STB | | + |---------|-----------|---------------------------------------| + | 1 | 1 | | SB | 8 bit data | PB | STB | | + +-------------------------------------------------------------+ + - Hardware flow control + - Receiver/transmitter modes + + The USART_Init() function follows the USART asynchronous configuration procedure + (details for the procedure are available in reference manual (RM0090)). + + - For the synchronous mode in addition to the asynchronous mode parameters these + parameters should be also configured: + - USART Clock Enabled + - USART polarity + - USART phase + - USART LastBit + + These parameters can be configured using the USART_ClockInit() function. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the USARTx peripheral registers to their default reset values. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @retval None + */ +void USART_DeInit(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + if (USARTx == USART1) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); + } + else if (USARTx == USART2) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE); + } + else if (USARTx == USART3) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE); + } + else if (USARTx == UART4) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE); + } + else if (USARTx == UART5) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE); + } + else + { + if (USARTx == USART6) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, DISABLE); + } + } +} + +/** + * @brief Initializes the USARTx peripheral according to the specified + * parameters in the USART_InitStruct . + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_InitStruct: pointer to a USART_InitTypeDef structure that contains + * the configuration information for the specified USART peripheral. + * @retval None + */ +void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) +{ + uint32_t tmpreg = 0x00, apbclock = 0x00; + uint32_t integerdivider = 0x00; + uint32_t fractionaldivider = 0x00; + RCC_ClocksTypeDef RCC_ClocksStatus; + + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate)); + assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength)); + assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits)); + assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity)); + assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode)); + assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl)); + + /* The hardware flow control is available only for USART1, USART2, USART3 and USART6 */ + if (USART_InitStruct->USART_HardwareFlowControl != USART_HardwareFlowControl_None) + { + assert_param(IS_USART_1236_PERIPH(USARTx)); + } + +/*---------------------------- USART CR2 Configuration -----------------------*/ + tmpreg = USARTx->CR2; + + /* Clear STOP[13:12] bits */ + tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP); + + /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit : + Set STOP[13:12] bits according to USART_StopBits value */ + tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits; + + /* Write to USART CR2 */ + USARTx->CR2 = (uint16_t)tmpreg; + +/*---------------------------- USART CR1 Configuration -----------------------*/ + tmpreg = USARTx->CR1; + + /* Clear M, PCE, PS, TE and RE bits */ + tmpreg &= (uint32_t)~((uint32_t)CR1_CLEAR_MASK); + + /* Configure the USART Word Length, Parity and mode: + Set the M bits according to USART_WordLength value + Set PCE and PS bits according to USART_Parity value + Set TE and RE bits according to USART_Mode value */ + tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity | + USART_InitStruct->USART_Mode; + + /* Write to USART CR1 */ + USARTx->CR1 = (uint16_t)tmpreg; + +/*---------------------------- USART CR3 Configuration -----------------------*/ + tmpreg = USARTx->CR3; + + /* Clear CTSE and RTSE bits */ + tmpreg &= (uint32_t)~((uint32_t)CR3_CLEAR_MASK); + + /* Configure the USART HFC : + Set CTSE and RTSE bits according to USART_HardwareFlowControl value */ + tmpreg |= USART_InitStruct->USART_HardwareFlowControl; + + /* Write to USART CR3 */ + USARTx->CR3 = (uint16_t)tmpreg; + +/*---------------------------- USART BRR Configuration -----------------------*/ + /* Configure the USART Baud Rate */ + RCC_GetClocksFreq(&RCC_ClocksStatus); + + if ((USARTx == USART1) || (USARTx == USART6)) + { + apbclock = RCC_ClocksStatus.PCLK2_Frequency; + } + else + { + apbclock = RCC_ClocksStatus.PCLK1_Frequency; + } + + /* Determine the integer part */ + if ((USARTx->CR1 & USART_CR1_OVER8) != 0) + { + /* Integer part computing in case Oversampling mode is 8 Samples */ + integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate))); + } + else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ + { + /* Integer part computing in case Oversampling mode is 16 Samples */ + integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate))); + } + tmpreg = (integerdivider / 100) << 4; + + /* Determine the fractional part */ + fractionaldivider = integerdivider - (100 * (tmpreg >> 4)); + + /* Implement the fractional part in the register */ + if ((USARTx->CR1 & USART_CR1_OVER8) != 0) + { + tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07); + } + else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ + { + tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F); + } + + /* Write to USART BRR register */ + USARTx->BRR = (uint16_t)tmpreg; +} + +/** + * @brief Fills each USART_InitStruct member with its default value. + * @param USART_InitStruct: pointer to a USART_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void USART_StructInit(USART_InitTypeDef* USART_InitStruct) +{ + /* USART_InitStruct members default value */ + USART_InitStruct->USART_BaudRate = 9600; + USART_InitStruct->USART_WordLength = USART_WordLength_8b; + USART_InitStruct->USART_StopBits = USART_StopBits_1; + USART_InitStruct->USART_Parity = USART_Parity_No ; + USART_InitStruct->USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None; +} + +/** + * @brief Initializes the USARTx peripheral Clock according to the + * specified parameters in the USART_ClockInitStruct . + * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART peripheral. + * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef structure that + * contains the configuration information for the specified USART peripheral. + * @note The Smart Card and Synchronous modes are not available for UART4 and UART5. + * @retval None + */ +void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct) +{ + uint32_t tmpreg = 0x00; + /* Check the parameters */ + assert_param(IS_USART_1236_PERIPH(USARTx)); + assert_param(IS_USART_CLOCK(USART_ClockInitStruct->USART_Clock)); + assert_param(IS_USART_CPOL(USART_ClockInitStruct->USART_CPOL)); + assert_param(IS_USART_CPHA(USART_ClockInitStruct->USART_CPHA)); + assert_param(IS_USART_LASTBIT(USART_ClockInitStruct->USART_LastBit)); + +/*---------------------------- USART CR2 Configuration -----------------------*/ + tmpreg = USARTx->CR2; + /* Clear CLKEN, CPOL, CPHA and LBCL bits */ + tmpreg &= (uint32_t)~((uint32_t)CR2_CLOCK_CLEAR_MASK); + /* Configure the USART Clock, CPOL, CPHA and LastBit ------------*/ + /* Set CLKEN bit according to USART_Clock value */ + /* Set CPOL bit according to USART_CPOL value */ + /* Set CPHA bit according to USART_CPHA value */ + /* Set LBCL bit according to USART_LastBit value */ + tmpreg |= (uint32_t)USART_ClockInitStruct->USART_Clock | USART_ClockInitStruct->USART_CPOL | + USART_ClockInitStruct->USART_CPHA | USART_ClockInitStruct->USART_LastBit; + /* Write to USART CR2 */ + USARTx->CR2 = (uint16_t)tmpreg; +} + +/** + * @brief Fills each USART_ClockInitStruct member with its default value. + * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef structure + * which will be initialized. + * @retval None + */ +void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct) +{ + /* USART_ClockInitStruct members default value */ + USART_ClockInitStruct->USART_Clock = USART_Clock_Disable; + USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low; + USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge; + USART_ClockInitStruct->USART_LastBit = USART_LastBit_Disable; +} + +/** + * @brief Enables or disables the specified USART peripheral. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param NewState: new state of the USARTx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected USART by setting the UE bit in the CR1 register */ + USARTx->CR1 |= USART_CR1_UE; + } + else + { + /* Disable the selected USART by clearing the UE bit in the CR1 register */ + USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_UE); + } +} + +/** + * @brief Sets the system clock prescaler. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_Prescaler: specifies the prescaler clock. + * @note The function is used for IrDA mode with UART4 and UART5. + * @retval None + */ +void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Clear the USART prescaler */ + USARTx->GTPR &= USART_GTPR_GT; + /* Set the USART prescaler */ + USARTx->GTPR |= USART_Prescaler; +} + +/** + * @brief Enables or disables the USART's 8x oversampling mode. + * @note This function has to be called before calling USART_Init() function + * in order to have correct baudrate Divider value. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param NewState: new state of the USART 8x oversampling mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the 8x Oversampling mode by setting the OVER8 bit in the CR1 register */ + USARTx->CR1 |= USART_CR1_OVER8; + } + else + { + /* Disable the 8x Oversampling mode by clearing the OVER8 bit in the CR1 register */ + USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_OVER8); + } +} + +/** + * @brief Enables or disables the USART's one bit sampling method. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param NewState: new state of the USART one bit sampling method. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the one bit method by setting the ONEBITE bit in the CR3 register */ + USARTx->CR3 |= USART_CR3_ONEBIT; + } + else + { + /* Disable the one bit method by clearing the ONEBITE bit in the CR3 register */ + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT); + } +} + +/** + * @} + */ + +/** @defgroup USART_Group2 Data transfers functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + Data transfers functions + =============================================================================== + + This subsection provides a set of functions allowing to manage the USART data + transfers. + + During an USART reception, data shifts in least significant bit first through + the RX pin. In this mode, the USART_DR register consists of a buffer (RDR) + between the internal bus and the received shift register. + + When a transmission is taking place, a write instruction to the USART_DR register + stores the data in the TDR register and which is copied in the shift register + at the end of the current transmission. + + The read access of the USART_DR register can be done using the USART_ReceiveData() + function and returns the RDR buffered value. Whereas a write access to the USART_DR + can be done using USART_SendData() function and stores the written data into + TDR buffer. + +@endverbatim + * @{ + */ + +/** + * @brief Transmits single data through the USARTx peripheral. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param Data: the data to transmit. + * @retval None + */ +void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_DATA(Data)); + + /* Transmit Data */ + USARTx->DR = (Data & (uint16_t)0x01FF); +} + +/** + * @brief Returns the most recent received data by the USARTx peripheral. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @retval The received data. + */ +uint16_t USART_ReceiveData(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Receive Data */ + return (uint16_t)(USARTx->DR & (uint16_t)0x01FF); +} + +/** + * @} + */ + +/** @defgroup USART_Group3 MultiProcessor Communication functions + * @brief Multi-Processor Communication functions + * +@verbatim + =============================================================================== + Multi-Processor Communication functions + =============================================================================== + + This subsection provides a set of functions allowing to manage the USART + multiprocessor communication. + + For instance one of the USARTs can be the master, its TX output is connected to + the RX input of the other USART. The others are slaves, their respective TX outputs + are logically ANDed together and connected to the RX input of the master. + + USART multiprocessor communication is possible through the following procedure: + 1. Program the Baud rate, Word length = 9 bits, Stop bits, Parity, Mode transmitter + or Mode receiver and hardware flow control values using the USART_Init() + function. + 2. Configures the USART address using the USART_SetAddress() function. + 3. Configures the wake up method (USART_WakeUp_IdleLine or USART_WakeUp_AddressMark) + using USART_WakeUpConfig() function only for the slaves. + 4. Enable the USART using the USART_Cmd() function. + 5. Enter the USART slaves in mute mode using USART_ReceiverWakeUpCmd() function. + + The USART Slave exit from mute mode when receive the wake up condition. + +@endverbatim + * @{ + */ + +/** + * @brief Sets the address of the USART node. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_Address: Indicates the address of the USART node. + * @retval None + */ +void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_ADDRESS(USART_Address)); + + /* Clear the USART address */ + USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_ADD); + /* Set the USART address node */ + USARTx->CR2 |= USART_Address; +} + +/** + * @brief Determines if the USART is in mute mode or not. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param NewState: new state of the USART mute mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the USART mute mode by setting the RWU bit in the CR1 register */ + USARTx->CR1 |= USART_CR1_RWU; + } + else + { + /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */ + USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_RWU); + } +} +/** + * @brief Selects the USART WakeUp method. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_WakeUp: specifies the USART wakeup method. + * This parameter can be one of the following values: + * @arg USART_WakeUp_IdleLine: WakeUp by an idle line detection + * @arg USART_WakeUp_AddressMark: WakeUp by an address mark + * @retval None + */ +void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_WAKEUP(USART_WakeUp)); + + USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_WAKE); + USARTx->CR1 |= USART_WakeUp; +} + +/** + * @} + */ + +/** @defgroup USART_Group4 LIN mode functions + * @brief LIN mode functions + * +@verbatim + =============================================================================== + LIN mode functions + =============================================================================== + + This subsection provides a set of functions allowing to manage the USART LIN + Mode communication. + + In LIN mode, 8-bit data format with 1 stop bit is required in accordance with + the LIN standard. + + Only this LIN Feature is supported by the USART IP: + - LIN Master Synchronous Break send capability and LIN slave break detection + capability : 13-bit break generation and 10/11 bit break detection + + + USART LIN Master transmitter communication is possible through the following procedure: + 1. Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity, + Mode transmitter or Mode receiver and hardware flow control values using + the USART_Init() function. + 2. Enable the USART using the USART_Cmd() function. + 3. Enable the LIN mode using the USART_LINCmd() function. + 4. Send the break character using USART_SendBreak() function. + + USART LIN Master receiver communication is possible through the following procedure: + 1. Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity, + Mode transmitter or Mode receiver and hardware flow control values using + the USART_Init() function. + 2. Enable the USART using the USART_Cmd() function. + 3. Configures the break detection length using the USART_LINBreakDetectLengthConfig() + function. + 4. Enable the LIN mode using the USART_LINCmd() function. + + +@note In LIN mode, the following bits must be kept cleared: + - CLKEN in the USART_CR2 register, + - STOP[1:0], SCEN, HDSEL and IREN in the USART_CR3 register. + +@endverbatim + * @{ + */ + +/** + * @brief Sets the USART LIN Break detection length. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_LINBreakDetectLength: specifies the LIN break detection length. + * This parameter can be one of the following values: + * @arg USART_LINBreakDetectLength_10b: 10-bit break detection + * @arg USART_LINBreakDetectLength_11b: 11-bit break detection + * @retval None + */ +void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_LIN_BREAK_DETECT_LENGTH(USART_LINBreakDetectLength)); + + USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_LBDL); + USARTx->CR2 |= USART_LINBreakDetectLength; +} + +/** + * @brief Enables or disables the USART's LIN mode. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param NewState: new state of the USART LIN mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ + USARTx->CR2 |= USART_CR2_LINEN; + } + else + { + /* Disable the LIN mode by clearing the LINEN bit in the CR2 register */ + USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_LINEN); + } +} + +/** + * @brief Transmits break characters. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @retval None + */ +void USART_SendBreak(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Send break characters */ + USARTx->CR1 |= USART_CR1_SBK; +} + +/** + * @} + */ + +/** @defgroup USART_Group5 Halfduplex mode function + * @brief Half-duplex mode function + * +@verbatim + =============================================================================== + Half-duplex mode function + =============================================================================== + + This subsection provides a set of functions allowing to manage the USART + Half-duplex communication. + + The USART can be configured to follow a single-wire half-duplex protocol where + the TX and RX lines are internally connected. + + USART Half duplex communication is possible through the following procedure: + 1. Program the Baud rate, Word length, Stop bits, Parity, Mode transmitter + or Mode receiver and hardware flow control values using the USART_Init() + function. + 2. Configures the USART address using the USART_SetAddress() function. + 3. Enable the USART using the USART_Cmd() function. + 4. Enable the half duplex mode using USART_HalfDuplexCmd() function. + + +@note The RX pin is no longer used +@note In Half-duplex mode the following bits must be kept cleared: + - LINEN and CLKEN bits in the USART_CR2 register. + - SCEN and IREN bits in the USART_CR3 register. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the USART's Half Duplex communication. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param NewState: new state of the USART Communication. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ + USARTx->CR3 |= USART_CR3_HDSEL; + } + else + { + /* Disable the Half-Duplex mode by clearing the HDSEL bit in the CR3 register */ + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_HDSEL); + } +} + +/** + * @} + */ + + +/** @defgroup USART_Group6 Smartcard mode functions + * @brief Smartcard mode functions + * +@verbatim + =============================================================================== + Smartcard mode functions + =============================================================================== + + This subsection provides a set of functions allowing to manage the USART + Smartcard communication. + + The Smartcard interface is designed to support asynchronous protocol Smartcards as + defined in the ISO 7816-3 standard. + + The USART can provide a clock to the smartcard through the SCLK output. + In smartcard mode, SCLK is not associated to the communication but is simply derived + from the internal peripheral input clock through a 5-bit prescaler. + + Smartcard communication is possible through the following procedure: + 1. Configures the Smartcard Prescaler using the USART_SetPrescaler() function. + 2. Configures the Smartcard Guard Time using the USART_SetGuardTime() function. + 3. Program the USART clock using the USART_ClockInit() function as following: + - USART Clock enabled + - USART CPOL Low + - USART CPHA on first edge + - USART Last Bit Clock Enabled + 4. Program the Smartcard interface using the USART_Init() function as following: + - Word Length = 9 Bits + - 1.5 Stop Bit + - Even parity + - BaudRate = 12096 baud + - Hardware flow control disabled (RTS and CTS signals) + - Tx and Rx enabled + 5. Optionally you can enable the parity error interrupt using the USART_ITConfig() + function + 6. Enable the USART using the USART_Cmd() function. + 7. Enable the Smartcard NACK using the USART_SmartCardNACKCmd() function. + 8. Enable the Smartcard interface using the USART_SmartCardCmd() function. + + Please refer to the ISO 7816-3 specification for more details. + + +@note It is also possible to choose 0.5 stop bit for receiving but it is recommended + to use 1.5 stop bits for both transmitting and receiving to avoid switching + between the two configurations. +@note In smartcard mode, the following bits must be kept cleared: + - LINEN bit in the USART_CR2 register. + - HDSEL and IREN bits in the USART_CR3 register. +@note Smartcard mode is available on USART peripherals only (not available on UART4 + and UART5 peripherals). + +@endverbatim + * @{ + */ + +/** + * @brief Sets the specified USART guard time. + * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART or + * UART peripheral. + * @param USART_GuardTime: specifies the guard time. + * @retval None + */ +void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime) +{ + /* Check the parameters */ + assert_param(IS_USART_1236_PERIPH(USARTx)); + + /* Clear the USART Guard time */ + USARTx->GTPR &= USART_GTPR_PSC; + /* Set the USART guard time */ + USARTx->GTPR |= (uint16_t)((uint16_t)USART_GuardTime << 0x08); +} + +/** + * @brief Enables or disables the USART's Smart Card mode. + * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART or + * UART peripheral. + * @param NewState: new state of the Smart Card mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_1236_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the SC mode by setting the SCEN bit in the CR3 register */ + USARTx->CR3 |= USART_CR3_SCEN; + } + else + { + /* Disable the SC mode by clearing the SCEN bit in the CR3 register */ + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_SCEN); + } +} + +/** + * @brief Enables or disables NACK transmission. + * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART or + * UART peripheral. + * @param NewState: new state of the NACK transmission. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_1236_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the NACK transmission by setting the NACK bit in the CR3 register */ + USARTx->CR3 |= USART_CR3_NACK; + } + else + { + /* Disable the NACK transmission by clearing the NACK bit in the CR3 register */ + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_NACK); + } +} + +/** + * @} + */ + +/** @defgroup USART_Group7 IrDA mode functions + * @brief IrDA mode functions + * +@verbatim + =============================================================================== + IrDA mode functions + =============================================================================== + + This subsection provides a set of functions allowing to manage the USART + IrDA communication. + + IrDA is a half duplex communication protocol. If the Transmitter is busy, any data + on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver + is busy, data on the TX from the USART to IrDA will not be encoded by IrDA. + While receiving data, transmission should be avoided as the data to be transmitted + could be corrupted. + + IrDA communication is possible through the following procedure: + 1. Program the Baud rate, Word length = 8 bits, Stop bits, Parity, Transmitter/Receiver + modes and hardware flow control values using the USART_Init() function. + 2. Enable the USART using the USART_Cmd() function. + 3. Configures the IrDA pulse width by configuring the prescaler using + the USART_SetPrescaler() function. + 4. Configures the IrDA USART_IrDAMode_LowPower or USART_IrDAMode_Normal mode + using the USART_IrDAConfig() function. + 5. Enable the IrDA using the USART_IrDACmd() function. + +@note A pulse of width less than two and greater than one PSC period(s) may or may + not be rejected. +@note The receiver set up time should be managed by software. The IrDA physical layer + specification specifies a minimum of 10 ms delay between transmission and + reception (IrDA is a half duplex protocol). +@note In IrDA mode, the following bits must be kept cleared: + - LINEN, STOP and CLKEN bits in the USART_CR2 register. + - SCEN and HDSEL bits in the USART_CR3 register. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the USART's IrDA interface. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_IrDAMode: specifies the IrDA mode. + * This parameter can be one of the following values: + * @arg USART_IrDAMode_LowPower + * @arg USART_IrDAMode_Normal + * @retval None + */ +void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_IRDA_MODE(USART_IrDAMode)); + + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_IRLP); + USARTx->CR3 |= USART_IrDAMode; +} + +/** + * @brief Enables or disables the USART's IrDA interface. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param NewState: new state of the IrDA mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the IrDA mode by setting the IREN bit in the CR3 register */ + USARTx->CR3 |= USART_CR3_IREN; + } + else + { + /* Disable the IrDA mode by clearing the IREN bit in the CR3 register */ + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_IREN); + } +} + +/** + * @} + */ + +/** @defgroup USART_Group8 DMA transfers management functions + * @brief DMA transfers management functions + * +@verbatim + =============================================================================== + DMA transfers management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the USART's DMA interface. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_DMAReq: specifies the DMA request. + * This parameter can be any combination of the following values: + * @arg USART_DMAReq_Tx: USART DMA transmit request + * @arg USART_DMAReq_Rx: USART DMA receive request + * @param NewState: new state of the DMA Request sources. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_DMAREQ(USART_DMAReq)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DMA transfer for selected requests by setting the DMAT and/or + DMAR bits in the USART CR3 register */ + USARTx->CR3 |= USART_DMAReq; + } + else + { + /* Disable the DMA transfer for selected requests by clearing the DMAT and/or + DMAR bits in the USART CR3 register */ + USARTx->CR3 &= (uint16_t)~USART_DMAReq; + } +} + +/** + * @} + */ + +/** @defgroup USART_Group9 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + + This subsection provides a set of functions allowing to configure the USART + Interrupts sources, DMA channels requests and check or clear the flags or + pending bits status. + The user should identify which mode will be used in his application to manage + the communication: Polling mode, Interrupt mode or DMA mode. + + Polling Mode + ============= + In Polling Mode, the SPI communication can be managed by 10 flags: + 1. USART_FLAG_TXE : to indicate the status of the transmit buffer register + 2. USART_FLAG_RXNE : to indicate the status of the receive buffer register + 3. USART_FLAG_TC : to indicate the status of the transmit operation + 4. USART_FLAG_IDLE : to indicate the status of the Idle Line + 5. USART_FLAG_CTS : to indicate the status of the nCTS input + 6. USART_FLAG_LBD : to indicate the status of the LIN break detection + 7. USART_FLAG_NE : to indicate if a noise error occur + 8. USART_FLAG_FE : to indicate if a frame error occur + 9. USART_FLAG_PE : to indicate if a parity error occur + 10. USART_FLAG_ORE : to indicate if an Overrun error occur + + In this Mode it is advised to use the following functions: + - FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); + - void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG); + + Interrupt Mode + =============== + In Interrupt Mode, the USART communication can be managed by 8 interrupt sources + and 10 pending bits: + + Pending Bits: + ------------- + 1. USART_IT_TXE : to indicate the status of the transmit buffer register + 2. USART_IT_RXNE : to indicate the status of the receive buffer register + 3. USART_IT_TC : to indicate the status of the transmit operation + 4. USART_IT_IDLE : to indicate the status of the Idle Line + 5. USART_IT_CTS : to indicate the status of the nCTS input + 6. USART_IT_LBD : to indicate the status of the LIN break detection + 7. USART_IT_NE : to indicate if a noise error occur + 8. USART_IT_FE : to indicate if a frame error occur + 9. USART_IT_PE : to indicate if a parity error occur + 10. USART_IT_ORE : to indicate if an Overrun error occur + + Interrupt Source: + ----------------- + 1. USART_IT_TXE : specifies the interrupt source for the Tx buffer empty + interrupt. + 2. USART_IT_RXNE : specifies the interrupt source for the Rx buffer not + empty interrupt. + 3. USART_IT_TC : specifies the interrupt source for the Transmit complete + interrupt. + 4. USART_IT_IDLE : specifies the interrupt source for the Idle Line interrupt. + 5. USART_IT_CTS : specifies the interrupt source for the CTS interrupt. + 6. USART_IT_LBD : specifies the interrupt source for the LIN break detection + interrupt. + 7. USART_IT_PE : specifies the interrupt source for the parity error interrupt. + 8. USART_IT_ERR : specifies the interrupt source for the errors interrupt. + +@note Some parameters are coded in order to use them as interrupt source or as pending bits. + + In this Mode it is advised to use the following functions: + - void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); + - ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); + - void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); + + DMA Mode + ======== + In DMA Mode, the USART communication can be managed by 2 DMA Channel requests: + 1. USART_DMAReq_Tx: specifies the Tx buffer DMA transfer request + 2. USART_DMAReq_Rx: specifies the Rx buffer DMA transfer request + + In this Mode it is advised to use the following function: + - void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState); + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified USART interrupts. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_IT: specifies the USART interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg USART_IT_CTS: CTS change interrupt + * @arg USART_IT_LBD: LIN Break detection interrupt + * @arg USART_IT_TXE: Transmit Data Register empty interrupt + * @arg USART_IT_TC: Transmission complete interrupt + * @arg USART_IT_RXNE: Receive Data register not empty interrupt + * @arg USART_IT_IDLE: Idle line detection interrupt + * @arg USART_IT_PE: Parity Error interrupt + * @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * @param NewState: new state of the specified USARTx interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState) +{ + uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00; + uint32_t usartxbase = 0x00; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CONFIG_IT(USART_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* The CTS interrupt is not available for UART4 and UART5 */ + if (USART_IT == USART_IT_CTS) + { + assert_param(IS_USART_1236_PERIPH(USARTx)); + } + + usartxbase = (uint32_t)USARTx; + + /* Get the USART register index */ + usartreg = (((uint8_t)USART_IT) >> 0x05); + + /* Get the interrupt position */ + itpos = USART_IT & IT_MASK; + itmask = (((uint32_t)0x01) << itpos); + + if (usartreg == 0x01) /* The IT is in CR1 register */ + { + usartxbase += 0x0C; + } + else if (usartreg == 0x02) /* The IT is in CR2 register */ + { + usartxbase += 0x10; + } + else /* The IT is in CR3 register */ + { + usartxbase += 0x14; + } + if (NewState != DISABLE) + { + *(__IO uint32_t*)usartxbase |= itmask; + } + else + { + *(__IO uint32_t*)usartxbase &= ~itmask; + } +} + +/** + * @brief Checks whether the specified USART flag is set or not. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5) + * @arg USART_FLAG_LBD: LIN Break detection flag + * @arg USART_FLAG_TXE: Transmit data register empty flag + * @arg USART_FLAG_TC: Transmission Complete flag + * @arg USART_FLAG_RXNE: Receive data register not empty flag + * @arg USART_FLAG_IDLE: Idle Line detection flag + * @arg USART_FLAG_ORE: OverRun Error flag + * @arg USART_FLAG_NE: Noise Error flag + * @arg USART_FLAG_FE: Framing Error flag + * @arg USART_FLAG_PE: Parity Error flag + * @retval The new state of USART_FLAG (SET or RESET). + */ +FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_FLAG(USART_FLAG)); + + /* The CTS flag is not available for UART4 and UART5 */ + if (USART_FLAG == USART_FLAG_CTS) + { + assert_param(IS_USART_1236_PERIPH(USARTx)); + } + + if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the USARTx's pending flags. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5). + * @arg USART_FLAG_LBD: LIN Break detection flag. + * @arg USART_FLAG_TC: Transmission Complete flag. + * @arg USART_FLAG_RXNE: Receive data register not empty flag. + * + * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun + * error) and IDLE (Idle line detected) flags are cleared by software + * sequence: a read operation to USART_SR register (USART_GetFlagStatus()) + * followed by a read operation to USART_DR register (USART_ReceiveData()). + * @note RXNE flag can be also cleared by a read to the USART_DR register + * (USART_ReceiveData()). + * @note TC flag can be also cleared by software sequence: a read operation to + * USART_SR register (USART_GetFlagStatus()) followed by a write operation + * to USART_DR register (USART_SendData()). + * @note TXE flag is cleared only by a write to the USART_DR register + * (USART_SendData()). + * + * @retval None + */ +void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CLEAR_FLAG(USART_FLAG)); + + /* The CTS flag is not available for UART4 and UART5 */ + if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS) + { + assert_param(IS_USART_1236_PERIPH(USARTx)); + } + + USARTx->SR = (uint16_t)~USART_FLAG; +} + +/** + * @brief Checks whether the specified USART interrupt has occurred or not. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_IT: specifies the USART interrupt source to check. + * This parameter can be one of the following values: + * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) + * @arg USART_IT_LBD: LIN Break detection interrupt + * @arg USART_IT_TXE: Transmit Data Register empty interrupt + * @arg USART_IT_TC: Transmission complete interrupt + * @arg USART_IT_RXNE: Receive Data register not empty interrupt + * @arg USART_IT_IDLE: Idle line detection interrupt + * @arg USART_IT_ORE_RX : OverRun Error interrupt if the RXNEIE bit is set + * @arg USART_IT_ORE_ER : OverRun Error interrupt if the EIE bit is set + * @arg USART_IT_NE: Noise Error interrupt + * @arg USART_IT_FE: Framing Error interrupt + * @arg USART_IT_PE: Parity Error interrupt + * @retval The new state of USART_IT (SET or RESET). + */ +ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT) +{ + uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00; + ITStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_GET_IT(USART_IT)); + + /* The CTS interrupt is not available for UART4 and UART5 */ + if (USART_IT == USART_IT_CTS) + { + assert_param(IS_USART_1236_PERIPH(USARTx)); + } + + /* Get the USART register index */ + usartreg = (((uint8_t)USART_IT) >> 0x05); + /* Get the interrupt position */ + itmask = USART_IT & IT_MASK; + itmask = (uint32_t)0x01 << itmask; + + if (usartreg == 0x01) /* The IT is in CR1 register */ + { + itmask &= USARTx->CR1; + } + else if (usartreg == 0x02) /* The IT is in CR2 register */ + { + itmask &= USARTx->CR2; + } + else /* The IT is in CR3 register */ + { + itmask &= USARTx->CR3; + } + + bitpos = USART_IT >> 0x08; + bitpos = (uint32_t)0x01 << bitpos; + bitpos &= USARTx->SR; + if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + + return bitstatus; +} + +/** + * @brief Clears the USARTx's interrupt pending bits. + * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or + * UART peripheral. + * @param USART_IT: specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) + * @arg USART_IT_LBD: LIN Break detection interrupt + * @arg USART_IT_TC: Transmission complete interrupt. + * @arg USART_IT_RXNE: Receive Data register not empty interrupt. + * + * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun + * error) and IDLE (Idle line detected) pending bits are cleared by + * software sequence: a read operation to USART_SR register + * (USART_GetITStatus()) followed by a read operation to USART_DR register + * (USART_ReceiveData()). + * @note RXNE pending bit can be also cleared by a read to the USART_DR register + * (USART_ReceiveData()). + * @note TC pending bit can be also cleared by software sequence: a read + * operation to USART_SR register (USART_GetITStatus()) followed by a write + * operation to USART_DR register (USART_SendData()). + * @note TXE pending bit is cleared only by a write to the USART_DR register + * (USART_SendData()). + * + * @retval None + */ +void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT) +{ + uint16_t bitpos = 0x00, itmask = 0x00; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CLEAR_IT(USART_IT)); + + /* The CTS interrupt is not available for UART4 and UART5 */ + if (USART_IT == USART_IT_CTS) + { + assert_param(IS_USART_1236_PERIPH(USARTx)); + } + + bitpos = USART_IT >> 0x08; + itmask = ((uint16_t)0x01 << (uint16_t)bitpos); + USARTx->SR = (uint16_t)~itmask; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_wwdg.c b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_wwdg.c new file mode 100644 index 0000000..816a92d --- /dev/null +++ b/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_wwdg.c @@ -0,0 +1,303 @@ +/** + ****************************************************************************** + * @file stm32f4xx_wwdg.c + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief This file provides firmware functions to manage the following + * functionalities of the Window watchdog (WWDG) peripheral: + * - Prescaler, Refresh window and Counter configuration + * - WWDG activation + * - Interrupts and flags management + * + * @verbatim + * + * =================================================================== + * WWDG features + * =================================================================== + * + * Once enabled the WWDG generates a system reset on expiry of a programmed + * time period, unless the program refreshes the counter (downcounter) + * before to reach 0x3F value (i.e. a reset is generated when the counter + * value rolls over from 0x40 to 0x3F). + * An MCU reset is also generated if the counter value is refreshed + * before the counter has reached the refresh window value. This + * implies that the counter must be refreshed in a limited window. + * + * Once enabled the WWDG cannot be disabled except by a system reset. + * + * WWDGRST flag in RCC_CSR register can be used to inform when a WWDG + * reset occurs. + * + * The WWDG counter input clock is derived from the APB clock divided + * by a programmable prescaler. + * + * WWDG counter clock = PCLK1 / Prescaler + * WWDG timeout = (WWDG counter clock) * (counter value) + * + * Min-max timeout value @42 MHz(PCLK1): ~97.5 us / ~49.9 ms + * + * =================================================================== + * How to use this driver + * =================================================================== + * 1. Enable WWDG clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE) function + * + * 2. Configure the WWDG prescaler using WWDG_SetPrescaler() function + * + * 3. Configure the WWDG refresh window using WWDG_SetWindowValue() function + * + * 4. Set the WWDG counter value and start it using WWDG_Enable() function. + * When the WWDG is enabled the counter value should be configured to + * a value greater than 0x40 to prevent generating an immediate reset. + * + * 5. Optionally you can enable the Early wakeup interrupt which is + * generated when the counter reach 0x40. + * Once enabled this interrupt cannot be disabled except by a system reset. + * + * 6. Then the application program must refresh the WWDG counter at regular + * intervals during normal operation to prevent an MCU reset, using + * WWDG_SetCounter() function. This operation must occur only when + * the counter value is lower than the refresh window value, + * programmed using WWDG_SetWindowValue(). + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_wwdg.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup WWDG + * @brief WWDG driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* ----------- WWDG registers bit address in the alias region ----------- */ +#define WWDG_OFFSET (WWDG_BASE - PERIPH_BASE) +/* Alias word address of EWI bit */ +#define CFR_OFFSET (WWDG_OFFSET + 0x04) +#define EWI_BitNumber 0x09 +#define CFR_EWI_BB (PERIPH_BB_BASE + (CFR_OFFSET * 32) + (EWI_BitNumber * 4)) + +/* --------------------- WWDG registers bit mask ------------------------ */ +/* CFR register bit mask */ +#define CFR_WDGTB_MASK ((uint32_t)0xFFFFFE7F) +#define CFR_W_MASK ((uint32_t)0xFFFFFF80) +#define BIT_MASK ((uint8_t)0x7F) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup WWDG_Private_Functions + * @{ + */ + +/** @defgroup WWDG_Group1 Prescaler, Refresh window and Counter configuration functions + * @brief Prescaler, Refresh window and Counter configuration functions + * +@verbatim + =============================================================================== + Prescaler, Refresh window and Counter configuration functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the WWDG peripheral registers to their default reset values. + * @param None + * @retval None + */ +void WWDG_DeInit(void) +{ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE); +} + +/** + * @brief Sets the WWDG Prescaler. + * @param WWDG_Prescaler: specifies the WWDG Prescaler. + * This parameter can be one of the following values: + * @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1 + * @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2 + * @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4 + * @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8 + * @retval None + */ +void WWDG_SetPrescaler(uint32_t WWDG_Prescaler) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler)); + /* Clear WDGTB[1:0] bits */ + tmpreg = WWDG->CFR & CFR_WDGTB_MASK; + /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */ + tmpreg |= WWDG_Prescaler; + /* Store the new value */ + WWDG->CFR = tmpreg; +} + +/** + * @brief Sets the WWDG window value. + * @param WindowValue: specifies the window value to be compared to the downcounter. + * This parameter value must be lower than 0x80. + * @retval None + */ +void WWDG_SetWindowValue(uint8_t WindowValue) +{ + __IO uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_WWDG_WINDOW_VALUE(WindowValue)); + /* Clear W[6:0] bits */ + + tmpreg = WWDG->CFR & CFR_W_MASK; + + /* Set W[6:0] bits according to WindowValue value */ + tmpreg |= WindowValue & (uint32_t) BIT_MASK; + + /* Store the new value */ + WWDG->CFR = tmpreg; +} + +/** + * @brief Enables the WWDG Early Wakeup interrupt(EWI). + * @note Once enabled this interrupt cannot be disabled except by a system reset. + * @param None + * @retval None + */ +void WWDG_EnableIT(void) +{ + *(__IO uint32_t *) CFR_EWI_BB = (uint32_t)ENABLE; +} + +/** + * @brief Sets the WWDG counter value. + * @param Counter: specifies the watchdog counter value. + * This parameter must be a number between 0x40 and 0x7F (to prevent generating + * an immediate reset) + * @retval None + */ +void WWDG_SetCounter(uint8_t Counter) +{ + /* Check the parameters */ + assert_param(IS_WWDG_COUNTER(Counter)); + /* Write to T[6:0] bits to configure the counter value, no need to do + a read-modify-write; writing a 0 to WDGA bit does nothing */ + WWDG->CR = Counter & BIT_MASK; +} +/** + * @} + */ + +/** @defgroup WWDG_Group2 WWDG activation functions + * @brief WWDG activation functions + * +@verbatim + =============================================================================== + WWDG activation function + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables WWDG and load the counter value. + * @param Counter: specifies the watchdog counter value. + * This parameter must be a number between 0x40 and 0x7F (to prevent generating + * an immediate reset) + * @retval None + */ +void WWDG_Enable(uint8_t Counter) +{ + /* Check the parameters */ + assert_param(IS_WWDG_COUNTER(Counter)); + WWDG->CR = WWDG_CR_WDGA | Counter; +} +/** + * @} + */ + +/** @defgroup WWDG_Group3 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + Interrupts and flags management functions + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Checks whether the Early Wakeup interrupt flag is set or not. + * @param None + * @retval The new state of the Early Wakeup interrupt flag (SET or RESET) + */ +FlagStatus WWDG_GetFlagStatus(void) +{ + FlagStatus bitstatus = RESET; + + if ((WWDG->SR) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears Early Wakeup interrupt flag. + * @param None + * @retval None + */ +void WWDG_ClearFlag(void) +{ + WWDG->SR = (uint32_t)RESET; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h b/Libraries/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h new file mode 100644 index 0000000..f58ff06 --- /dev/null +++ b/Libraries/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h @@ -0,0 +1,158 @@ +/** + ****************************************************************************** + * @file usbd_audio_core.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header file for the usbd_audio_core.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_req.h" +#include "usbd_ioreq.h" +#include "usbd_desc.h" + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_REQ + * @brief USB standard requests module + * @{ + */ + +/** @defgroup USBD_REQ_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Variables + * @{ + */ + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint32_t USBD_ep_status __ALIGN_END = 0; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint32_t USBD_default_cfg __ALIGN_END = 0; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint32_t USBD_cfg_status __ALIGN_END = 0; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ] __ALIGN_END ; +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_FunctionPrototypes + * @{ + */ +static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static uint8_t USBD_GetLen(uint8_t *buf); +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Functions + * @{ + */ + + +/** +* @brief USBD_StdDevReq +* Handle standard usb device requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) +{ + USBD_Status ret = USBD_OK; + + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + + USBD_GetDescriptor (pdev, req) ; + break; + + case USB_REQ_SET_ADDRESS: + USBD_SetAddress(pdev, req); + break; + + case USB_REQ_SET_CONFIGURATION: + USBD_SetConfig (pdev , req); + break; + + case USB_REQ_GET_CONFIGURATION: + USBD_GetConfig (pdev , req); + break; + + case USB_REQ_GET_STATUS: + USBD_GetStatus (pdev , req); + break; + + + case USB_REQ_SET_FEATURE: + USBD_SetFeature (pdev , req); + break; + + case USB_REQ_CLEAR_FEATURE: + USBD_ClrFeature (pdev , req); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + + return ret; +} + +/** +* @brief USBD_StdItfReq +* Handle standard usb interface requests +* @param pdev: USB OTG device instance +* @param req: usb request +* @retval status +*/ +USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) +{ + USBD_Status ret = USBD_OK; + + switch (pdev->dev.device_status) + { + case USB_OTG_CONFIGURED: + + if (LOBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) + { + pdev->dev.class_cb->Setup (pdev, req); + + if((req->wLength == 0)&& (ret == USBD_OK)) + { + USBD_CtlSendStatus(pdev); + } + } + else + { + USBD_CtlError(pdev , req); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + return ret; +} + +/** +* @brief USBD_StdEPReq +* Handle standard usb endpoint requests +* @param pdev: USB OTG device instance +* @param req: usb request +* @retval status +*/ +USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) +{ + + uint8_t ep_addr; + USBD_Status ret = USBD_OK; + + ep_addr = LOBYTE(req->wIndex); + + switch (req->bRequest) + { + + case USB_REQ_SET_FEATURE : + + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + DCD_EP_Stall(pdev , ep_addr); + } + break; + + case USB_OTG_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + DCD_EP_Stall(pdev , ep_addr); + + } + } + pdev->dev.class_cb->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + case USB_REQ_CLEAR_FEATURE : + + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + DCD_EP_Stall(pdev , ep_addr); + } + break; + + case USB_OTG_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + DCD_EP_ClrStall(pdev , ep_addr); + pdev->dev.class_cb->Setup (pdev, req); + } + USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + case USB_REQ_GET_STATUS: + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + DCD_EP_Stall(pdev , ep_addr); + } + break; + + case USB_OTG_CONFIGURED: + + + if ((ep_addr & 0x80)== 0x80) + { + if(pdev->dev.in_ep[ep_addr & 0x7F].is_stall) + { + USBD_ep_status = 0x0001; + } + else + { + USBD_ep_status = 0x0000; + } + } + else if ((ep_addr & 0x80)== 0x00) + { + if(pdev->dev.out_ep[ep_addr].is_stall) + { + USBD_ep_status = 0x0001; + } + + else + { + USBD_ep_status = 0x0000; + } + } + USBD_CtlSendData (pdev, + (uint8_t *)&USBD_ep_status, + 2); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + default: + break; + } + return ret; +} +/** +* @brief USBD_GetDescriptor +* Handle Get Descriptor requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + uint16_t len; + uint8_t *pbuf; + + switch (req->wValue >> 8) + { + case USB_DESC_TYPE_DEVICE: + pbuf = pdev->dev.usr_device->GetDeviceDescriptor(pdev->cfg.speed, &len); + if ((req->wLength == 64) ||( pdev->dev.device_status == USB_OTG_DEFAULT)) + { + len = 8; + } + break; + + case USB_DESC_TYPE_CONFIGURATION: + pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len); +#ifdef USB_OTG_HS_CORE + if((pdev->cfg.speed == USB_OTG_SPEED_FULL )&& + (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY)) + { + pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len); + } +#endif + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; + pdev->dev.pConfig_descriptor = pbuf; + break; + + case USB_DESC_TYPE_STRING: + switch ((uint8_t)(req->wValue)) + { + case USBD_IDX_LANGID_STR: + pbuf = pdev->dev.usr_device->GetLangIDStrDescriptor(pdev->cfg.speed, &len); + break; + + case USBD_IDX_MFC_STR: + pbuf = pdev->dev.usr_device->GetManufacturerStrDescriptor(pdev->cfg.speed, &len); + break; + + case USBD_IDX_PRODUCT_STR: + pbuf = pdev->dev.usr_device->GetProductStrDescriptor(pdev->cfg.speed, &len); + break; + + case USBD_IDX_SERIAL_STR: + pbuf = pdev->dev.usr_device->GetSerialStrDescriptor(pdev->cfg.speed, &len); + break; + + case USBD_IDX_CONFIG_STR: + pbuf = pdev->dev.usr_device->GetConfigurationStrDescriptor(pdev->cfg.speed, &len); + break; + + case USBD_IDX_INTERFACE_STR: + pbuf = pdev->dev.usr_device->GetInterfaceStrDescriptor(pdev->cfg.speed, &len); + break; + + default: +#ifdef USB_SUPPORT_USER_STRING_DESC + pbuf = pdev->dev.class_cb->GetUsrStrDescriptor(pdev->cfg.speed, (req->wValue) , &len); + break; +#else + USBD_CtlError(pdev , req); + return; +#endif /* USBD_CtlError(pdev , req); */ + } + break; + case USB_DESC_TYPE_DEVICE_QUALIFIER: +#ifdef USB_OTG_HS_CORE + if(pdev->cfg.speed == USB_OTG_SPEED_HIGH ) + { + + pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len); + + USBD_DeviceQualifierDesc[4]= pbuf[14]; + USBD_DeviceQualifierDesc[5]= pbuf[15]; + USBD_DeviceQualifierDesc[6]= pbuf[16]; + + pbuf = USBD_DeviceQualifierDesc; + len = USB_LEN_DEV_QUALIFIER_DESC; + break; + } + else + { + USBD_CtlError(pdev , req); + return; + } +#else + USBD_CtlError(pdev , req); + return; +#endif + + case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: +#ifdef USB_OTG_HS_CORE + + if(pdev->cfg.speed == USB_OTG_SPEED_HIGH ) + { + pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len); + pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; + break; + } + else + { + USBD_CtlError(pdev , req); + return; + } +#else + USBD_CtlError(pdev , req); + return; +#endif + + + default: + USBD_CtlError(pdev , req); + return; + } + + if((len != 0)&& (req->wLength != 0)) + { + + len = MIN(len , req->wLength); + + USBD_CtlSendData (pdev, + pbuf, + len); + } + +} + +/** +* @brief USBD_SetAddress +* Set device address +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + uint8_t dev_addr; + + if ((req->wIndex == 0) && (req->wLength == 0)) + { + dev_addr = (uint8_t)(req->wValue) & 0x7F; + + if (pdev->dev.device_status == USB_OTG_CONFIGURED) + { + USBD_CtlError(pdev , req); + } + else + { + pdev->dev.device_address = dev_addr; + DCD_EP_SetAddress(pdev, dev_addr); + USBD_CtlSendStatus(pdev); + + if (dev_addr != 0) + { + pdev->dev.device_status = USB_OTG_ADDRESSED; + } + else + { + pdev->dev.device_status = USB_OTG_DEFAULT; + } + } + } + else + { + USBD_CtlError(pdev , req); + } +} + +/** +* @brief USBD_SetConfig +* Handle Set device configuration request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + + static uint8_t cfgidx; + + cfgidx = (uint8_t)(req->wValue); + + if (cfgidx > USBD_CFG_MAX_NUM ) + { + USBD_CtlError(pdev , req); + } + else + { + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + if (cfgidx) + { + pdev->dev.device_config = cfgidx; + pdev->dev.device_status = USB_OTG_CONFIGURED; + USBD_SetCfg(pdev , cfgidx); + USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + + case USB_OTG_CONFIGURED: + if (cfgidx == 0) + { + pdev->dev.device_status = USB_OTG_ADDRESSED; + pdev->dev.device_config = cfgidx; + USBD_ClrCfg(pdev , cfgidx); + USBD_CtlSendStatus(pdev); + + } + else if (cfgidx != pdev->dev.device_config) + { + /* Clear old configuration */ + USBD_ClrCfg(pdev , pdev->dev.device_config); + + /* set new configuration */ + pdev->dev.device_config = cfgidx; + USBD_SetCfg(pdev , cfgidx); + USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + } +} + +/** +* @brief USBD_GetConfig +* Handle Get device configuration request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + + if (req->wLength != 1) + { + USBD_CtlError(pdev , req); + } + else + { + switch (pdev->dev.device_status ) + { + case USB_OTG_ADDRESSED: + + USBD_CtlSendData (pdev, + (uint8_t *)&USBD_default_cfg, + 1); + break; + + case USB_OTG_CONFIGURED: + + USBD_CtlSendData (pdev, + &pdev->dev.device_config, + 1); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + } +} + +/** +* @brief USBD_GetStatus +* Handle Get Status request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + case USB_OTG_CONFIGURED: + + if (pdev->dev.DevRemoteWakeup) + { + USBD_cfg_status = USB_CONFIG_SELF_POWERED | USB_CONFIG_REMOTE_WAKEUP; + } + else + { + USBD_cfg_status = USB_CONFIG_SELF_POWERED; + } + + USBD_CtlSendData (pdev, + (uint8_t *)&USBD_cfg_status, + 1); + break; + + default : + USBD_CtlError(pdev , req); + break; + } +} + + +/** +* @brief USBD_SetFeature +* Handle Set device feature request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + + USB_OTG_DCTL_TypeDef dctl; + uint8_t test_mode = 0; + + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev.DevRemoteWakeup = 1; + pdev->dev.class_cb->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + } + + else if ((req->wValue == USB_FEATURE_TEST_MODE) && + ((req->wIndex & 0xFF) == 0)) + { + dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); + + test_mode = req->wIndex >> 8; + switch (test_mode) + { + case 1: // TEST_J + dctl.b.tstctl = 1; + break; + + case 2: // TEST_K + dctl.b.tstctl = 2; + break; + + case 3: // TEST_SE0_NAK + dctl.b.tstctl = 3; + break; + + case 4: // TEST_PACKET + dctl.b.tstctl = 4; + break; + + case 5: // TEST_FORCE_ENABLE + dctl.b.tstctl = 5; + break; + } + USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); + USBD_CtlSendStatus(pdev); + } + +} + + +/** +* @brief USBD_ClrFeature +* Handle clear device feature request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + case USB_OTG_CONFIGURED: + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev.DevRemoteWakeup = 0; + pdev->dev.class_cb->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + } + break; + + default : + USBD_CtlError(pdev , req); + break; + } +} + +/** +* @brief USBD_ParseSetupRequest +* Copy buffer into setup structure +* @param pdev: device instance +* @param req: usb request +* @retval None +*/ + +void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + req->bmRequest = *(uint8_t *) (pdev->dev.setup_packet); + req->bRequest = *(uint8_t *) (pdev->dev.setup_packet + 1); + req->wValue = SWAPBYTE (pdev->dev.setup_packet + 2); + req->wIndex = SWAPBYTE (pdev->dev.setup_packet + 4); + req->wLength = SWAPBYTE (pdev->dev.setup_packet + 6); + + pdev->dev.in_ep[0].ctl_data_len = req->wLength ; + pdev->dev.device_state = USB_OTG_EP0_SETUP; +} + +/** +* @brief USBD_CtlError +* Handle USB low level Error +* @param pdev: device instance +* @param req: usb request +* @retval None +*/ + +void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + if((req->bmRequest & 0x80) == 0x80) + { + DCD_EP_Stall(pdev , 0x80); + } + else + { + if(req->wLength == 0) + { + DCD_EP_Stall(pdev , 0x80); + } + else + { + DCD_EP_Stall(pdev , 0); + } + } + USB_OTG_EP0_OutStart(pdev); +} + + +/** + * @brief USBD_GetString + * Convert Ascii string into unicode one + * @param desc : descriptor buffer + * @param unicode : Formatted string buffer (unicode) + * @param len : descriptor length + * @retval None + */ +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) +{ + uint8_t idx = 0; + + if (desc != NULL) + { + *len = USBD_GetLen(desc) * 2 + 2; + unicode[idx++] = *len; + unicode[idx++] = USB_DESC_TYPE_STRING; + + while (*desc != NULL) + { + unicode[idx++] = *desc++; + unicode[idx++] = 0x00; + } + } +} + +/** + * @brief USBD_GetLen + * return the string length + * @param buf : pointer to the ascii string buffer + * @retval string length + */ +static uint8_t USBD_GetLen(uint8_t *buf) +{ + uint8_t len = 0; + + while (*buf != NULL) + { + len++; + buf++; + } + + return len; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32_USB_Device_Library/Release_Notes.html b/Libraries/STM32_USB_Device_Library/Release_Notes.html new file mode 100644 index 0000000..ecb4998 --- /dev/null +++ b/Libraries/STM32_USB_Device_Library/Release_Notes.html @@ -0,0 +1,941 @@ + + + + + + + + +Release Notes for STM32F105/7xx and STM32F2xx USB Device Library + + + + + +
+ +

 

+ +
+ + + + + +
+ + + + + + + +
+

Back to Release page

+
+

Release Notes for STM32F105/7xx and STM32F2xx USB Device Library

+

Copyright + 2011 STMicroelectronics

+

+
+

 

+ + + + +
+

Contents

+
    +
  1. STM32F105/7xx and STM32F2xx USB Device Library update History
  2. +
  3. License
  4. +
+

STM32F105/7xx and STM32F2xx USB Device Library  update History

V1.0.0 / 22-July-2011

Main +Changes

+
  • First official version for STM32F105/7xx and STM32F2xx devices

+

License

+

The use of this STM32 software is governed by the terms and conditions of the License Agreement "MCD-ST Liberty SW License Agreement 20Jul2011 v0.1.pdf" available in the root of this package. 

+
+
+
+

For + complete documentation on STM32(CORTEX M3) 32-Bit + Microcontrollers visit www.st.com/STM32

+
+

+
+ +
+ +

 

+ +
+ + \ No newline at end of file diff --git a/Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_core.h b/Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_core.h new file mode 100644 index 0000000..e6d0b79 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_core.h @@ -0,0 +1,195 @@ +/** + ****************************************************************************** + * @file usbh_hid_core.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file contains all the prototypes for the usbh_hid_core.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_HID_CORE_H +#define __USBH_HID_CORE_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_core.h" +#include "usbh_stdreq.h" +#include "usb_bsp.h" +#include "usbh_ioreq.h" +#include "usbh_hcs.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_CLASS + * @{ + */ + +/** @addtogroup USBH_HID_CLASS + * @{ + */ + +/** @defgroup USBH_HID_CORE + * @brief This file is the Header file for USBH_HID_CORE.c + * @{ + */ + + +/** @defgroup USBH_HID_CORE_Exported_Types + * @{ + */ + + +/* States for HID State Machine */ +typedef enum +{ + HID_IDLE= 0, + HID_SEND_DATA, + HID_BUSY, + HID_GET_DATA, + HID_POLL, + HID_ERROR, +} +HID_State; + +typedef enum +{ + HID_REQ_IDLE = 0, + HID_REQ_GET_REPORT_DESC, + HID_REQ_GET_HID_DESC, + HID_REQ_SET_IDLE, + HID_REQ_SET_PROTOCOL, + HID_REQ_SET_REPORT, + +} +HID_CtlState; + +typedef struct HID_cb +{ + void (*Init) (void); + void (*Decode) (uint8_t *data); + +} HID_cb_TypeDef; + +typedef struct _HID_Report +{ + uint8_t ReportID; + uint8_t ReportType; + uint16_t UsagePage; + uint32_t Usage[2]; + uint32_t NbrUsage; + uint32_t UsageMin; + uint32_t UsageMax; + int32_t LogMin; + int32_t LogMax; + int32_t PhyMin; + int32_t PhyMax; + int32_t UnitExp; + uint32_t Unit; + uint32_t ReportSize; + uint32_t ReportCnt; + uint32_t Flag; + uint32_t PhyUsage; + uint32_t AppUsage; + uint32_t LogUsage; +} +HID_Report_TypeDef; + +/* Structure for HID process */ +typedef struct _HID_Process +{ + uint8_t buff[64]; + uint8_t hc_num_in; + uint8_t hc_num_out; + HID_State state; + uint8_t HIDIntOutEp; + uint8_t HIDIntInEp; + HID_CtlState ctl_state; + uint16_t length; + uint8_t ep_addr; + uint16_t poll; + __IO uint16_t timer; + HID_cb_TypeDef *cb; +} +HID_Machine_TypeDef; + +/** + * @} + */ + +/** @defgroup USBH_HID_CORE_Exported_Defines + * @{ + */ + +#define USB_HID_REQ_GET_REPORT 0x01 +#define USB_HID_GET_IDLE 0x02 +#define USB_HID_GET_PROTOCOL 0x03 +#define USB_HID_SET_REPORT 0x09 +#define USB_HID_SET_IDLE 0x0A +#define USB_HID_SET_PROTOCOL 0x0B +/** + * @} + */ + +/** @defgroup USBH_HID_CORE_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_HID_CORE_Exported_Variables + * @{ + */ +extern USBH_Class_cb_TypeDef HID_cb; +/** + * @} + */ + +/** @defgroup USBH_HID_CORE_Exported_FunctionsPrototype + * @{ + */ + +USBH_Status USBH_Set_Report (USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t reportType, + uint8_t reportId, + uint8_t reportLen, + uint8_t* reportBuff); +/** + * @} + */ + + +#endif /* __USBH_HID_CORE_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_keybd.h b/Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_keybd.h new file mode 100644 index 0000000..08f6b9f --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_keybd.h @@ -0,0 +1,122 @@ +/** + ****************************************************************************** + * @file usbh_hid_keybd.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file contains all the prototypes for the usbh_hid_keybd.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive -----------------------------------------------*/ +#ifndef __USBH_HID_KEYBD_H +#define __USBH_HID_KEYBD_H + +/* Includes ------------------------------------------------------------------*/ +#include "usb_conf.h" +#include "usbh_hid_core.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_CLASS + * @{ + */ + +/** @addtogroup USBH_HID_CLASS + * @{ + */ + +/** @defgroup USBH_HID_KEYBD + * @brief This file is the Header file for USBH_HID_KEYBD.c + * @{ + */ + + +/** @defgroup USBH_HID_KEYBD_Exported_Types + * @{ + */ + + +/** + * @} + */ + +/** @defgroup USBH_HID_KEYBD_Exported_Defines + * @{ + */ +//#define QWERTY_KEYBOARD +#define AZERTY_KEYBOARD + +#define KBD_LEFT_CTRL 0x01 +#define KBD_LEFT_SHIFT 0x02 +#define KBD_LEFT_ALT 0x04 +#define KBD_LEFT_GUI 0x08 +#define KBD_RIGHT_CTRL 0x10 +#define KBD_RIGHT_SHIFT 0x20 +#define KBD_RIGHT_ALT 0x40 +#define KBD_RIGHT_GUI 0x80 + +#define KBR_MAX_NBR_PRESSED 6 + +/** + * @} + */ + +/** @defgroup USBH_HID_KEYBD_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_HID_KEYBD_Exported_Variables + * @{ + */ + +extern HID_cb_TypeDef HID_KEYBRD_cb; +/** + * @} + */ + +/** @defgroup USBH_HID_KEYBD_Exported_FunctionsPrototype + * @{ + */ +void USR_KEYBRD_Init (void); +void USR_KEYBRD_ProcessData (uint8_t pbuf); +/** + * @} + */ + +#endif /* __USBH_HID_KEYBD_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_mouse.h b/Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_mouse.h new file mode 100644 index 0000000..eb2c2ae --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_mouse.h @@ -0,0 +1,114 @@ +/** + ****************************************************************************** + * @file usbh_hid_mouse.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file contains all the prototypes for the usbh_hid_mouse.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_HID_MOUSE_H +#define __USBH_HID_MOUSE_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_hid_core.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_CLASS + * @{ + */ + +/** @addtogroup USBH_HID_CLASS + * @{ + */ + +/** @defgroup USBH_HID_MOUSE + * @brief This file is the Header file for USBH_HID_MOUSE.c + * @{ + */ + + +/** @defgroup USBH_HID_MOUSE_Exported_Types + * @{ + */ +typedef struct _HID_MOUSE_Data +{ + uint8_t x; + uint8_t y; + uint8_t z; /* Not Supported */ + uint8_t button; +} +HID_MOUSE_Data_TypeDef; + +/** + * @} + */ + +/** @defgroup USBH_HID_MOUSE_Exported_Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_HID_MOUSE_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_HID_MOUSE_Exported_Variables + * @{ + */ + +extern HID_cb_TypeDef HID_MOUSE_cb; +extern HID_MOUSE_Data_TypeDef HID_MOUSE_Data; +/** + * @} + */ + +/** @defgroup USBH_HID_MOUSE_Exported_FunctionsPrototype + * @{ + */ +void USR_MOUSE_Init (void); +void USR_MOUSE_ProcessData (HID_MOUSE_Data_TypeDef *data); +/** + * @} + */ + +#endif /* __USBH_HID_MOUSE_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_core.c b/Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_core.c new file mode 100644 index 0000000..53cb196 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_core.c @@ -0,0 +1,640 @@ +/** + ****************************************************************************** + * @file usbh_hid_core.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file is the HID Layer Handlers for USB Host HID class. + * + * @verbatim + * + * =================================================================== + * HID Class Description + * =================================================================== + * This module manages the MSC class V1.11 following the "Device Class Definition + * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001". + * This driver implements the following aspects of the specification: + * - The Boot Interface Subclass + * - The Mouse and Keyboard protocols + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_hid_core.h" +#include "usbh_hid_mouse.h" +#include "usbh_hid_keybd.h" + +/** @addtogroup USBH_LIB +* @{ +*/ + +/** @addtogroup USBH_CLASS +* @{ +*/ + +/** @addtogroup USBH_HID_CLASS +* @{ +*/ + +/** @defgroup USBH_HID_CORE +* @brief This file includes HID Layer Handlers for USB Host HID class. +* @{ +*/ + +/** @defgroup USBH_HID_CORE_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_HID_CORE_Private_Defines +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_HID_CORE_Private_Macros +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_HID_CORE_Private_Variables +* @{ +*/ +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN HID_Machine_TypeDef HID_Machine __ALIGN_END ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN HID_Report_TypeDef HID_Report __ALIGN_END ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN USB_Setup_TypeDef HID_Setup __ALIGN_END ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN USBH_HIDDesc_TypeDef HID_Desc __ALIGN_END ; + +__IO uint8_t flag = 0; +/** +* @} +*/ + + +/** @defgroup USBH_HID_CORE_Private_FunctionPrototypes +* @{ +*/ + +static USBH_Status USBH_HID_InterfaceInit (USB_OTG_CORE_HANDLE *pdev , + void *phost); + +static void USBH_ParseHIDDesc (USBH_HIDDesc_TypeDef *desc, uint8_t *buf); + +static void USBH_HID_InterfaceDeInit (USB_OTG_CORE_HANDLE *pdev , + void *phost); + +static USBH_Status USBH_HID_Handle(USB_OTG_CORE_HANDLE *pdev , + void *phost); + +static USBH_Status USBH_HID_ClassRequest(USB_OTG_CORE_HANDLE *pdev , + void *phost); + +static USBH_Status USBH_Get_HID_ReportDescriptor (USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint16_t length); + +static USBH_Status USBH_Get_HID_Descriptor (USB_OTG_CORE_HANDLE *pdev,\ + USBH_HOST *phost, + uint16_t length); + +static USBH_Status USBH_Set_Idle (USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t duration, + uint8_t reportId); + +static USBH_Status USBH_Set_Protocol (USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t protocol); + + +USBH_Class_cb_TypeDef HID_cb = +{ + USBH_HID_InterfaceInit, + USBH_HID_InterfaceDeInit, + USBH_HID_ClassRequest, + USBH_HID_Handle +}; +/** +* @} +*/ + + +/** @defgroup USBH_HID_CORE_Private_Functions +* @{ +*/ + +/** +* @brief USBH_HID_InterfaceInit +* The function init the HID class. +* @param pdev: Selected device +* @param hdev: Selected device property +* @retval USBH_Status :Response for USB HID driver intialization +*/ +static USBH_Status USBH_HID_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev, + void *phost) +{ + uint8_t maxEP; + USBH_HOST *pphost = phost; + + uint8_t num =0; + USBH_Status status = USBH_BUSY ; + HID_Machine.state = HID_ERROR; + + + if(pphost->device_prop.Itf_Desc[0].bInterfaceSubClass == HID_BOOT_CODE) + { + /*Decode Bootclass Protocl: Mouse or Keyboard*/ + if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE) + { + HID_Machine.cb = &HID_KEYBRD_cb; + } + else if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_MOUSE_BOOT_CODE) + { + HID_Machine.cb = &HID_MOUSE_cb; + } + + HID_Machine.state = HID_IDLE; + HID_Machine.ctl_state = HID_REQ_IDLE; + HID_Machine.ep_addr = pphost->device_prop.Ep_Desc[0][0].bEndpointAddress; + HID_Machine.length = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize; + HID_Machine.poll = pphost->device_prop.Ep_Desc[0][0].bInterval ; + + /* Check fo available number of endpoints */ + /* Find the number of EPs in the Interface Descriptor */ + /* Choose the lower number in order not to overrun the buffer allocated */ + maxEP = ( (pphost->device_prop.Itf_Desc[0].bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) ? + pphost->device_prop.Itf_Desc[0].bNumEndpoints : + USBH_MAX_NUM_ENDPOINTS); + + + /* Decode endpoint IN and OUT address from interface descriptor */ + for (num=0; num < maxEP; num++) + { + if(pphost->device_prop.Ep_Desc[0][num].bEndpointAddress & 0x80) + { + HID_Machine.HIDIntInEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); + HID_Machine.hc_num_in =\ + USBH_Alloc_Channel(pdev, + pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); + + /* Open channel for IN endpoint */ + USBH_Open_Channel (pdev, + HID_Machine.hc_num_in, + pphost->device_prop.address, + pphost->device_prop.speed, + EP_TYPE_INTR, + HID_Machine.length); + } + else + { + HID_Machine.HIDIntOutEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); + HID_Machine.hc_num_out =\ + USBH_Alloc_Channel(pdev, + pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); + + /* Open channel for OUT endpoint */ + USBH_Open_Channel (pdev, + HID_Machine.hc_num_out, + pphost->device_prop.address, + pphost->device_prop.speed, + EP_TYPE_INTR, + HID_Machine.length); + } + + } + + flag =0; + status = USBH_OK; + } + else + { + pphost->usr_cb->USBH_USR_DeviceNotSupported(); + } + + return status; + +} + + + +/** +* @brief USBH_HID_InterfaceDeInit +* The function DeInit the Host Channels used for the HID class. +* @param pdev: Selected device +* @param hdev: Selected device property +* @retval None +*/ +void USBH_HID_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev, + void *phost) +{ + //USBH_HOST *pphost = phost; + + if(HID_Machine.hc_num_in != 0x00) + { + USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_in); + USBH_Free_Channel (pdev, HID_Machine.hc_num_in); + HID_Machine.hc_num_in = 0; /* Reset the Channel as Free */ + } + + if(HID_Machine.hc_num_out != 0x00) + { + USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_out); + USBH_Free_Channel (pdev, HID_Machine.hc_num_out); + HID_Machine.hc_num_out = 0; /* Reset the Channel as Free */ + } + + flag = 0; +} + +/** +* @brief USBH_HID_ClassRequest +* The function is responsible for handling HID Class requests +* for HID class. +* @param pdev: Selected device +* @param hdev: Selected device property +* @retval USBH_Status :Response for USB Set Protocol request +*/ +static USBH_Status USBH_HID_ClassRequest(USB_OTG_CORE_HANDLE *pdev , + void *phost) +{ + USBH_HOST *pphost = phost; + + USBH_Status status = USBH_BUSY; + USBH_Status classReqStatus = USBH_BUSY; + + + /* Switch HID state machine */ + switch (HID_Machine.ctl_state) + { + case HID_IDLE: + case HID_REQ_GET_HID_DESC: + + /* Get HID Desc */ + if (USBH_Get_HID_Descriptor (pdev, pphost, USB_HID_DESC_SIZE)== USBH_OK) + { + + USBH_ParseHIDDesc(&HID_Desc, pdev->host.Rx_Buffer); + HID_Machine.ctl_state = HID_REQ_GET_REPORT_DESC; + } + + break; + case HID_REQ_GET_REPORT_DESC: + + + /* Get Report Desc */ + if (USBH_Get_HID_ReportDescriptor(pdev , pphost, HID_Desc.wItemLength) == USBH_OK) + { + HID_Machine.ctl_state = HID_REQ_SET_IDLE; + } + + break; + + case HID_REQ_SET_IDLE: + + classReqStatus = USBH_Set_Idle (pdev, pphost, 0, 0); + + /* set Idle */ + if (classReqStatus == USBH_OK) + { + HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL; + } + else if(classReqStatus == USBH_NOT_SUPPORTED) + { + HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL; + } + break; + + case HID_REQ_SET_PROTOCOL: + /* set protocol */ + if (USBH_Set_Protocol (pdev ,pphost, 0) == USBH_OK) + { + HID_Machine.ctl_state = HID_REQ_IDLE; + + /* all requests performed*/ + status = USBH_OK; + } + break; + + default: + break; + } + + return status; +} + + +/** +* @brief USBH_HID_Handle +* The function is for managing state machine for HID data transfers +* @param pdev: Selected device +* @param hdev: Selected device property +* @retval USBH_Status +*/ +static USBH_Status USBH_HID_Handle(USB_OTG_CORE_HANDLE *pdev , + void *phost) +{ + USBH_HOST *pphost = phost; + USBH_Status status = USBH_OK; + + switch (HID_Machine.state) + { + + case HID_IDLE: + HID_Machine.cb->Init(); + HID_Machine.state = HID_GET_DATA; + break; + + case HID_GET_DATA: + + /* Sync with start of Even Frame */ + while(USB_OTG_IsEvenFrame(pdev) == FALSE); + + USBH_InterruptReceiveData(pdev, + HID_Machine.buff, + HID_Machine.length, + HID_Machine.hc_num_in); + flag = 1; + + HID_Machine.state = HID_POLL; + HID_Machine.timer = HCD_GetCurrentFrame(pdev); + break; + + case HID_POLL: + if(( HCD_GetCurrentFrame(pdev) - HID_Machine.timer) >= HID_Machine.poll) + { + HID_Machine.state = HID_GET_DATA; + } + else if(HCD_GetURB_State(pdev , HID_Machine.hc_num_in) == URB_DONE) + { + if(flag == 1) /* handle data once */ + { + flag = 0; + HID_Machine.cb->Decode(HID_Machine.buff); + } + } + else if(HCD_GetURB_State(pdev, HID_Machine.hc_num_in) == URB_STALL) /* IN Endpoint Stalled */ + { + + /* Issue Clear Feature on interrupt IN endpoint */ + if( (USBH_ClrFeature(pdev, + pphost, + HID_Machine.ep_addr, + HID_Machine.hc_num_in)) == USBH_OK) + { + /* Change state to issue next IN token */ + HID_Machine.state = HID_GET_DATA; + + } + + } + break; + + default: + break; + } + return status; +} + + +/** +* @brief USBH_Get_HID_ReportDescriptor +* Issue report Descriptor command to the device. Once the response +* received, parse the report descriptor and update the status. +* @param pdev : Selected device +* @param Length : HID Report Descriptor Length +* @retval USBH_Status : Response for USB HID Get Report Descriptor Request +*/ +static USBH_Status USBH_Get_HID_ReportDescriptor (USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint16_t length) +{ + + USBH_Status status; + + status = USBH_GetDescriptor(pdev, + phost, + USB_REQ_RECIPIENT_INTERFACE + | USB_REQ_TYPE_STANDARD, + USB_DESC_HID_REPORT, + pdev->host.Rx_Buffer, + length); + + /* HID report descriptor is available in pdev->host.Rx_Buffer. + In case of USB Boot Mode devices for In report handling , + HID report descriptor parsing is not required. + In case, for supporting Non-Boot Protocol devices and output reports, + user may parse the report descriptor*/ + + + return status; +} + +/** +* @brief USBH_Get_HID_Descriptor +* Issue HID Descriptor command to the device. Once the response +* received, parse the report descriptor and update the status. +* @param pdev : Selected device +* @param Length : HID Descriptor Length +* @retval USBH_Status : Response for USB HID Get Report Descriptor Request +*/ +static USBH_Status USBH_Get_HID_Descriptor (USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint16_t length) +{ + + USBH_Status status; + + status = USBH_GetDescriptor(pdev, + phost, + USB_REQ_RECIPIENT_INTERFACE + | USB_REQ_TYPE_STANDARD, + USB_DESC_HID, + pdev->host.Rx_Buffer, + length); + + return status; +} + +/** +* @brief USBH_Set_Idle +* Set Idle State. +* @param pdev: Selected device +* @param duration: Duration for HID Idle request +* @param reportID : Targetted report ID for Set Idle request +* @retval USBH_Status : Response for USB Set Idle request +*/ +static USBH_Status USBH_Set_Idle (USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t duration, + uint8_t reportId) +{ + + phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\ + USB_REQ_TYPE_CLASS; + + + phost->Control.setup.b.bRequest = USB_HID_SET_IDLE; + phost->Control.setup.b.wValue.w = (duration << 8 ) | reportId; + + phost->Control.setup.b.wIndex.w = 0; + phost->Control.setup.b.wLength.w = 0; + + return USBH_CtlReq(pdev, phost, 0 , 0 ); +} + + +/** +* @brief USBH_Set_Report +* Issues Set Report +* @param pdev: Selected device +* @param reportType : Report type to be sent +* @param reportID : Targetted report ID for Set Report request +* @param reportLen : Length of data report to be send +* @param reportBuff : Report Buffer +* @retval USBH_Status : Response for USB Set Idle request +*/ +USBH_Status USBH_Set_Report (USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t reportType, + uint8_t reportId, + uint8_t reportLen, + uint8_t* reportBuff) +{ + + phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\ + USB_REQ_TYPE_CLASS; + + + phost->Control.setup.b.bRequest = USB_HID_SET_REPORT; + phost->Control.setup.b.wValue.w = (reportType << 8 ) | reportId; + + phost->Control.setup.b.wIndex.w = 0; + phost->Control.setup.b.wLength.w = reportLen; + + return USBH_CtlReq(pdev, phost, reportBuff , reportLen ); +} + + +/** +* @brief USBH_Set_Protocol +* Set protocol State. +* @param pdev: Selected device +* @param protocol : Set Protocol for HID : boot/report protocol +* @retval USBH_Status : Response for USB Set Protocol request +*/ +static USBH_Status USBH_Set_Protocol(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t protocol) +{ + + + phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\ + USB_REQ_TYPE_CLASS; + + + phost->Control.setup.b.bRequest = USB_HID_SET_PROTOCOL; + + if(protocol != 0) + { + /* Boot Protocol */ + phost->Control.setup.b.wValue.w = 0; + } + else + { + /*Report Protocol*/ + phost->Control.setup.b.wValue.w = 1; + } + + phost->Control.setup.b.wIndex.w = 0; + phost->Control.setup.b.wLength.w = 0; + + return USBH_CtlReq(pdev, phost, 0 , 0 ); + +} + +/** +* @brief USBH_ParseHIDDesc +* This function Parse the HID descriptor +* @param buf: Buffer where the source descriptor is available +* @retval None +*/ +static void USBH_ParseHIDDesc (USBH_HIDDesc_TypeDef *desc, uint8_t *buf) +{ + + desc->bLength = *(uint8_t *) (buf + 0); + desc->bDescriptorType = *(uint8_t *) (buf + 1); + desc->bcdHID = LE16 (buf + 2); + desc->bCountryCode = *(uint8_t *) (buf + 4); + desc->bNumDescriptors = *(uint8_t *) (buf + 5); + desc->bReportDescriptorType = *(uint8_t *) (buf + 6); + desc->wItemLength = LE16 (buf + 7); + +} +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + + +/** +* @} +*/ + + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_keybd.c b/Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_keybd.c new file mode 100644 index 0000000..ae0df34 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_keybd.c @@ -0,0 +1,338 @@ +/** + ****************************************************************************** + * @file usbh_hid_keybd.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file is the application layer for USB Host HID Keyboard handling + * QWERTY and AZERTY Keyboard are supported as per the selection in + * usbh_hid_keybd.h + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_hid_keybd.h" + +/** @addtogroup USBH_LIB +* @{ +*/ + +/** @addtogroup USBH_CLASS +* @{ +*/ + +/** @addtogroup USBH_HID_CLASS +* @{ +*/ + +/** @defgroup USBH_HID_KEYBD +* @brief This file includes HID Layer Handlers for USB Host HID class. +* @{ +*/ + +/** @defgroup USBH_HID_KEYBD_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_HID_KEYBD_Private_Defines +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_HID_KEYBD_Private_Macros +* @{ +*/ +/** +* @} +*/ + +/** @defgroup USBH_HID_KEYBD_Private_FunctionPrototypes +* @{ +*/ +static void KEYBRD_Init (void); +static void KEYBRD_Decode(uint8_t *data); + +/** +* @} +*/ + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined (__CC_ARM) /*!< ARM Compiler */ + __align(4) + #elif defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #elif defined (__GNUC__) /*!< GNU Compiler */ + #pragma pack(4) + #elif defined (__TASKING__) /*!< TASKING Compiler */ + __align(4) + #endif /* __CC_ARM */ +#endif + +/** @defgroup USBH_HID_KEYBD_Private_Variables +* @{ +*/ +HID_cb_TypeDef HID_KEYBRD_cb= +{ + KEYBRD_Init, + KEYBRD_Decode +}; + +/* +******************************************************************************* +* LOCAL CONSTANTS +******************************************************************************* +*/ + +static const uint8_t HID_KEYBRD_Codes[] = { + 0, 0, 0, 0, 31, 50, 48, 33, + 19, 34, 35, 36, 24, 37, 38, 39, /* 0x00 - 0x0F */ + 52, 51, 25, 26, 17, 20, 32, 21, + 23, 49, 18, 47, 22, 46, 2, 3, /* 0x10 - 0x1F */ + 4, 5, 6, 7, 8, 9, 10, 11, + 43, 110, 15, 16, 61, 12, 13, 27, /* 0x20 - 0x2F */ + 28, 29, 42, 40, 41, 1, 53, 54, + 55, 30, 112, 113, 114, 115, 116, 117, /* 0x30 - 0x3F */ + 118, 119, 120, 121, 122, 123, 124, 125, + 126, 75, 80, 85, 76, 81, 86, 89, /* 0x40 - 0x4F */ + 79, 84, 83, 90, 95, 100, 105, 106, + 108, 93, 98, 103, 92, 97, 102, 91, /* 0x50 - 0x5F */ + 96, 101, 99, 104, 45, 129, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6F */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7F */ + 0, 0, 0, 0, 0, 107, 0, 56, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8F */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9F */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xAF */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 - 0xBF */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 - 0xCF */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 - 0xDF */ + 58, 44, 60, 127, 64, 57, 62, 128 /* 0xE0 - 0xE7 */ +}; + +#ifdef QWERTY_KEYBOARD +static const int8_t HID_KEYBRD_Key[] = { + '\0', '`', '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', '\0', '\r', + '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', + 'i', 'o', 'p', '[', ']', '\\', + '\0', 'a', 's', 'd', 'f', 'g', 'h', 'j', + 'k', 'l', ';', '\'', '\0', '\n', + '\0', '\0', 'z', 'x', 'c', 'v', 'b', 'n', + 'm', ',', '.', '/', '\0', '\0', + '\0', '\0', '\0', ' ', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '7', '4', '1', + '\0', '/', '8', '5', '2', + '0', '*', '9', '6', '3', + '.', '-', '+', '\0', '\n', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0' +}; + +static const int8_t HID_KEYBRD_ShiftKey[] = { + '\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', + '_', '+', '\0', '\0', '\0', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', + 'I', 'O', 'P', '{', '}', '|', '\0', 'A', 'S', 'D', 'F', 'G', + 'H', 'J', 'K', 'L', ':', '"', '\0', '\n', '\0', '\0', 'Z', 'X', + 'C', 'V', 'B', 'N', 'M', '<', '>', '?', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' +}; + +#else + +static const int8_t HID_KEYBRD_Key[] = { + '\0', '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', + '-', '=', '\0', '\r', '\t', 'a', 'z', 'e', 'r', 't', 'y', 'u', + 'i', 'o', 'p', '[', ']', '\\', '\0', 'q', 's', 'd', 'f', 'g', + 'h', 'j', 'k', 'l', 'm', '\0', '\0', '\n', '\0', '\0', 'w', 'x', + 'c', 'v', 'b', 'n', ',', ';', ':', '!', '\0', '\0', '\0', '\0', + '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '7', '4', '1','\0', '/', + '8', '5', '2', '0', '*', '9', '6', '3', '.', '-', '+', '\0', + '\n', '\0', '\0', '\0', '\0', '\0', '\0','\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' +}; + +static const int8_t HID_KEYBRD_ShiftKey[] = { + '\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', + '+', '\0', '\0', '\0', 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', + 'P', '{', '}', '*', '\0', 'Q', 'S', 'D', 'F', 'G', 'H', 'J', 'K', + 'L', 'M', '%', '\0', '\n', '\0', '\0', 'W', 'X', 'C', 'V', 'B', 'N', + '?', '.', '/', '\0', '\0', '\0','\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' +}; +#endif + +/** +* @} +*/ + + +/** @defgroup USBH_HID_KEYBD_Private_Functions +* @{ +*/ + + +/** +* @brief KEYBRD_Init. +* Initialize the keyboard function. +* @param None +* @retval None +*/ +static void KEYBRD_Init (void) +{ + /* Call User Init*/ + USR_KEYBRD_Init(); +} + +/** +* @brief KEYBRD_ProcessData. +* The function is to decode the pressed keys. +* @param pbuf : Pointer to the HID IN report data buffer +* @retval None +*/ + +static void KEYBRD_Decode(uint8_t *pbuf) +{ + static uint8_t shift; + static uint8_t keys[KBR_MAX_NBR_PRESSED]; + static uint8_t keys_new[KBR_MAX_NBR_PRESSED]; + static uint8_t keys_last[KBR_MAX_NBR_PRESSED]; + static uint8_t key_newest; + static uint8_t nbr_keys; + static uint8_t nbr_keys_new; + static uint8_t nbr_keys_last; + uint8_t ix; + uint8_t jx; + uint8_t error; + uint8_t output; + + nbr_keys = 0; + nbr_keys_new = 0; + nbr_keys_last = 0; + key_newest = 0x00; + + + /* Check if Shift key is pressed */ + if ((pbuf[0] == KBD_LEFT_SHIFT) || (pbuf[0] == KBD_RIGHT_SHIFT)) { + shift = TRUE; + } else { + shift = FALSE; + } + + error = FALSE; + + /* Check for the value of pressed key */ + for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++) { + if ((pbuf[ix] == 0x01) || + (pbuf[ix] == 0x02) || + (pbuf[ix] == 0x03)) { + error = TRUE; + } + } + + if (error == TRUE) { + return; + } + + nbr_keys = 0; + nbr_keys_new = 0; + for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++) { + if (pbuf[ix] != 0) { + keys[nbr_keys] = pbuf[ix]; + nbr_keys++; + for (jx = 0; jx < nbr_keys_last; jx++) { + if (pbuf[ix] == keys_last[jx]) { + break; + } + } + + if (jx == nbr_keys_last) { + keys_new[nbr_keys_new] = pbuf[ix]; + nbr_keys_new++; + } + } + } + + if (nbr_keys_new == 1) { + key_newest = keys_new[0]; + + if (shift == TRUE) { + output = HID_KEYBRD_ShiftKey[HID_KEYBRD_Codes[key_newest]]; + } else { + output = HID_KEYBRD_Key[HID_KEYBRD_Codes[key_newest]]; + } + + /* call user process handle */ + USR_KEYBRD_ProcessData(output); + } else { + key_newest = 0x00; + } + + + nbr_keys_last = nbr_keys; + for (ix = 0; ix < KBR_MAX_NBR_PRESSED; ix++) { + keys_last[ix] = keys[ix]; + } +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_mouse.c b/Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_mouse.c new file mode 100644 index 0000000..f3ec2fc --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_mouse.c @@ -0,0 +1,155 @@ +/** + ****************************************************************************** + * @file usbh_hid_mouse.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file is the application layer for USB Host HID Mouse Handling. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_hid_mouse.h" + + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_CLASS + * @{ + */ + +/** @addtogroup USBH_HID_CLASS + * @{ + */ + +/** @defgroup USBH_HID_MOUSE + * @brief This file includes HID Layer Handlers for USB Host HID class. + * @{ + */ + +/** @defgroup USBH_HID_MOUSE_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_HID_MOUSE_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_HID_MOUSE_Private_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_HID_MOUSE_Private_FunctionPrototypes + * @{ + */ +static void MOUSE_Init (void); +static void MOUSE_Decode(uint8_t *data); +/** + * @} + */ + + +/** @defgroup USBH_HID_MOUSE_Private_Variables + * @{ + */ +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined (__CC_ARM) /*!< ARM Compiler */ + __align(4) + #elif defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #elif defined (__GNUC__) /*!< GNU Compiler */ + #pragma pack(4) + #elif defined (__TASKING__) /*!< TASKING Compiler */ + __align(4) + #endif /* __CC_ARM */ +#endif + + +HID_MOUSE_Data_TypeDef HID_MOUSE_Data; +HID_cb_TypeDef HID_MOUSE_cb = +{ + MOUSE_Init, + MOUSE_Decode, +}; +/** + * @} + */ + + +/** @defgroup USBH_HID_MOUSE_Private_Functions + * @{ + */ + +/** +* @brief MOUSE_Init +* Init Mouse State. +* @param None +* @retval None +*/ +static void MOUSE_Init ( void) +{ + /* Call User Init*/ + USR_MOUSE_Init(); +} + +/** +* @brief MOUSE_Decode +* Decode Mouse data +* @param data : Pointer to Mouse HID data buffer +* @retval None +*/ +static void MOUSE_Decode(uint8_t *data) +{ + HID_MOUSE_Data.button = data[0]; + + HID_MOUSE_Data.x = data[1]; + HID_MOUSE_Data.y = data[2]; + + USR_MOUSE_ProcessData(&HID_MOUSE_Data); + +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_bot.h b/Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_bot.h new file mode 100644 index 0000000..27e9659 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_bot.h @@ -0,0 +1,221 @@ +/** + ****************************************************************************** + * @file usbh_msc_bot.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Header file for usbh_msc_bot.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_MSC_BOT_H__ +#define __USBH_MSC_BOT_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_stdreq.h" + + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_CLASS + * @{ + */ + +/** @addtogroup USBH_MSC_CLASS + * @{ + */ + +/** @defgroup USBH_MSC_BOT + * @brief This file is the Header file for usbh_msc_core.c + * @{ + */ + + +/** @defgroup USBH_MSC_BOT_Exported_Types + * @{ + */ + +typedef union _USBH_CBW_Block +{ + struct __CBW + { + uint32_t CBWSignature; + uint32_t CBWTag; + uint32_t CBWTransferLength; + uint8_t CBWFlags; + uint8_t CBWLUN; + uint8_t CBWLength; + uint8_t CBWCB[16]; +}field; + uint8_t CBWArray[31]; +}HostCBWPkt_TypeDef; + +typedef enum +{ + USBH_MSC_BOT_INIT_STATE = 0, + USBH_MSC_BOT_RESET, + USBH_MSC_GET_MAX_LUN, + USBH_MSC_TEST_UNIT_READY, + USBH_MSC_READ_CAPACITY10, + USBH_MSC_MODE_SENSE6, + USBH_MSC_REQUEST_SENSE, + USBH_MSC_BOT_USB_TRANSFERS, + USBH_MSC_DEFAULT_APPLI_STATE, + USBH_MSC_CTRL_ERROR_STATE, + USBH_MSC_UNRECOVERED_STATE +} +MSCState; + + +typedef struct _BOTXfer +{ +uint8_t MSCState; +uint8_t MSCStateBkp; +uint8_t MSCStateCurrent; +uint8_t CmdStateMachine; +uint8_t BOTState; +uint8_t BOTStateBkp; +uint8_t* pRxTxBuff; +uint16_t DataLength; +uint8_t BOTXferErrorCount; +uint8_t BOTXferStatus; +} USBH_BOTXfer_TypeDef; + + +typedef union _USBH_CSW_Block +{ + struct __CSW + { + uint32_t CSWSignature; + uint32_t CSWTag; + uint32_t CSWDataResidue; + uint8_t CSWStatus; + }field; + uint8_t CSWArray[13]; +}HostCSWPkt_TypeDef; + +/** + * @} + */ + + + +/** @defgroup USBH_MSC_BOT_Exported_Defines + * @{ + */ +#define USBH_MSC_SEND_CBW 1 +#define USBH_MSC_SENT_CBW 2 +#define USBH_MSC_BOT_DATAIN_STATE 3 +#define USBH_MSC_BOT_DATAOUT_STATE 4 +#define USBH_MSC_RECEIVE_CSW_STATE 5 +#define USBH_MSC_DECODE_CSW 6 +#define USBH_MSC_BOT_ERROR_IN 7 +#define USBH_MSC_BOT_ERROR_OUT 8 + + +#define USBH_MSC_BOT_CBW_SIGNATURE 0x43425355 +#define USBH_MSC_BOT_CBW_TAG 0x20304050 +#define USBH_MSC_BOT_CSW_SIGNATURE 0x53425355 +#define USBH_MSC_CSW_DATA_LENGTH 0x000D +#define USBH_MSC_BOT_CBW_PACKET_LENGTH 31 +#define USBH_MSC_CSW_LENGTH 13 +#define USBH_MSC_CSW_MAX_LENGTH 63 + +/* CSW Status Definitions */ +#define USBH_MSC_CSW_CMD_PASSED 0x00 +#define USBH_MSC_CSW_CMD_FAILED 0x01 +#define USBH_MSC_CSW_PHASE_ERROR 0x02 + +#define USBH_MSC_SEND_CSW_DISABLE 0 +#define USBH_MSC_SEND_CSW_ENABLE 1 + +#define USBH_MSC_DIR_IN 0 +#define USBH_MSC_DIR_OUT 1 +#define USBH_MSC_BOTH_DIR 2 + +//#define USBH_MSC_PAGE_LENGTH 0x40 +#define USBH_MSC_PAGE_LENGTH 512 + + +#define CBW_CB_LENGTH 16 +#define CBW_LENGTH 10 +#define CBW_LENGTH_TEST_UNIT_READY 6 + +#define USB_REQ_BOT_RESET 0xFF +#define USB_REQ_GET_MAX_LUN 0xFE + +#define MAX_BULK_STALL_COUNT_LIMIT 0x04 /* If STALL is seen on Bulk + Endpoint continously, this means + that device and Host has phase error + Hence a Reset is needed */ + +/** + * @} + */ + +/** @defgroup USBH_MSC_BOT_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_MSC_BOT_Exported_Variables + * @{ + */ +extern USBH_BOTXfer_TypeDef USBH_MSC_BOTXferParam; +extern HostCBWPkt_TypeDef USBH_MSC_CBWData; +extern HostCSWPkt_TypeDef USBH_MSC_CSWData; +/** + * @} + */ + +/** @defgroup USBH_MSC_BOT_Exported_FunctionsPrototype + * @{ + */ +void USBH_MSC_HandleBOTXfer(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost); +uint8_t USBH_MSC_DecodeCSW(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost); +void USBH_MSC_Init(USB_OTG_CORE_HANDLE *pdev); +USBH_Status USBH_MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t direction); +/** + * @} + */ + +#endif //__USBH_MSC_BOT_H__ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_core.h b/Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_core.h new file mode 100644 index 0000000..72ab4ce --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_core.h @@ -0,0 +1,141 @@ +/** + ****************************************************************************** + * @file usbh_msc_core.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file contains all the prototypes for the usbh_msc_core.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_MSC_CORE_H +#define __USBH_MSC_CORE_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_core.h" +#include "usbh_stdreq.h" +#include "usb_bsp.h" +#include "usbh_ioreq.h" +#include "usbh_hcs.h" +#include "usbh_msc_core.h" +#include "usbh_msc_scsi.h" +#include "usbh_msc_bot.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_CLASS + * @{ + */ + +/** @addtogroup USBH_MSC_CLASS + * @{ + */ + +/** @defgroup USBH_MSC_CORE + * @brief This file is the Header file for usbh_msc_core.c + * @{ + */ + + +/** @defgroup USBH_MSC_CORE_Exported_Types + * @{ + */ + + +/* Structure for MSC process */ +typedef struct _MSC_Process +{ + uint8_t hc_num_in; + uint8_t hc_num_out; + uint8_t MSBulkOutEp; + uint8_t MSBulkInEp; + uint16_t MSBulkInEpSize; + uint16_t MSBulkOutEpSize; + uint8_t buff[USBH_MSC_MPS_SIZE]; + uint8_t maxLun; +} +MSC_Machine_TypeDef; + + +/** + * @} + */ + + + +/** @defgroup USBH_MSC_CORE_Exported_Defines + * @{ + */ + +#define USB_REQ_BOT_RESET 0xFF +#define USB_REQ_GET_MAX_LUN 0xFE + + +/** + * @} + */ + +/** @defgroup USBH_MSC_CORE_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_MSC_CORE_Exported_Variables + * @{ + */ +extern USBH_Class_cb_TypeDef USBH_MSC_cb; +extern MSC_Machine_TypeDef MSC_Machine; +extern uint8_t MSCErrorCount; + +/** + * @} + */ + +/** @defgroup USBH_MSC_CORE_Exported_FunctionsPrototype + * @{ + */ + + + +/** + * @} + */ + +#endif /* __USBH_MSC_CORE_H */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + + diff --git a/Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_scsi.h b/Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_scsi.h new file mode 100644 index 0000000..3bdf4ec --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_scsi.h @@ -0,0 +1,163 @@ +/** + ****************************************************************************** + * @file usbh_msc_scsi.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Header file for usbh_msc_scsi.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_MSC_SCSI_H__ +#define __USBH_MSC_SCSI_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_stdreq.h" + + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_CLASS + * @{ + */ + +/** @addtogroup USBH_MSC_CLASS + * @{ + */ + +/** @defgroup USBH_MSC_SCSI + * @brief This file is the Header file for usbh_msc_scsi.c + * @{ + */ + + +/** @defgroup USBH_MSC_SCSI_Exported_Types + * @{ + */ +typedef enum { + USBH_MSC_OK = 0, + USBH_MSC_FAIL = 1, + USBH_MSC_PHASE_ERROR = 2, + USBH_MSC_BUSY = 3 +}USBH_MSC_Status_TypeDef; + +typedef enum { + CMD_UNINITIALIZED_STATE =0, + CMD_SEND_STATE, + CMD_WAIT_STATUS +} CMD_STATES_TypeDef; + + + +typedef struct __MassStorageParameter +{ + uint32_t MSCapacity; + uint32_t MSSenseKey; + uint16_t MSPageLength; + uint8_t MSBulkOutEp; + uint8_t MSBulkInEp; + uint8_t MSWriteProtect; +} MassStorageParameter_TypeDef; +/** + * @} + */ + + + +/** @defgroup USBH_MSC_SCSI_Exported_Defines + * @{ + */ + + + +#define OPCODE_TEST_UNIT_READY 0X00 +#define OPCODE_READ_CAPACITY10 0x25 +#define OPCODE_MODE_SENSE6 0x1A +#define OPCODE_READ10 0x28 +#define OPCODE_WRITE10 0x2A +#define OPCODE_REQUEST_SENSE 0x03 + +#define DESC_REQUEST_SENSE 0X00 +#define ALLOCATION_LENGTH_REQUEST_SENSE 63 +#define XFER_LEN_READ_CAPACITY10 8 +#define XFER_LEN_MODE_SENSE6 63 + +#define MASK_MODE_SENSE_WRITE_PROTECT 0x80 +#define MODE_SENSE_PAGE_CONTROL_FIELD 0x00 +#define MODE_SENSE_PAGE_CODE 0x3F +#define DISK_WRITE_PROTECTED 0x01 +/** + * @} + */ + +/** @defgroup USBH_MSC_SCSI_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup _Exported_Variables + * @{ + */ +extern MassStorageParameter_TypeDef USBH_MSC_Param; +/** + * @} + */ + +/** @defgroup USBH_MSC_SCSI_Exported_FunctionsPrototype + * @{ + */ +uint8_t USBH_MSC_TestUnitReady(USB_OTG_CORE_HANDLE *pdev); +uint8_t USBH_MSC_ReadCapacity10(USB_OTG_CORE_HANDLE *pdev); +uint8_t USBH_MSC_ModeSense6(USB_OTG_CORE_HANDLE *pdev); +uint8_t USBH_MSC_RequestSense(USB_OTG_CORE_HANDLE *pdev); +uint8_t USBH_MSC_Write10(USB_OTG_CORE_HANDLE *pdev, + uint8_t *, + uint32_t , + uint32_t ); +uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev, + uint8_t *, + uint32_t , + uint32_t ); +void USBH_MSC_StateMachine(USB_OTG_CORE_HANDLE *pdev); + +/** + * @} + */ + +#endif //__USBH_MSC_SCSI_H__ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_bot.c b/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_bot.c new file mode 100644 index 0000000..eeb1075 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_bot.c @@ -0,0 +1,613 @@ +/** + ****************************************************************************** + * @file usbh_msc_bot.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file includes the mass storage related functions + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_msc_core.h" +#include "usbh_msc_scsi.h" +#include "usbh_msc_bot.h" +#include "usbh_ioreq.h" +#include "usbh_def.h" +#include "usb_hcd_int.h" + + +/** @addtogroup USBH_LIB +* @{ +*/ + +/** @addtogroup USBH_CLASS +* @{ +*/ + +/** @addtogroup USBH_MSC_CLASS +* @{ +*/ + +/** @defgroup USBH_MSC_BOT +* @brief This file includes the mass storage related functions +* @{ +*/ + + +/** @defgroup USBH_MSC_BOT_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + +/** @defgroup USBH_MSC_BOT_Private_Defines +* @{ +*/ +/** +* @} +*/ + +/** @defgroup USBH_MSC_BOT_Private_Macros +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_MSC_BOT_Private_Variables +* @{ +*/ + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN HostCBWPkt_TypeDef USBH_MSC_CBWData __ALIGN_END ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN HostCSWPkt_TypeDef USBH_MSC_CSWData __ALIGN_END ; + + +static uint32_t BOTStallErrorCount; /* Keeps count of STALL Error Cases*/ + +/** +* @} +*/ + + +/** @defgroup USBH_MSC_BOT_Private_FunctionPrototypes +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_MSC_BOT_Exported_Variables +* @{ +*/ +USBH_BOTXfer_TypeDef USBH_MSC_BOTXferParam; +/** +* @} +*/ + + +/** @defgroup USBH_MSC_BOT_Private_Functions +* @{ +*/ + + +/** +* @brief USBH_MSC_Init +* Initializes the mass storage parameters +* @param None +* @retval None +*/ +void USBH_MSC_Init(USB_OTG_CORE_HANDLE *pdev ) +{ + if(HCD_IsDeviceConnected(pdev)) + { + USBH_MSC_CBWData.field.CBWSignature = USBH_MSC_BOT_CBW_SIGNATURE; + USBH_MSC_CBWData.field.CBWTag = USBH_MSC_BOT_CBW_TAG; + USBH_MSC_CBWData.field.CBWLUN = 0; /*Only one LUN is supported*/ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + } + + BOTStallErrorCount = 0; + MSCErrorCount = 0; +} + +/** +* @brief USBH_MSC_HandleBOTXfer +* This function manages the different states of BOT transfer and +* updates the status to upper layer. +* @param None +* @retval None +* +*/ +void USBH_MSC_HandleBOTXfer (USB_OTG_CORE_HANDLE *pdev ,USBH_HOST *phost) +{ + uint8_t xferDirection, index; + static uint32_t remainingDataLength; + static uint8_t *datapointer; + static uint8_t error_direction; + USBH_Status status; + + URB_STATE URB_Status = URB_IDLE; + + if(HCD_IsDeviceConnected(pdev)) + { + + switch (USBH_MSC_BOTXferParam.BOTState) + { + case USBH_MSC_SEND_CBW: + /* send CBW */ + USBH_BulkSendData (pdev, + &USBH_MSC_CBWData.CBWArray[0], + USBH_MSC_BOT_CBW_PACKET_LENGTH , + MSC_Machine.hc_num_out); + + USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_SEND_CBW; + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SENT_CBW; + + break; + + case USBH_MSC_SENT_CBW: + URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out); + + if(URB_Status == URB_DONE) + { + BOTStallErrorCount = 0; + USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_SENT_CBW; + + /* If the CBW Pkt is sent successful, then change the state */ + xferDirection = (USBH_MSC_CBWData.field.CBWFlags & USB_REQ_DIR_MASK); + + if ( USBH_MSC_CBWData.field.CBWTransferLength != 0 ) + { + remainingDataLength = USBH_MSC_CBWData.field.CBWTransferLength ; + datapointer = USBH_MSC_BOTXferParam.pRxTxBuff; + + /* If there is Data Transfer Stage */ + if (xferDirection == USB_D2H) + { + /* Data Direction is IN */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_DATAIN_STATE; + } + else + { + /* Data Direction is OUT */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_DATAOUT_STATE; + } + } + + else + {/* If there is NO Data Transfer Stage */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE; + } + + } + else if(URB_Status == URB_NOTREADY) + { + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; + } + else if(URB_Status == URB_STALL) + { + error_direction = USBH_MSC_DIR_OUT; + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT; + } + break; + + case USBH_MSC_BOT_DATAIN_STATE: + + URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_in); + /* BOT DATA IN stage */ + if((URB_Status == URB_DONE) ||(USBH_MSC_BOTXferParam.BOTStateBkp != USBH_MSC_BOT_DATAIN_STATE)) + { + BOTStallErrorCount = 0; + USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_BOT_DATAIN_STATE; + + if(remainingDataLength > USBH_MSC_MPS_SIZE) + { + USBH_BulkReceiveData (pdev, + datapointer, + USBH_MSC_MPS_SIZE , + MSC_Machine.hc_num_in); + + remainingDataLength -= USBH_MSC_MPS_SIZE; + datapointer = datapointer + USBH_MSC_MPS_SIZE; + } + else if ( remainingDataLength == 0) + { + /* If value was 0, and successful transfer, then change the state */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE; + } + else + { + USBH_BulkReceiveData (pdev, + datapointer, + remainingDataLength , + MSC_Machine.hc_num_in); + + remainingDataLength = 0; /* Reset this value and keep in same state */ + } + } + else if(URB_Status == URB_STALL) + { + /* This is Data Stage STALL Condition */ + + error_direction = USBH_MSC_DIR_IN; + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_IN; + + /* Refer to USB Mass-Storage Class : BOT (www.usb.org) + 6.7.2 Host expects to receive data from the device + 3. On a STALL condition receiving data, then: + The host shall accept the data received. + The host shall clear the Bulk-In pipe. + 4. The host shall attempt to receive a CSW. + + USBH_MSC_BOTXferParam.BOTStateBkp is used to switch to the Original + state after the ClearFeature Command is issued. + */ + USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE; + + } + break; + + + case USBH_MSC_BOT_DATAOUT_STATE: + /* BOT DATA OUT stage */ + URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out); + if(URB_Status == URB_DONE) + { + BOTStallErrorCount = 0; + USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_BOT_DATAOUT_STATE; + if(remainingDataLength > USBH_MSC_MPS_SIZE) + { + USBH_BulkSendData (pdev, + datapointer, + USBH_MSC_MPS_SIZE , + MSC_Machine.hc_num_out); + datapointer = datapointer + USBH_MSC_MPS_SIZE; + remainingDataLength = remainingDataLength - USBH_MSC_MPS_SIZE; + } + else if ( remainingDataLength == 0) + { + /* If value was 0, and successful transfer, then change the state */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE; + } + else + { + USBH_BulkSendData (pdev, + datapointer, + remainingDataLength , + MSC_Machine.hc_num_out); + + remainingDataLength = 0; /* Reset this value and keep in same state */ + } + } + + else if(URB_Status == URB_NOTREADY) + { + USBH_BulkSendData (pdev, + (datapointer - USBH_MSC_MPS_SIZE), + USBH_MSC_MPS_SIZE , + MSC_Machine.hc_num_out); + } + + else if(URB_Status == URB_STALL) + { + error_direction = USBH_MSC_DIR_OUT; + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT; + + /* Refer to USB Mass-Storage Class : BOT (www.usb.org) + 6.7.3 Ho - Host expects to send data to the device + 3. On a STALL condition sending data, then: + " The host shall clear the Bulk-Out pipe. + 4. The host shall attempt to receive a CSW. + + The Above statement will do the clear the Bulk-Out pipe. + The Below statement will help in Getting the CSW. + + USBH_MSC_BOTXferParam.BOTStateBkp is used to switch to the Original + state after the ClearFeature Command is issued. + */ + + USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE; + + } + break; + + case USBH_MSC_RECEIVE_CSW_STATE: + /* BOT CSW stage */ + /* NOTE: We cannot reset the BOTStallErrorCount here as it may come from + the clearFeature from previous command */ + + USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE; + + USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray; + USBH_MSC_BOTXferParam.DataLength = USBH_MSC_CSW_MAX_LENGTH; + + for(index = USBH_MSC_CSW_LENGTH; index != 0; index--) + { + USBH_MSC_CSWData.CSWArray[index] = 0; + } + + USBH_MSC_CSWData.CSWArray[0] = 0; + + USBH_BulkReceiveData (pdev, + USBH_MSC_BOTXferParam.pRxTxBuff, + USBH_MSC_CSW_MAX_LENGTH , + MSC_Machine.hc_num_in); + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_DECODE_CSW; + + break; + + case USBH_MSC_DECODE_CSW: + URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_in); + /* Decode CSW */ + if(URB_Status == URB_DONE) + { + BOTStallErrorCount = 0; + USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE; + + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateCurrent ; + + USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_DecodeCSW(pdev , phost); + } + else if(URB_Status == URB_STALL) + { + error_direction = USBH_MSC_DIR_IN; + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_IN; + } + break; + + case USBH_MSC_BOT_ERROR_IN: + status = USBH_MSC_BOT_Abort(pdev, phost, USBH_MSC_DIR_IN); + if (status == USBH_OK) + { + /* Check if the error was due in Both the directions */ + if (error_direction == USBH_MSC_BOTH_DIR) + {/* If Both directions are Needed, Switch to OUT Direction */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT; + } + else + { + /* Switch Back to the Original State, In many cases this will be + USBH_MSC_RECEIVE_CSW_STATE state */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; + } + } + else if (status == USBH_UNRECOVERED_ERROR) + { + /* This means that there is a STALL Error limit, Do Reset Recovery */ + USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_PHASE_ERROR; + } + break; + + case USBH_MSC_BOT_ERROR_OUT: + status = USBH_MSC_BOT_Abort(pdev, phost, USBH_MSC_DIR_OUT); + if ( status == USBH_OK) + { /* Switch Back to the Original State */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; + } + else if (status == USBH_UNRECOVERED_ERROR) + { + /* This means that there is a STALL Error limit, Do Reset Recovery */ + USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_PHASE_ERROR; + } + break; + + default: + break; + } + } +} + +/** +* @brief USBH_MSC_BOT_Abort +* This function manages the different Error handling for STALL +* @param direction : IN / OUT +* @retval None +*/ +USBH_Status USBH_MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t direction) +{ + USBH_Status status; + + status = USBH_BUSY; + + switch (direction) + { + case USBH_MSC_DIR_IN : + /* send ClrFeture on Bulk IN endpoint */ + status = USBH_ClrFeature(pdev, + phost, + MSC_Machine.MSBulkInEp, + MSC_Machine.hc_num_in); + + break; + + case USBH_MSC_DIR_OUT : + /*send ClrFeature on Bulk OUT endpoint */ + status = USBH_ClrFeature(pdev, + phost, + MSC_Machine.MSBulkOutEp, + MSC_Machine.hc_num_out); + break; + + default: + break; + } + + BOTStallErrorCount++; /* Check Continous Number of times, STALL has Occured */ + if (BOTStallErrorCount > MAX_BULK_STALL_COUNT_LIMIT ) + { + status = USBH_UNRECOVERED_ERROR; + } + + return status; +} + +/** +* @brief USBH_MSC_DecodeCSW +* This function decodes the CSW received by the device and updates the +* same to upper layer. +* @param None +* @retval On success USBH_MSC_OK, on failure USBH_MSC_FAIL +* @notes +* Refer to USB Mass-Storage Class : BOT (www.usb.org) +* 6.3.1 Valid CSW Conditions : +* The host shall consider the CSW valid when: +* 1. dCSWSignature is equal to 53425355h +* 2. the CSW is 13 (Dh) bytes in length, +* 3. dCSWTag matches the dCBWTag from the corresponding CBW. +*/ + +uint8_t USBH_MSC_DecodeCSW(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost) +{ + uint8_t status; + uint32_t dataXferCount = 0; + status = USBH_MSC_FAIL; + + if(HCD_IsDeviceConnected(pdev)) + { + /*Checking if the transfer length is diffrent than 13*/ + dataXferCount = HCD_GetXferCnt(pdev, MSC_Machine.hc_num_in); + + if(dataXferCount != USBH_MSC_CSW_LENGTH) + { + /*(4) Hi > Dn (Host expects to receive data from the device, + Device intends to transfer no data) + (5) Hi > Di (Host expects to receive data from the device, + Device intends to send data to the host) + (9) Ho > Dn (Host expects to send data to the device, + Device intends to transfer no data) + (11) Ho > Do (Host expects to send data to the device, + Device intends to receive data from the host)*/ + + + status = USBH_MSC_PHASE_ERROR; + } + else + { /* CSW length is Correct */ + + /* Check validity of the CSW Signature and CSWStatus */ + if(USBH_MSC_CSWData.field.CSWSignature == USBH_MSC_BOT_CSW_SIGNATURE) + {/* Check Condition 1. dCSWSignature is equal to 53425355h */ + + if(USBH_MSC_CSWData.field.CSWTag == USBH_MSC_CBWData.field.CBWTag) + { + /* Check Condition 3. dCSWTag matches the dCBWTag from the + corresponding CBW */ + + if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_OK) + { + /* Refer to USB Mass-Storage Class : BOT (www.usb.org) + + Hn Host expects no data transfers + Hi Host expects to receive data from the device + Ho Host expects to send data to the device + + Dn Device intends to transfer no data + Di Device intends to send data to the host + Do Device intends to receive data from the host + + Section 6.7 + (1) Hn = Dn (Host expects no data transfers, + Device intends to transfer no data) + (6) Hi = Di (Host expects to receive data from the device, + Device intends to send data to the host) + (12) Ho = Do (Host expects to send data to the device, + Device intends to receive data from the host) + + */ + + status = USBH_MSC_OK; + } + else if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_FAIL) + { + status = USBH_MSC_FAIL; + } + + else if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_PHASE_ERROR) + { + /* Refer to USB Mass-Storage Class : BOT (www.usb.org) + Section 6.7 + (2) Hn < Di ( Host expects no data transfers, + Device intends to send data to the host) + (3) Hn < Do ( Host expects no data transfers, + Device intends to receive data from the host) + (7) Hi < Di ( Host expects to receive data from the device, + Device intends to send data to the host) + (8) Hi <> Do ( Host expects to receive data from the device, + Device intends to receive data from the host) + (10) Ho <> Di (Host expects to send data to the device, + Di Device intends to send data to the host) + (13) Ho < Do (Host expects to send data to the device, + Device intends to receive data from the host) + */ + + status = USBH_MSC_PHASE_ERROR; + } + } /* CSW Tag Matching is Checked */ + } /* CSW Signature Correct Checking */ + else + { + /* If the CSW Signature is not valid, We sall return the Phase Error to + Upper Layers for Reset Recovery */ + + status = USBH_MSC_PHASE_ERROR; + } + } /* CSW Length Check*/ + } + + USBH_MSC_BOTXferParam.BOTXferStatus = status; + return status; +} + + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + + diff --git a/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_core.c b/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_core.c new file mode 100644 index 0000000..466399e --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_core.c @@ -0,0 +1,559 @@ +/** + ****************************************************************************** + * @file usbh_msc_core.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file implements the MSC class driver functions + * =================================================================== + * MSC Class Description + * =================================================================== + * This module manages the MSC class V1.0 following the "Universal + * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0 + * Sep. 31, 1999". + * This driver implements the following aspects of the specification: + * - Bulk-Only Transport protocol + * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3)) + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+*/ + +/* Includes ------------------------------------------------------------------*/ + +#include "usbh_msc_core.h" +#include "usbh_msc_scsi.h" +#include "usbh_msc_bot.h" +#include "usbh_core.h" + + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_CLASS + * @{ + */ + +/** @addtogroup USBH_MSC_CLASS + * @{ + */ + +/** @defgroup USBH_MSC_CORE + * @brief This file includes the mass storage related functions + * @{ + */ + + +/** @defgroup USBH_MSC_CORE_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_MSC_CORE_Private_Defines + * @{ + */ +#define USBH_MSC_ERROR_RETRY_LIMIT 10 +/** + * @} + */ + +/** @defgroup USBH_MSC_CORE_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_MSC_CORE_Private_Variables + * @{ + */ +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN MSC_Machine_TypeDef MSC_Machine __ALIGN_END ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN USB_Setup_TypeDef MSC_Setup __ALIGN_END ; +uint8_t MSCErrorCount = 0; + + +/** + * @} + */ + + +/** @defgroup USBH_MSC_CORE_Private_FunctionPrototypes + * @{ + */ + +static USBH_Status USBH_MSC_InterfaceInit (USB_OTG_CORE_HANDLE *pdev , + void *phost); + +static void USBH_MSC_InterfaceDeInit (USB_OTG_CORE_HANDLE *pdev , + void *phost); + +static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev , + void *phost); + +static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev , + void *phost); + +static USBH_Status USBH_MSC_BOTReset(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost); +static USBH_Status USBH_MSC_GETMaxLUN(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost); + + +USBH_Class_cb_TypeDef USBH_MSC_cb = +{ + USBH_MSC_InterfaceInit, + USBH_MSC_InterfaceDeInit, + USBH_MSC_ClassRequest, + USBH_MSC_Handle, +}; + +void USBH_MSC_ErrorHandle(uint8_t status); + +/** + * @} + */ + + +/** @defgroup USBH_MSC_CORE_Exported_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBH_MSC_CORE_Private_Functions + * @{ + */ + + +/** + * @brief USBH_MSC_InterfaceInit + * Interface initialization for MSC class. + * @param pdev: Selected device + * @param hdev: Selected device property + * @retval USBH_Status : Status of class request handled. + */ +static USBH_Status USBH_MSC_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev, + void *phost) +{ + USBH_HOST *pphost = phost; + + if((pphost->device_prop.Itf_Desc[0].bInterfaceClass == MSC_CLASS) && \ + (pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == MSC_PROTOCOL)) + { + if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80) + { + MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress); + MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize; + } + else + { + MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress); + MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0] [0].wMaxPacketSize; + } + + if(pphost->device_prop.Ep_Desc[0][1].bEndpointAddress & 0x80) + { + MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress); + MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize; + } + else + { + MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress); + MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize; + } + + MSC_Machine.hc_num_out = USBH_Alloc_Channel(pdev, + MSC_Machine.MSBulkOutEp); + MSC_Machine.hc_num_in = USBH_Alloc_Channel(pdev, + MSC_Machine.MSBulkInEp); + + /* Open the new channels */ + USBH_Open_Channel (pdev, + MSC_Machine.hc_num_out, + pphost->device_prop.address, + pphost->device_prop.speed, + EP_TYPE_BULK, + MSC_Machine.MSBulkOutEpSize); + + USBH_Open_Channel (pdev, + MSC_Machine.hc_num_in, + pphost->device_prop.address, + pphost->device_prop.speed, + EP_TYPE_BULK, + MSC_Machine.MSBulkInEpSize); + + } + + else + { + pphost->usr_cb->USBH_USR_DeviceNotSupported(); + } + + return USBH_OK ; + +} + + +/** + * @brief USBH_MSC_InterfaceDeInit + * De-Initialize interface by freeing host channels allocated to interface + * @param pdev: Selected device + * @param hdev: Selected device property + * @retval None + */ +void USBH_MSC_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev, + void *phost) +{ + if ( MSC_Machine.hc_num_out) + { + USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_out); + USBH_Free_Channel (pdev, MSC_Machine.hc_num_out); + MSC_Machine.hc_num_out = 0; /* Reset the Channel as Free */ + } + + if ( MSC_Machine.hc_num_in) + { + USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_in); + USBH_Free_Channel (pdev, MSC_Machine.hc_num_in); + MSC_Machine.hc_num_in = 0; /* Reset the Channel as Free */ + } +} + +/** + * @brief USBH_MSC_ClassRequest + * This function will only initialize the MSC state machine + * @param pdev: Selected device + * @param hdev: Selected device property + * @retval USBH_Status : Status of class request handled. + */ + +static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev , + void *phost) +{ + + USBH_Status status = USBH_OK ; + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_INIT_STATE; + + return status; +} + + +/** + * @brief USBH_MSC_Handle + * MSC state machine handler + * @param pdev: Selected device + * @param hdev: Selected device property + * @retval USBH_Status + */ + +static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev , + void *phost) +{ + USBH_HOST *pphost = phost; + + USBH_Status status = USBH_BUSY; + uint8_t mscStatus = USBH_MSC_BUSY; + uint8_t appliStatus = 0; + + static uint8_t maxLunExceed = FALSE; + + + if(HCD_IsDeviceConnected(pdev)) + { + switch(USBH_MSC_BOTXferParam.MSCState) + { + case USBH_MSC_BOT_INIT_STATE: + USBH_MSC_Init(pdev); + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_RESET; + break; + + case USBH_MSC_BOT_RESET: + /* Issue BOT RESET request */ + status = USBH_MSC_BOTReset(pdev, phost); + if(status == USBH_OK ) + { + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_GET_MAX_LUN; + } + + if(status == USBH_NOT_SUPPORTED ) + { + /* If the Command has failed, then we need to move to Next State, after + STALL condition is cleared by Control-Transfer */ + USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_GET_MAX_LUN; + + /* a Clear Feature should be issued here */ + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE; + } + break; + + case USBH_MSC_GET_MAX_LUN: + /* Issue GetMaxLUN request */ + status = USBH_MSC_GETMaxLUN(pdev, phost); + + if(status == USBH_OK ) + { + MSC_Machine.maxLun = *(MSC_Machine.buff) ; + + /* If device has more that one logical unit then it is not supported */ + if((MSC_Machine.maxLun > 0) && (maxLunExceed == FALSE)) + { + maxLunExceed = TRUE; + pphost->usr_cb->USBH_USR_DeviceNotSupported(); + + break; + } + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_TEST_UNIT_READY; + } + + if(status == USBH_NOT_SUPPORTED ) + { + /* If the Command has failed, then we need to move to Next State, after + STALL condition is cleared by Control-Transfer */ + USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_TEST_UNIT_READY; + + /* a Clear Feature should be issued here */ + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE; + } + break; + + case USBH_MSC_CTRL_ERROR_STATE: + /* Issue Clearfeature request */ + status = USBH_ClrFeature(pdev, + phost, + 0x00, + pphost->Control.hc_num_out); + if(status == USBH_OK ) + { + /* If GetMaxLun Request not support, assume Single LUN configuration */ + MSC_Machine.maxLun = 0; + + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp; + } + break; + + case USBH_MSC_TEST_UNIT_READY: + /* Issue SCSI command TestUnitReady */ + mscStatus = USBH_MSC_TestUnitReady(pdev); + + if(mscStatus == USBH_MSC_OK ) + { + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_READ_CAPACITY10; + MSCErrorCount = 0; + status = USBH_OK; + } + else + { + USBH_MSC_ErrorHandle(mscStatus); + } + break; + + case USBH_MSC_READ_CAPACITY10: + /* Issue READ_CAPACITY10 SCSI command */ + mscStatus = USBH_MSC_ReadCapacity10(pdev); + if(mscStatus == USBH_MSC_OK ) + { + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_MODE_SENSE6; + MSCErrorCount = 0; + status = USBH_OK; + } + else + { + USBH_MSC_ErrorHandle(mscStatus); + } + break; + + case USBH_MSC_MODE_SENSE6: + /* Issue ModeSense6 SCSI command for detecting if device is write-protected */ + mscStatus = USBH_MSC_ModeSense6(pdev); + if(mscStatus == USBH_MSC_OK ) + { + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE; + MSCErrorCount = 0; + status = USBH_OK; + } + else + { + USBH_MSC_ErrorHandle(mscStatus); + } + break; + + case USBH_MSC_REQUEST_SENSE: + /* Issue RequestSense SCSI command for retreiving error code */ + mscStatus = USBH_MSC_RequestSense(pdev); + if(mscStatus == USBH_MSC_OK ) + { + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp; + status = USBH_OK; + } + else + { + USBH_MSC_ErrorHandle(mscStatus); + } + break; + + case USBH_MSC_BOT_USB_TRANSFERS: + /* Process the BOT state machine */ + USBH_MSC_HandleBOTXfer(pdev , phost); + break; + + case USBH_MSC_DEFAULT_APPLI_STATE: + /* Process Application callback for MSC */ + appliStatus = pphost->usr_cb->USBH_USR_MSC_Application(); + if(appliStatus == 0) + { + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE; + } + else if (appliStatus == 1) + { + /* De-init requested from application layer */ + status = USBH_APPLY_DEINIT; + } + break; + + case USBH_MSC_UNRECOVERED_STATE: + + status = USBH_UNRECOVERED_ERROR; + + break; + + default: + break; + + } + } + return status; +} + + + +/** + * @brief USBH_MSC_BOTReset + * This request is used to reset the mass storage device and its + * associated interface. This class-specific request shall ready the + * device for the next CBW from the host. + * @param pdev: Selected device + * @retval USBH_Status : Status of class request handled. + */ +static USBH_Status USBH_MSC_BOTReset(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost) +{ + + phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | \ + USB_REQ_RECIPIENT_INTERFACE; + + phost->Control.setup.b.bRequest = USB_REQ_BOT_RESET; + phost->Control.setup.b.wValue.w = 0; + phost->Control.setup.b.wIndex.w = 0; + phost->Control.setup.b.wLength.w = 0; + + return USBH_CtlReq(pdev, phost, 0 , 0 ); +} + + +/** + * @brief USBH_MSC_GETMaxLUN + * This request is used to reset the mass storage device and its + * associated interface. This class-specific request shall ready the + * device for the next CBW from the host. + * @param pdev: Selected device + * @retval USBH_Status : USB ctl xfer status + */ +static USBH_Status USBH_MSC_GETMaxLUN(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost) +{ + phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \ + USB_REQ_RECIPIENT_INTERFACE; + + phost->Control.setup.b.bRequest = USB_REQ_GET_MAX_LUN; + phost->Control.setup.b.wValue.w = 0; + phost->Control.setup.b.wIndex.w = 0; + phost->Control.setup.b.wLength.w = 1; + + return USBH_CtlReq(pdev, phost, MSC_Machine.buff , 1 ); +} + +/** + * @brief USBH_MSC_ErrorHandle + * The function is for handling errors occuring during the MSC + * state machine + * @param status + * @retval None + */ + +void USBH_MSC_ErrorHandle(uint8_t status) +{ + if(status == USBH_MSC_FAIL) + { + MSCErrorCount++; + if(MSCErrorCount < USBH_MSC_ERROR_RETRY_LIMIT) + { /* Try MSC level error recovery, Issue the request Sense to get + Drive error reason */ + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_REQUEST_SENSE; + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + } + else + { + /* Error trials exceeded the limit, go to unrecovered state */ + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_UNRECOVERED_STATE; + } + } + else if(status == USBH_MSC_PHASE_ERROR) + { + /* Phase error, Go to Unrecoovered state */ + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_UNRECOVERED_STATE; + } + else if(status == USBH_MSC_BUSY) + { + /*No change in state*/ + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_fatfs.c b/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_fatfs.c new file mode 100644 index 0000000..48d2407 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_fatfs.c @@ -0,0 +1,186 @@ + +#include "usb_conf.h" +#include "diskio.h" +#include "usbh_msc_core.h" +/*-------------------------------------------------------------------------- + +Module Private Functions and Variables + +---------------------------------------------------------------------------*/ + +static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */ + +extern USB_OTG_CORE_HANDLE USB_OTG_Core; +extern USBH_HOST USB_Host; + +/*-----------------------------------------------------------------------*/ +/* Initialize Disk Drive */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_initialize ( + BYTE drv /* Physical drive number (0) */ + ) +{ + + if(HCD_IsDeviceConnected(&USB_OTG_Core)) + { + Stat &= ~STA_NOINIT; + } + + return Stat; + + +} + + + +/*-----------------------------------------------------------------------*/ +/* Get Disk Status */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_status ( + BYTE drv /* Physical drive number (0) */ + ) +{ + if (drv) return STA_NOINIT; /* Supports only single drive */ + return Stat; +} + + + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_read ( + BYTE drv, /* Physical drive number (0) */ + BYTE *buff, /* Pointer to the data buffer to store read data */ + DWORD sector, /* Start sector number (LBA) */ + BYTE count /* Sector count (1..255) */ + ) +{ + BYTE status = USBH_MSC_OK; + + if (drv || !count) return RES_PARERR; + if (Stat & STA_NOINIT) return RES_NOTRDY; + + + if(HCD_IsDeviceConnected(&USB_OTG_Core)) + { + + do + { + status = USBH_MSC_Read10(&USB_OTG_Core, buff, sector, 512*count); + USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host); + + if(!HCD_IsDeviceConnected(&USB_OTG_Core)) + { + return RES_ERROR; + } + } + while(status == USBH_MSC_BUSY ); + } + + if(status == USBH_MSC_OK) + return RES_OK; + return RES_ERROR; + +} + + + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ +/*-----------------------------------------------------------------------*/ + +#if _READONLY == 0 +DRESULT disk_write ( + BYTE drv, /* Physical drive number (0) */ + const BYTE *buff, /* Pointer to the data to be written */ + DWORD sector, /* Start sector number (LBA) */ + BYTE count /* Sector count (1..255) */ + ) +{ + BYTE status = USBH_MSC_OK; + if (drv || !count) return RES_PARERR; + if (Stat & STA_NOINIT) return RES_NOTRDY; + if (Stat & STA_PROTECT) return RES_WRPRT; + + + if(HCD_IsDeviceConnected(&USB_OTG_Core)) + { + do + { + status = USBH_MSC_Write10(&USB_OTG_Core,(BYTE*)buff, sector, 512*count); + USBH_MSC_HandleBOTXfer(&USB_OTG_Core, &USB_Host); + + if(!HCD_IsDeviceConnected(&USB_OTG_Core)) + { + return RES_ERROR; + } + } + + while(status == USBH_MSC_BUSY ); + + } + + if(status == USBH_MSC_OK) + return RES_OK; + return RES_ERROR; +} +#endif /* _READONLY == 0 */ + + + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ +/*-----------------------------------------------------------------------*/ + +#if _USE_IOCTL != 0 +DRESULT disk_ioctl ( + BYTE drv, /* Physical drive number (0) */ + BYTE ctrl, /* Control code */ + void *buff /* Buffer to send/receive control data */ + ) +{ + DRESULT res = RES_OK; + + if (drv) return RES_PARERR; + + res = RES_ERROR; + + if (Stat & STA_NOINIT) return RES_NOTRDY; + + switch (ctrl) { + case CTRL_SYNC : /* Make sure that no pending write process */ + + res = RES_OK; + break; + + case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ + + *(DWORD*)buff = (DWORD) USBH_MSC_Param.MSCapacity; + res = RES_OK; + break; + + case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */ + *(WORD*)buff = 512; + res = RES_OK; + break; + + case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ + + *(DWORD*)buff = 512; + + break; + + + default: + res = RES_PARERR; + } + + + + return res; +} +#endif /* _USE_IOCTL != 0 */ diff --git a/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_scsi.c b/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_scsi.c new file mode 100644 index 0000000..f6bb7c4 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_scsi.c @@ -0,0 +1,674 @@ +/** + ****************************************************************************** + * @file usbh_msc_scsi.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file implements the SCSI commands + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_msc_core.h" +#include "usbh_msc_scsi.h" +#include "usbh_msc_bot.h" +#include "usbh_ioreq.h" +#include "usbh_def.h" + + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_CLASS + * @{ + */ + +/** @addtogroup USBH_MSC_CLASS + * @{ + */ + +/** @defgroup USBH_MSC_SCSI + * @brief This file includes the mass storage related functions + * @{ + */ + + +/** @defgroup USBH_MSC_SCSI_Private_TypesDefinitions + * @{ + */ + +MassStorageParameter_TypeDef USBH_MSC_Param; +/** + * @} + */ + +/** @defgroup USBH_MSC_SCSI_Private_Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_MSC_SCSI_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_MSC_SCSI_Private_Variables + * @{ + */ + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t USBH_DataInBuffer[512] __ALIGN_END ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t USBH_DataOutBuffer[512] __ALIGN_END ; +/** + * @} + */ + + +/** @defgroup USBH_MSC_SCSI_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_MSC_SCSI_Exported_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBH_MSC_SCSI_Private_Functions + * @{ + */ + + + + +/** + * @brief USBH_MSC_TestUnitReady + * Issues 'Test unit ready' command to the device. Once the response + * received, it updates the status to upper layer. + * @param None + * @retval Status + */ +uint8_t USBH_MSC_TestUnitReady (USB_OTG_CORE_HANDLE *pdev) +{ + uint8_t index; + USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; + + if(HCD_IsDeviceConnected(pdev)) + { + switch(USBH_MSC_BOTXferParam.CmdStateMachine) + { + case CMD_SEND_STATE: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = 0; /* No Data Transfer */ + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH_TEST_UNIT_READY; + USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray; + USBH_MSC_BOTXferParam.DataLength = USBH_MSC_CSW_MAX_LENGTH; + USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_TEST_UNIT_READY; + + for(index = CBW_CB_LENGTH; index != 0; index--) + { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_TEST_UNIT_READY; + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; + /* Start the transfer, then let the state + machine magage the other transactions */ + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; + + status = USBH_MSC_BUSY; + break; + + case CMD_WAIT_STATUS: + if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) + { + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + + status = USBH_MSC_OK; + } + else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_FAIL; + } + + else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_PHASE_ERROR; + } + break; + + default: + break; + } + } + return status; +} + + +/** + * @brief USBH_MSC_ReadCapacity10 + * Issue the read capacity command to the device. Once the response + * received, it updates the status to upper layer + * @param None + * @retval Status + */ +uint8_t USBH_MSC_ReadCapacity10(USB_OTG_CORE_HANDLE *pdev) +{ + uint8_t index; + USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; + + if(HCD_IsDeviceConnected(pdev)) + { + switch(USBH_MSC_BOTXferParam.CmdStateMachine) + { + case CMD_SEND_STATE: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_READ_CAPACITY10; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + + USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer; + USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_READ_CAPACITY10; + + for(index = CBW_CB_LENGTH; index != 0; index--) + { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ_CAPACITY10; + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; + + /* Start the transfer, then let the state machine manage the other + transactions */ + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; + + status = USBH_MSC_BUSY; + break; + + case CMD_WAIT_STATUS: + if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) + { + /*assign the capacity*/ + (((uint8_t*)&USBH_MSC_Param.MSCapacity )[3]) = USBH_DataInBuffer[0]; + (((uint8_t*)&USBH_MSC_Param.MSCapacity )[2]) = USBH_DataInBuffer[1]; + (((uint8_t*)&USBH_MSC_Param.MSCapacity )[1]) = USBH_DataInBuffer[2]; + (((uint8_t*)&USBH_MSC_Param.MSCapacity )[0]) = USBH_DataInBuffer[3]; + + /*assign the page length*/ + (((uint8_t*)&USBH_MSC_Param.MSPageLength )[1]) = USBH_DataInBuffer[6]; + (((uint8_t*)&USBH_MSC_Param.MSPageLength )[0]) = USBH_DataInBuffer[7]; + + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_OK; + } + else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_FAIL; + } + else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_PHASE_ERROR; + } + else + { + /* Wait for the Commands to get Completed */ + /* NO Change in state Machine */ + } + break; + + default: + break; + } + } + return status; +} + + +/** + * @brief USBH_MSC_ModeSense6 + * Issue the Mode Sense6 Command to the device. This function is used + * for reading the WriteProtect Status of the Mass-Storage device. + * @param None + * @retval Status + */ +uint8_t USBH_MSC_ModeSense6(USB_OTG_CORE_HANDLE *pdev) +{ + uint8_t index; + USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; + + if(HCD_IsDeviceConnected(pdev)) + { + switch(USBH_MSC_BOTXferParam.CmdStateMachine) + { + case CMD_SEND_STATE: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_MODE_SENSE6; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + + USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer; + USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_MODE_SENSE6; + + for(index = CBW_CB_LENGTH; index != 0; index--) + { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_MODE_SENSE6; + USBH_MSC_CBWData.field.CBWCB[2] = MODE_SENSE_PAGE_CONTROL_FIELD | \ + MODE_SENSE_PAGE_CODE; + + USBH_MSC_CBWData.field.CBWCB[4] = XFER_LEN_MODE_SENSE6; + + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; + + /* Start the transfer, then let the state machine manage the other + transactions */ + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; + + status = USBH_MSC_BUSY; + break; + + case CMD_WAIT_STATUS: + if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) + { + /* Assign the Write Protect status */ + /* If WriteProtect = 0, Writing is allowed + If WriteProtect != 0, Disk is Write Protected */ + if ( USBH_DataInBuffer[2] & MASK_MODE_SENSE_WRITE_PROTECT) + { + USBH_MSC_Param.MSWriteProtect = DISK_WRITE_PROTECTED; + } + else + { + USBH_MSC_Param.MSWriteProtect = 0; + } + + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_OK; + } + else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_FAIL; + } + else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_PHASE_ERROR; + } + else + { + /* Wait for the Commands to get Completed */ + /* NO Change in state Machine */ + } + break; + + default: + break; + } + } + return status; +} + +/** + * @brief USBH_MSC_RequestSense + * Issues the Request Sense command to the device. Once the response + * received, it updates the status to upper layer + * @param None + * @retval Status + */ +uint8_t USBH_MSC_RequestSense(USB_OTG_CORE_HANDLE *pdev) +{ + USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; + + uint8_t index; + + + if(HCD_IsDeviceConnected(pdev)) + { + switch(USBH_MSC_BOTXferParam.CmdStateMachine) + { + case CMD_SEND_STATE: + + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = \ + ALLOCATION_LENGTH_REQUEST_SENSE; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + + USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer; + USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_BOTXferParam.MSCStateCurrent; + USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_REQUEST_SENSE; + + + for(index = CBW_CB_LENGTH; index != 0; index--) + { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_REQUEST_SENSE; + USBH_MSC_CBWData.field.CBWCB[1] = DESC_REQUEST_SENSE; + USBH_MSC_CBWData.field.CBWCB[4] = ALLOCATION_LENGTH_REQUEST_SENSE; + + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; + /* Start the transfer, then let the state machine magage + the other transactions */ + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; + + status = USBH_MSC_BUSY; + + break; + + case CMD_WAIT_STATUS: + + if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) + { + /* Get Sense data*/ + (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[3]) = USBH_DataInBuffer[0]; + (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[2]) = USBH_DataInBuffer[1]; + (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[1]) = USBH_DataInBuffer[2]; + (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[0]) = USBH_DataInBuffer[3]; + + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_OK; + } + else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_FAIL; + } + + else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_PHASE_ERROR; + } + + else + { + /* Wait for the Commands to get Completed */ + /* NO Change in state Machine */ + } + break; + + default: + break; + } + } + return status; +} + + +/** + * @brief USBH_MSC_Write10 + * Issue the write command to the device. Once the response received, + * it updates the status to upper layer + * @param dataBuffer : DataBuffer contains the data to write + * @param address : Address to which the data will be written + * @param nbOfbytes : NbOfbytes to be written + * @retval Status + */ +uint8_t USBH_MSC_Write10(USB_OTG_CORE_HANDLE *pdev, + uint8_t *dataBuffer, + uint32_t address, + uint32_t nbOfbytes) +{ + uint8_t index; + USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; + uint16_t nbOfPages; + + if(HCD_IsDeviceConnected(pdev)) + { + switch(USBH_MSC_BOTXferParam.CmdStateMachine) + { + case CMD_SEND_STATE: + USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer; + + + for(index = CBW_CB_LENGTH; index != 0; index--) + { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_WRITE10; + + /*logical block address*/ + USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]) ; + USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]); + USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]); + USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]); + + /*USBH_MSC_PAGE_LENGTH = 512*/ + nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH; + + /*Tranfer length */ + USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ; + USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ; + + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; + /* Start the transfer, then let the state machine + magage the other transactions */ + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; + + status = USBH_MSC_BUSY; + + break; + + case CMD_WAIT_STATUS: + if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) + { + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_OK; + } + else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + } + + else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_PHASE_ERROR; + } + break; + + default: + break; + } + } + return status; +} + +/** + * @brief USBH_MSC_Read10 + * Issue the read command to the device. Once the response received, + * it updates the status to upper layer + * @param dataBuffer : DataBuffer will contain the data to be read + * @param address : Address from which the data will be read + * @param nbOfbytes : NbOfbytes to be read + * @retval Status + */ +uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev, + uint8_t *dataBuffer, + uint32_t address, + uint32_t nbOfbytes) +{ + uint8_t index; + static USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; + uint16_t nbOfPages; + status = USBH_MSC_BUSY; + + if(HCD_IsDeviceConnected(pdev)) + { + switch(USBH_MSC_BOTXferParam.CmdStateMachine) + { + case CMD_SEND_STATE: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + + USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer; + + for(index = CBW_CB_LENGTH; index != 0; index--) + { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ10; + + /*logical block address*/ + + USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]); + USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]); + USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]); + USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]); + + /*USBH_MSC_PAGE_LENGTH = 512*/ + nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH; + + /*Tranfer length */ + USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ; + USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ; + + + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; + /* Start the transfer, then let the state machine + magage the other transactions */ + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; + + status = USBH_MSC_BUSY; + + break; + + case CMD_WAIT_STATUS: + + if((USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) && \ + (HCD_IsDeviceConnected(pdev))) + { + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_OK; + } + else if (( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) && \ + (HCD_IsDeviceConnected(pdev))) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + } + + else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) + { + /* Failure Mode */ + USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; + status = USBH_MSC_PHASE_ERROR; + } + else + { + /* Wait for the Commands to get Completed */ + /* NO Change in state Machine */ + } + break; + + default: + break; + } + } + return status; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + + diff --git a/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_conf_template.h b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_conf_template.h new file mode 100644 index 0000000..7e41bf8 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_conf_template.h @@ -0,0 +1,94 @@ +/** + ****************************************************************************** + * @file usbh_conf_template + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief General USB Host library configuration + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBH_CONF__H__ +#define __USBH_CONF__H__ + +/* Includes ------------------------------------------------------------------*/ +/** @addtogroup USBH_OTG_DRIVER + * @{ + */ + +/** @defgroup USBH_CONF + * @brief usb otg low level driver configuration file + * @{ + */ + +/** @defgroup USBH_CONF_Exported_Defines + * @{ + */ + +#define USBH_MAX_NUM_ENDPOINTS 2 +#define USBH_MAX_NUM_INTERFACES 2 +#ifdef USE_USB_OTG_FS +#define USBH_MSC_MPS_SIZE 0x40 +#else +#define USBH_MSC_MPS_SIZE 0x200 +#endif + +/** + * @} + */ + + +/** @defgroup USBH_CONF_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_CONF_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_CONF_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_CONF_Exported_FunctionsPrototype + * @{ + */ +/** + * @} + */ + + +#endif //__USBH_CONF__H__ + + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_core.h b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_core.h new file mode 100644 index 0000000..3a8de2c --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_core.h @@ -0,0 +1,289 @@ +/** + ****************************************************************************** + * @file usbh_core.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Header file for usbh_core.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_CORE_H +#define __USBH_CORE_H + +/* Includes ------------------------------------------------------------------*/ +#include "usb_hcd.h" +#include "usbh_def.h" +#include "usbh_conf.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_CORE + * @brief This file is the Header file for usbh_core.c + * @{ + */ + + +/** @defgroup USBH_CORE_Exported_Defines + * @{ + */ + +#define MSC_CLASS 0x08 +#define HID_CLASS 0x03 +#define MSC_PROTOCOL 0x50 +#define CBI_PROTOCOL 0x01 + + +#define USBH_MAX_ERROR_COUNT 2 +#define USBH_DEVICE_ADDRESS_DEFAULT 0 +#define USBH_DEVICE_ADDRESS 1 + + +/** + * @} + */ + + +/** @defgroup USBH_CORE_Exported_Types + * @{ + */ + +typedef enum { + USBH_OK = 0, + USBH_BUSY, + USBH_FAIL, + USBH_NOT_SUPPORTED, + USBH_UNRECOVERED_ERROR, + USBH_ERROR_SPEED_UNKNOWN, + USBH_APPLY_DEINIT +}USBH_Status; + +/* Following states are used for gState */ +typedef enum { + HOST_IDLE =0, + HOST_ISSUE_CORE_RESET, + HOST_DEV_ATTACHED, + HOST_DEV_DISCONNECTED, + HOST_ISSUE_RESET, + HOST_DETECT_DEVICE_SPEED, + HOST_ENUMERATION, + HOST_CLASS_REQUEST, + HOST_CLASS, + HOST_CTRL_XFER, + HOST_USR_INPUT, + HOST_SUSPENDED, + HOST_ERROR_STATE +}HOST_State; + +/* Following states are used for EnumerationState */ +typedef enum { + ENUM_IDLE = 0, + ENUM_GET_FULL_DEV_DESC, + ENUM_SET_ADDR, + ENUM_GET_CFG_DESC, + ENUM_GET_FULL_CFG_DESC, + ENUM_GET_MFC_STRING_DESC, + ENUM_GET_PRODUCT_STRING_DESC, + ENUM_GET_SERIALNUM_STRING_DESC, + ENUM_SET_CONFIGURATION, + ENUM_DEV_CONFIGURED +} ENUM_State; + + + +/* Following states are used for CtrlXferStateMachine */ +typedef enum { + CTRL_IDLE =0, + CTRL_SETUP, + CTRL_SETUP_WAIT, + CTRL_DATA_IN, + CTRL_DATA_IN_WAIT, + CTRL_DATA_OUT, + CTRL_DATA_OUT_WAIT, + CTRL_STATUS_IN, + CTRL_STATUS_IN_WAIT, + CTRL_STATUS_OUT, + CTRL_STATUS_OUT_WAIT, + CTRL_ERROR +} +CTRL_State; + +typedef enum { + USBH_USR_NO_RESP = 0, + USBH_USR_RESP_OK = 1, +} +USBH_USR_Status; + +/* Following states are used for RequestState */ +typedef enum { + CMD_IDLE =0, + CMD_SEND, + CMD_WAIT +} CMD_State; + + + +typedef struct _Ctrl +{ + uint8_t hc_num_in; + uint8_t hc_num_out; + uint8_t ep0size; + uint8_t *buff; + uint16_t length; + uint8_t errorcount; + uint16_t timer; + CTRL_STATUS status; + USB_Setup_TypeDef setup; + CTRL_State state; + +} USBH_Ctrl_TypeDef; + + + +typedef struct _DeviceProp +{ + + uint8_t address; + uint8_t speed; + USBH_DevDesc_TypeDef Dev_Desc; + USBH_CfgDesc_TypeDef Cfg_Desc; + USBH_InterfaceDesc_TypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES]; + USBH_EpDesc_TypeDef Ep_Desc[USBH_MAX_NUM_INTERFACES][USBH_MAX_NUM_ENDPOINTS]; + USBH_HIDDesc_TypeDef HID_Desc; + +}USBH_Device_TypeDef; + +typedef struct _USBH_Class_cb +{ + USBH_Status (*Init)\ + (USB_OTG_CORE_HANDLE *pdev , void *phost); + void (*DeInit)\ + (USB_OTG_CORE_HANDLE *pdev , void *phost); + USBH_Status (*Requests)\ + (USB_OTG_CORE_HANDLE *pdev , void *phost); + USBH_Status (*Machine)\ + (USB_OTG_CORE_HANDLE *pdev , void *phost); + +} USBH_Class_cb_TypeDef; + + +typedef struct _USBH_USR_PROP +{ + void (*Init)(void); /* HostLibInitialized */ + void (*DeInit)(void); /* HostLibInitialized */ + void (*DeviceAttached)(void); /* DeviceAttached */ + void (*ResetDevice)(void); + void (*DeviceDisconnected)(void); + void (*OverCurrentDetected)(void); + void (*DeviceSpeedDetected)(uint8_t DeviceSpeed); /* DeviceSpeed */ + void (*DeviceDescAvailable)(void *); /* DeviceDescriptor is available */ + void (*DeviceAddressAssigned)(void); /* Address is assigned to USB Device */ + void (*ConfigurationDescAvailable)(USBH_CfgDesc_TypeDef *, + USBH_InterfaceDesc_TypeDef *, + USBH_EpDesc_TypeDef *); + /* Configuration Descriptor available */ + void (*ManufacturerString)(void *); /* ManufacturerString*/ + void (*ProductString)(void *); /* ProductString*/ + void (*SerialNumString)(void *); /* SerialNubString*/ + void (*EnumerationDone)(void); /* Enumeration finished */ + USBH_USR_Status (*UserInput)(void); + int (*USBH_USR_MSC_Application) (void); + void (*USBH_USR_DeviceNotSupported)(void); /* Device is not supported*/ + void (*UnrecoveredError)(void); + +} +USBH_Usr_cb_TypeDef; + +typedef struct _Host_TypeDef +{ + HOST_State gState; /* Host State Machine Value */ + HOST_State gStateBkp; /* backup of previous State machine value */ + ENUM_State EnumState; /* Enumeration state Machine */ + CMD_State RequestState; + USBH_Ctrl_TypeDef Control; + + USBH_Device_TypeDef device_prop; + + USBH_Class_cb_TypeDef *class_cb; + USBH_Usr_cb_TypeDef *usr_cb; + + +} USBH_HOST, *pUSBH_HOST; + +/** + * @} + */ + + + +/** @defgroup USBH_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBH_CORE_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBH_CORE_Exported_FunctionsPrototype + * @{ + */ +void USBH_Init(USB_OTG_CORE_HANDLE *pdev, + USB_OTG_CORE_ID_TypeDef coreID, + USBH_HOST *phost, + USBH_Class_cb_TypeDef *class_cb, + USBH_Usr_cb_TypeDef *usr_cb); + +USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost); +void USBH_Process(USB_OTG_CORE_HANDLE *pdev , + USBH_HOST *phost); +void USBH_ErrorHandle(USBH_HOST *phost, + USBH_Status errType); + +/** + * @} + */ + +#endif /* __USBH_CORE_H */ +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + + diff --git a/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_def.h b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_def.h new file mode 100644 index 0000000..35ebeb4 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_def.h @@ -0,0 +1,280 @@ +/** + ****************************************************************************** + * @file usbh_def.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Definitions used in the USB host library + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_DEF + * @brief This file is includes USB descriptors + * @{ + */ + +#ifndef USBH_DEF_H +#define USBH_DEF_H + +#ifndef USBH_NULL +#define USBH_NULL ((void *)0) +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + + +#define ValBit(VAR,POS) (VAR & (1 << POS)) +#define SetBit(VAR,POS) (VAR |= (1 << POS)) +#define ClrBit(VAR,POS) (VAR &= ((1 << POS)^255)) + +#define LE16(addr) (((u16)(*((u8 *)(addr))))\ + + (((u16)(*(((u8 *)(addr)) + 1))) << 8)) + +#define USB_LEN_DESC_HDR 0x02 +#define USB_LEN_DEV_DESC 0x12 +#define USB_LEN_CFG_DESC 0x09 +#define USB_LEN_IF_DESC 0x09 +#define USB_LEN_EP_DESC 0x07 +#define USB_LEN_OTG_DESC 0x03 +#define USB_LEN_SETUP_PKT 0x08 + +/* bmRequestType :D7 Data Phase Transfer Direction */ +#define USB_REQ_DIR_MASK 0x80 +#define USB_H2D 0x00 +#define USB_D2H 0x80 + +/* bmRequestType D6..5 Type */ +#define USB_REQ_TYPE_STANDARD 0x00 +#define USB_REQ_TYPE_CLASS 0x20 +#define USB_REQ_TYPE_VENDOR 0x40 +#define USB_REQ_TYPE_RESERVED 0x60 + +/* bmRequestType D4..0 Recipient */ +#define USB_REQ_RECIPIENT_DEVICE 0x00 +#define USB_REQ_RECIPIENT_INTERFACE 0x01 +#define USB_REQ_RECIPIENT_ENDPOINT 0x02 +#define USB_REQ_RECIPIENT_OTHER 0x03 + +/* Table 9-4. Standard Request Codes */ +/* bRequest , Value */ +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +/* Table 9-5. Descriptor Types of USB Specifications */ +#define USB_DESC_TYPE_DEVICE 1 +#define USB_DESC_TYPE_CONFIGURATION 2 +#define USB_DESC_TYPE_STRING 3 +#define USB_DESC_TYPE_INTERFACE 4 +#define USB_DESC_TYPE_ENDPOINT 5 +#define USB_DESC_TYPE_DEVICE_QUALIFIER 6 +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 +#define USB_DESC_TYPE_INTERFACE_POWER 8 +#define USB_DESC_TYPE_HID 0x21 +#define USB_DESC_TYPE_HID_REPORT 0x22 + + +#define USB_DEVICE_DESC_SIZE 18 +#define USB_CONFIGURATION_DESC_SIZE 9 +#define USB_HID_DESC_SIZE 9 +#define USB_INTERFACE_DESC_SIZE 9 +#define USB_ENDPOINT_DESC_SIZE 7 + +/* Descriptor Type and Descriptor Index */ +/* Use the following values when calling the function USBH_GetDescriptor */ +#define USB_DESC_DEVICE ((USB_DESC_TYPE_DEVICE << 8) & 0xFF00) +#define USB_DESC_CONFIGURATION ((USB_DESC_TYPE_CONFIGURATION << 8) & 0xFF00) +#define USB_DESC_STRING ((USB_DESC_TYPE_STRING << 8) & 0xFF00) +#define USB_DESC_INTERFACE ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00) +#define USB_DESC_ENDPOINT ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00) +#define USB_DESC_DEVICE_QUALIFIER ((USB_DESC_TYPE_DEVICE_QUALIFIER << 8) & 0xFF00) +#define USB_DESC_OTHER_SPEED_CONFIGURATION ((USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8) & 0xFF00) +#define USB_DESC_INTERFACE_POWER ((USB_DESC_TYPE_INTERFACE_POWER << 8) & 0xFF00) +#define USB_DESC_HID_REPORT ((USB_DESC_TYPE_HID_REPORT << 8) & 0xFF00) +#define USB_DESC_HID ((USB_DESC_TYPE_HID << 8) & 0xFF00) + + +#define USB_EP_TYPE_CTRL 0x00 +#define USB_EP_TYPE_ISOC 0x01 +#define USB_EP_TYPE_BULK 0x02 +#define USB_EP_TYPE_INTR 0x03 + +#define USB_EP_DIR_OUT 0x00 +#define USB_EP_DIR_IN 0x80 +#define USB_EP_DIR_MSK 0x80 + +/* supported classes */ +#define USB_MSC_CLASS 0x08 +#define USB_HID_CLASS 0x03 + +/* Interface Descriptor field values for HID Boot Protocol */ +#define HID_BOOT_CODE 0x01 +#define HID_KEYBRD_BOOT_CODE 0x01 +#define HID_MOUSE_BOOT_CODE 0x02 + +/* As per USB specs 9.2.6.4 :Standard request with data request timeout: 5sec + Standard request with no data stage timeout : 50ms */ +#define DATA_STAGE_TIMEOUT 5000 +#define NODATA_STAGE_TIMEOUT 50 + +/** + * @} + */ + + +#define USBH_CONFIGURATION_DESCRIPTOR_SIZE (USB_CONFIGURATION_DESC_SIZE \ + + USB_INTERFACE_DESC_SIZE\ + + (USBH_MAX_NUM_ENDPOINTS * USB_ENDPOINT_DESC_SIZE)) + + +#define CONFIG_DESC_wTOTAL_LENGTH (ConfigurationDescriptorData.ConfigDescfield.\ + ConfigurationDescriptor.wTotalLength) + + +/* This Union is copied from usb_core.h */ +typedef union +{ + uint16_t w; + struct BW + { + uint8_t msb; + uint8_t lsb; + } + bw; +} +uint16_t_uint8_t; + + +typedef union _USB_Setup +{ + uint8_t d8[8]; + + struct _SetupPkt_Struc + { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t_uint8_t wValue; + uint16_t_uint8_t wIndex; + uint16_t_uint8_t wLength; + } b; +} +USB_Setup_TypeDef; + +typedef struct _DescHeader +{ + uint8_t bLength; + uint8_t bDescriptorType; +} +USBH_DescHeader_t; + +typedef struct _DeviceDescriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; /* USB Specification Number which device complies too */ + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + /* If equal to Zero, each interface specifies its own class + code if equal to 0xFF, the class code is vendor specified. + Otherwise field is valid Class Code.*/ + uint8_t bMaxPacketSize; + uint16_t idVendor; /* Vendor ID (Assigned by USB Org) */ + uint16_t idProduct; /* Product ID (Assigned by Manufacturer) */ + uint16_t bcdDevice; /* Device Release Number */ + uint8_t iManufacturer; /* Index of Manufacturer String Descriptor */ + uint8_t iProduct; /* Index of Product String Descriptor */ + uint8_t iSerialNumber; /* Index of Serial Number String Descriptor */ + uint8_t bNumConfigurations; /* Number of Possible Configurations */ +} +USBH_DevDesc_TypeDef; + + +typedef struct _ConfigurationDescriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; /* Total Length of Data Returned */ + uint8_t bNumInterfaces; /* Number of Interfaces */ + uint8_t bConfigurationValue; /* Value to use as an argument to select this configuration*/ + uint8_t iConfiguration; /*Index of String Descriptor Describing this configuration */ + uint8_t bmAttributes; /* D7 Bus Powered , D6 Self Powered, D5 Remote Wakeup , D4..0 Reserved (0)*/ + uint8_t bMaxPower; /*Maximum Power Consumption */ +} +USBH_CfgDesc_TypeDef; + + +typedef struct _HIDDescriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdHID; /* indicates what endpoint this descriptor is describing */ + uint8_t bCountryCode; /* specifies the transfer type. */ + uint8_t bNumDescriptors; /* specifies the transfer type. */ + uint8_t bReportDescriptorType; /* Maximum Packet Size this endpoint is capable of sending or receiving */ + uint16_t wItemLength; /* is used to specify the polling interval of certain transfers. */ +} +USBH_HIDDesc_TypeDef; + + +typedef struct _InterfaceDescriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; /* Value used to select alternative setting */ + uint8_t bNumEndpoints; /* Number of Endpoints used for this interface */ + uint8_t bInterfaceClass; /* Class Code (Assigned by USB Org) */ + uint8_t bInterfaceSubClass; /* Subclass Code (Assigned by USB Org) */ + uint8_t bInterfaceProtocol; /* Protocol Code */ + uint8_t iInterface; /* Index of String Descriptor Describing this interface */ + +} +USBH_InterfaceDesc_TypeDef; + + +typedef struct _EndpointDescriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; /* indicates what endpoint this descriptor is describing */ + uint8_t bmAttributes; /* specifies the transfer type. */ + uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving */ + uint8_t bInterval; /* is used to specify the polling interval of certain transfers. */ +} +USBH_EpDesc_TypeDef; +#endif +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_hcs.h b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_hcs.h new file mode 100644 index 0000000..c5310b2 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_hcs.h @@ -0,0 +1,125 @@ +/** + ****************************************************************************** + * @file usbh_hcs.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Header file for usbh_hcs.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_HCS_H +#define __USBH_HCS_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_core.h" + + + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_HCS + * @brief This file is the header file for usbh_hcs.c + * @{ + */ + +/** @defgroup USBH_HCS_Exported_Defines + * @{ + */ +#define HC_MAX 8 + +#define HC_OK 0x0000 +#define HC_USED 0x8000 +#define HC_ERROR 0xFFFF +#define HC_USED_MASK 0x7FFF +/** + * @} + */ + +/** @defgroup USBH_HCS_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_HCS_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_HCS_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_HCS_Exported_FunctionsPrototype + * @{ + */ + +uint8_t USBH_Alloc_Channel(USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr); + +uint8_t USBH_Free_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t idx); + +uint8_t USBH_DeAllocate_AllChannel (USB_OTG_CORE_HANDLE *pdev); + +uint8_t USBH_Open_Channel (USB_OTG_CORE_HANDLE *pdev, + uint8_t ch_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps); + +uint8_t USBH_Modify_Channel (USB_OTG_CORE_HANDLE *pdev, + uint8_t hc_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps); +/** + * @} + */ + + + +#endif /* __USBH_HCS_H */ + + +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + diff --git a/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_ioreq.h b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_ioreq.h new file mode 100644 index 0000000..4bdd436 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_ioreq.h @@ -0,0 +1,140 @@ +/** + ****************************************************************************** + * @file usbh_ioreq.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Header file for usbh_ioreq.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_IOREQ_H +#define __USBH_IOREQ_H + +/* Includes ------------------------------------------------------------------*/ +#include "usb_conf.h" +#include "usbh_core.h" +#include "usbh_def.h" + + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_IOREQ + * @brief This file is the header file for usbh_ioreq.c + * @{ + */ + + +/** @defgroup USBH_IOREQ_Exported_Defines + * @{ + */ +#define USBH_SETUP_PKT_SIZE 8 +#define USBH_EP0_EP_NUM 0 +#define USBH_MAX_PACKET_SIZE 0x40 +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_IOREQ_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_IOREQ_Exported_FunctionsPrototype + * @{ + */ +USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t hc_num); + +USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t length, + uint8_t hc_num); + +USBH_Status USBH_CtlReceiveData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t length, + uint8_t hc_num); + +USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint16_t length, + uint8_t hc_num); + +USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint16_t length, + uint8_t hc_num); + +USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t length, + uint8_t hc_num); + +USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t length, + uint8_t hc_num); + +USBH_Status USBH_CtlReq (USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t *buff, + uint16_t length); +/** + * @} + */ + +#endif /* __USBH_IOREQ_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + diff --git a/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_stdreq.h b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_stdreq.h new file mode 100644 index 0000000..22bf3d1 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Core/inc/usbh_stdreq.h @@ -0,0 +1,148 @@ +/** + ****************************************************************************** + * @file usbh_stdreq.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Header file for usbh_stdreq.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_STDREQ_H +#define __USBH_STDREQ_H + +/* Includes ------------------------------------------------------------------*/ + +#include "usb_conf.h" +#include "usb_hcd.h" +#include "usbh_core.h" +#include "usbh_def.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_STDREQ + * @brief This file is the + * @{ + */ + + +/** @defgroup USBH_STDREQ_Exported_Defines + * @{ + */ +/*Standard Feature Selector for clear feature command*/ +#define FEATURE_SELECTOR_ENDPOINT 0X00 +#define FEATURE_SELECTOR_DEVICE 0X01 + + +#define INTERFACE_DESC_TYPE 0x04 +#define ENDPOINT_DESC_TYPE 0x05 +#define INTERFACE_DESC_SIZE 0x09 + + +#define USBH_HID_CLASS 0x03 + +/** + * @} + */ + + +/** @defgroup USBH_STDREQ_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_STDREQ_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_STDREQ_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_STDREQ_Exported_FunctionsPrototype + * @{ + */ +USBH_Status USBH_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t req_type, + uint16_t value_idx, + uint8_t* buff, + uint16_t length ); + +USBH_Status USBH_Get_DevDesc(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t length); + +USBH_Status USBH_Get_StringDesc(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t string_index, + uint8_t *buff, + uint16_t length); + +USBH_Status USBH_SetCfg(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint16_t configuration_value); + +USBH_Status USBH_Get_CfgDesc(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint16_t length); + +USBH_Status USBH_SetAddress(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t DeviceAddress); + +USBH_Status USBH_ClrFeature(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t ep_num, uint8_t hc_num); + +USBH_Status USBH_Issue_ClrFeature(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t ep_num); +/** + * @} + */ + +#endif /* __USBH_STDREQ_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + diff --git a/Libraries/STM32_USB_HOST_Library/Core/src/usbh_core.c b/Libraries/STM32_USB_HOST_Library/Core/src/usbh_core.c new file mode 100644 index 0000000..a155357 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Core/src/usbh_core.c @@ -0,0 +1,842 @@ +/** + ****************************************************************************** + * @file usbh_core.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file implements the functions for the core state machine process + * the enumeration and the control transfer process + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ + +#include "usbh_ioreq.h" +#include "usb_bsp.h" +#include "usbh_hcs.h" +#include "usbh_stdreq.h" +#include "usbh_core.h" + + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_CORE + * @brief TThis file handles the basic enumaration when a device is connected + * to the host. + * @{ + */ + +/** @defgroup USBH_CORE_Private_TypesDefinitions + * @{ + */ +void USBH_Disconnect (void *pdev); +void USBH_Connect (void *pdev); + +USB_OTG_hPort_TypeDef USBH_DeviceConnStatus_cb = +{ + USBH_Disconnect, + USBH_Connect, + 0, + 0, + 0, + 0 +}; +/** + * @} + */ + + +/** @defgroup USBH_CORE_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_CORE_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_CORE_Private_Variables + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_CORE_Private_FunctionPrototypes + * @{ + */ +static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost); +USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost); + +/** + * @} + */ + + +/** @defgroup USBH_CORE_Private_Functions + * @{ + */ + + +/** + * @brief USBH_Connect + * USB Connect callback function from the Interrupt. + * @param selected device + * @retval none + */ +void USBH_Connect (void *pdev) +{ + USB_OTG_CORE_HANDLE *ppdev = pdev; + ppdev->host.port_cb->ConnStatus = 1; + ppdev->host.port_cb->ConnHandled = 0; +} + +/** + * @brief USBH_Disconnect + * USB Disconnect callback function from the Interrupt. + * @param selected device + * @retval none + */ + +void USBH_Disconnect (void *pdev) +{ + + USB_OTG_CORE_HANDLE *ppdev = pdev; + + /* Make device Not connected flag true */ + ppdev->host.port_cb->DisconnStatus = 1; + ppdev->host.port_cb->DisconnHandled = 0; +} + +/** + * @brief USBH_Init + * Host hardware and stack initializations + * @param class_cb: Class callback structure address + * @param usr_cb: User callback structure address + * @retval None + */ +void USBH_Init(USB_OTG_CORE_HANDLE *pdev, + USB_OTG_CORE_ID_TypeDef coreID, + USBH_HOST *phost, + USBH_Class_cb_TypeDef *class_cb, + USBH_Usr_cb_TypeDef *usr_cb) +{ + + /* Hardware Init */ + USB_OTG_BSP_Init(pdev); + + /* configure GPIO pin used for switching VBUS power */ + USB_OTG_BSP_ConfigVBUS(0); + + + /* Host de-initializations */ + USBH_DeInit(pdev, phost); + + /*Register class and user callbacks */ + phost->class_cb = class_cb; + phost->usr_cb = usr_cb; + pdev->host.port_cb = &USBH_DeviceConnStatus_cb; + + pdev->host.port_cb->ConnStatus = 0; + pdev->host.port_cb->DisconnStatus = 0; + + + /* Start the USB OTG core */ + HCD_Init(pdev , coreID); + + /* Upon Init call usr call back */ + phost->usr_cb->Init(); + + /* Enable Interrupts */ + USB_OTG_BSP_EnableInterrupt(pdev); +} + +/** + * @brief USBH_DeInit + * Re-Initialize Host + * @param None + * @retval status: USBH_Status + */ +USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost) +{ + /* Software Init */ + + phost->gState = HOST_IDLE; + phost->gStateBkp = HOST_IDLE; + phost->EnumState = ENUM_IDLE; + phost->RequestState = CMD_SEND; + + phost->Control.state = CTRL_SETUP; + phost->Control.ep0size = USB_OTG_MAX_EP0_SIZE; + + phost->device_prop.address = USBH_DEVICE_ADDRESS_DEFAULT; + phost->device_prop.speed = HPRT0_PRTSPD_FULL_SPEED; + + USBH_Free_Channel (pdev, phost->Control.hc_num_in); + USBH_Free_Channel (pdev, phost->Control.hc_num_out); + return USBH_OK; +} + +/** +* @brief USBH_Process +* USB Host core main state machine process +* @param None +* @retval None +*/ +void USBH_Process(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost) +{ + volatile USBH_Status status = USBH_FAIL; + + switch (phost->gState) + { + case HOST_ISSUE_CORE_RESET : + + if ( HCD_ResetPort(pdev) == 0) + { + phost->gState = HOST_IDLE; + } + break; + + case HOST_IDLE : + + if (HCD_IsDeviceConnected(pdev)) + { + /* Wait for USB Connect Interrupt void USBH_ISR_Connected(void) */ + USBH_DeAllocate_AllChannel(pdev); + phost->gState = HOST_DEV_ATTACHED; + } + break; + + case HOST_DEV_ATTACHED : + + phost->usr_cb->DeviceAttached(); + pdev->host.port_cb->DisconnStatus = 0; + pdev->host.port_cb->ConnHandled = 1; + + phost->Control.hc_num_out = USBH_Alloc_Channel(pdev, 0x00); + phost->Control.hc_num_in = USBH_Alloc_Channel(pdev, 0x80); + + /* Reset USB Device */ + if ( HCD_ResetPort(pdev) == 0) + { + phost->usr_cb->ResetDevice(); + /* Wait for USB USBH_ISR_PrtEnDisableChange() + Host is Now ready to start the Enumeration + */ + + phost->device_prop.speed = HCD_GetCurrentSpeed(pdev); + + phost->gState = HOST_ENUMERATION; + phost->usr_cb->DeviceSpeedDetected(phost->device_prop.speed); + + /* Open Control pipes */ + USBH_Open_Channel (pdev, + phost->Control.hc_num_in, + phost->device_prop.address, + phost->device_prop.speed, + EP_TYPE_CTRL, + phost->Control.ep0size); + + /* Open Control pipes */ + USBH_Open_Channel (pdev, + phost->Control.hc_num_out, + phost->device_prop.address, + phost->device_prop.speed, + EP_TYPE_CTRL, + phost->Control.ep0size); + } + break; + + case HOST_ENUMERATION: + /* Check for enumeration status */ + if ( USBH_HandleEnum(pdev , phost) == USBH_OK) + { + /* The function shall return USBH_OK when full enumeration is complete */ + + /* user callback for end of device basic enumeration */ + phost->usr_cb->EnumerationDone(); + + phost->gState = HOST_USR_INPUT; + } + break; + + case HOST_USR_INPUT: + /*The function should return user response true to move to class state */ + if ( phost->usr_cb->UserInput() == USBH_USR_RESP_OK) + { + if((phost->class_cb->Init(pdev, phost))\ + == USBH_OK) + { + phost->gState = HOST_CLASS_REQUEST; + } + } + break; + + case HOST_CLASS_REQUEST: + /* process class standard contol requests state machine */ + status = phost->class_cb->Requests(pdev, phost); + + if(status == USBH_OK) + { + phost->gState = HOST_CLASS; + } + + else + { + USBH_ErrorHandle(phost, status); + } + + + break; + case HOST_CLASS: + /* process class state machine */ + status = phost->class_cb->Machine(pdev, phost); + USBH_ErrorHandle(phost, status); + break; + + case HOST_CTRL_XFER: + /* process control transfer state machine */ + USBH_HandleControl(pdev, phost); + break; + + case HOST_SUSPENDED: + break; + + case HOST_ERROR_STATE: + /* Re-Initilaize Host for new Enumeration */ + USBH_DeInit(pdev, phost); + phost->usr_cb->DeInit(); + phost->class_cb->DeInit(pdev, &phost->device_prop); + break; + + default : + break; + } + + /* check device disconnection event */ + if (!(HCD_IsDeviceConnected(pdev)) && + (pdev->host.port_cb->DisconnHandled == 0)) + { + /* Manage User disconnect operations*/ + phost->usr_cb->DeviceDisconnected(); + + pdev->host.port_cb->DisconnHandled = 1; /* Handle to avoid the Re-entry*/ + + /* Re-Initilaize Host for new Enumeration */ + USBH_DeInit(pdev, phost); + phost->usr_cb->DeInit(); + phost->class_cb->DeInit(pdev, &phost->device_prop); + } +} + + +/** + * @brief USBH_ErrorHandle + * This function handles the Error on Host side. + * @param errType : Type of Error or Busy/OK state + * @retval None + */ +void USBH_ErrorHandle(USBH_HOST *phost, USBH_Status errType) +{ + /* Error unrecovered or not supported device speed */ + if ( (errType == USBH_ERROR_SPEED_UNKNOWN) || + (errType == USBH_UNRECOVERED_ERROR) ) + { + phost->usr_cb->UnrecoveredError(); + phost->gState = HOST_ERROR_STATE; + } + /* USB host restart requested from application layer */ + else if(errType == USBH_APPLY_DEINIT) + { + phost->gState = HOST_ERROR_STATE; + /* user callback for initalization */ + phost->usr_cb->Init(); + } +} + + +/** + * @brief USBH_HandleEnum + * This function includes the complete enumeration process + * @param pdev: Selected device + * @retval USBH_Status + */ +static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost) +{ + USBH_Status Status = USBH_BUSY; + uint8_t Local_Buffer[64]; + + switch (phost->EnumState) + { + case ENUM_IDLE: + /* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */ + if ( USBH_Get_DevDesc(pdev , phost, 8) == USBH_OK) + { + phost->Control.ep0size = phost->device_prop.Dev_Desc.bMaxPacketSize; + + /* Issue Reset */ + HCD_ResetPort(pdev); + phost->EnumState = ENUM_GET_FULL_DEV_DESC; + + /* modify control channels configuration for MaxPacket size */ + USBH_Modify_Channel (pdev, + phost->Control.hc_num_out, + 0, + 0, + 0, + phost->Control.ep0size); + + USBH_Modify_Channel (pdev, + phost->Control.hc_num_in, + 0, + 0, + 0, + phost->Control.ep0size); + } + break; + + case ENUM_GET_FULL_DEV_DESC: + /* Get FULL Device Desc */ + if ( USBH_Get_DevDesc(pdev, phost, USB_DEVICE_DESC_SIZE)\ + == USBH_OK) + { + /* user callback for device descriptor available */ + phost->usr_cb->DeviceDescAvailable(&phost->device_prop.Dev_Desc); + phost->EnumState = ENUM_SET_ADDR; + } + break; + + case ENUM_SET_ADDR: + /* set address */ + if ( USBH_SetAddress(pdev, phost, USBH_DEVICE_ADDRESS) == USBH_OK) + { + phost->device_prop.address = USBH_DEVICE_ADDRESS; + + /* user callback for device address assigned */ + phost->usr_cb->DeviceAddressAssigned(); + phost->EnumState = ENUM_GET_CFG_DESC; + + /* modify control channels to update device address */ + USBH_Modify_Channel (pdev, + phost->Control.hc_num_in, + phost->device_prop.address, + 0, + 0, + 0); + + USBH_Modify_Channel (pdev, + phost->Control.hc_num_out, + phost->device_prop.address, + 0, + 0, + 0); + } + break; + + case ENUM_GET_CFG_DESC: + /* get standard configuration descriptor */ + if ( USBH_Get_CfgDesc(pdev, + phost, + USB_CONFIGURATION_DESC_SIZE) == USBH_OK) + { + phost->EnumState = ENUM_GET_FULL_CFG_DESC; + } + break; + + case ENUM_GET_FULL_CFG_DESC: + /* get FULL config descriptor (config, interface, endpoints) */ + if (USBH_Get_CfgDesc(pdev, + phost, + phost->device_prop.Cfg_Desc.wTotalLength) == USBH_OK) + { + /* User callback for configuration descriptors available */ + phost->usr_cb->ConfigurationDescAvailable(&phost->device_prop.Cfg_Desc, + phost->device_prop.Itf_Desc, + phost->device_prop.Ep_Desc[0]); + + phost->EnumState = ENUM_GET_MFC_STRING_DESC; + } + break; + + case ENUM_GET_MFC_STRING_DESC: + if (phost->device_prop.Dev_Desc.iManufacturer != 0) + { /* Check that Manufacturer String is available */ + + if ( USBH_Get_StringDesc(pdev, + phost, + phost->device_prop.Dev_Desc.iManufacturer, + Local_Buffer , + 0xff) == USBH_OK) + { + /* User callback for Manufacturing string */ + phost->usr_cb->ManufacturerString(Local_Buffer); + phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC; + } + } + else + { + phost->usr_cb->ManufacturerString("N/A"); + phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC; + } + break; + + case ENUM_GET_PRODUCT_STRING_DESC: + if (phost->device_prop.Dev_Desc.iProduct != 0) + { /* Check that Product string is available */ + if ( USBH_Get_StringDesc(pdev, + phost, + phost->device_prop.Dev_Desc.iProduct, + Local_Buffer, + 0xff) == USBH_OK) + { + /* User callback for Product string */ + phost->usr_cb->ProductString(Local_Buffer); + phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC; + } + } + else + { + phost->usr_cb->ProductString("N/A"); + phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC; + } + break; + + case ENUM_GET_SERIALNUM_STRING_DESC: + if (phost->device_prop.Dev_Desc.iSerialNumber != 0) + { /* Check that Serial number string is available */ + if ( USBH_Get_StringDesc(pdev, + phost, + phost->device_prop.Dev_Desc.iSerialNumber, + Local_Buffer, + 0xff) == USBH_OK) + { + /* User callback for Serial number string */ + phost->usr_cb->SerialNumString(Local_Buffer); + phost->EnumState = ENUM_SET_CONFIGURATION; + } + } + else + { + phost->usr_cb->SerialNumString("N/A"); + phost->EnumState = ENUM_SET_CONFIGURATION; + } + break; + + case ENUM_SET_CONFIGURATION: + /* set configuration (default config) */ + if (USBH_SetCfg(pdev, + phost, + phost->device_prop.Cfg_Desc.bConfigurationValue) == USBH_OK) + { + phost->EnumState = ENUM_DEV_CONFIGURED; + } + break; + + + case ENUM_DEV_CONFIGURED: + /* user callback for enumeration done */ + Status = USBH_OK; + break; + + default: + break; + } + return Status; +} + + +/** + * @brief USBH_HandleControl + * Handles the USB control transfer state machine + * @param pdev: Selected device + * @retval Status + */ +USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost) +{ + uint8_t direction; + static uint16_t timeout = 0; + USBH_Status status = USBH_OK; + URB_STATE URB_Status = URB_IDLE; + + phost->Control.status = CTRL_START; + + + switch (phost->Control.state) + { + case CTRL_SETUP: + /* send a SETUP packet */ + USBH_CtlSendSetup (pdev, + phost->Control.setup.d8 , + phost->Control.hc_num_out); + phost->Control.state = CTRL_SETUP_WAIT; + break; + + case CTRL_SETUP_WAIT: + + URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out); + /* case SETUP packet sent successfully */ + if(URB_Status == URB_DONE) + { + direction = (phost->Control.setup.b.bmRequestType & USB_REQ_DIR_MASK); + + /* check if there is a data stage */ + if (phost->Control.setup.b.wLength.w != 0 ) + { + timeout = DATA_STAGE_TIMEOUT; + if (direction == USB_D2H) + { + /* Data Direction is IN */ + phost->Control.state = CTRL_DATA_IN; + } + else + { + /* Data Direction is OUT */ + phost->Control.state = CTRL_DATA_OUT; + } + } + /* No DATA stage */ + else + { + timeout = NODATA_STAGE_TIMEOUT; + + /* If there is No Data Transfer Stage */ + if (direction == USB_D2H) + { + /* Data Direction is IN */ + phost->Control.state = CTRL_STATUS_OUT; + } + else + { + /* Data Direction is OUT */ + phost->Control.state = CTRL_STATUS_IN; + } + } + /* Set the delay timer to enable timeout for data stage completion */ + phost->Control.timer = HCD_GetCurrentFrame(pdev); + } + else if(URB_Status == URB_ERROR) + { + phost->Control.state = CTRL_ERROR; + phost->Control.status = CTRL_XACTERR; + } + break; + + case CTRL_DATA_IN: + /* Issue an IN token */ + USBH_CtlReceiveData(pdev, + phost->Control.buff, + phost->Control.length, + phost->Control.hc_num_in); + + phost->Control.state = CTRL_DATA_IN_WAIT; + break; + + case CTRL_DATA_IN_WAIT: + + URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in); + + /* check is DATA packet transfered successfully */ + if (URB_Status == URB_DONE) + { + phost->Control.state = CTRL_STATUS_OUT; + } + + /* manage error cases*/ + if (URB_Status == URB_STALL) + { + /* In stall case, return to previous machine state*/ + phost->gState = phost->gStateBkp; + } + else if (URB_Status == URB_ERROR) + { + /* Device error */ + phost->Control.state = CTRL_ERROR; + } + else if ((HCD_GetCurrentFrame(pdev)- phost->Control.timer) > timeout) + { + /* timeout for IN transfer */ + phost->Control.state = CTRL_ERROR; + } + break; + + case CTRL_DATA_OUT: + /* Start DATA out transfer (only one DATA packet)*/ + + pdev->host.hc[phost->Control.hc_num_out].toggle_out ^= 1; + + USBH_CtlSendData (pdev, + phost->Control.buff, + phost->Control.length , + phost->Control.hc_num_out); + + phost->Control.state = CTRL_DATA_OUT_WAIT; + break; + + case CTRL_DATA_OUT_WAIT: + + URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out); + if (URB_Status == URB_DONE) + { /* If the Setup Pkt is sent successful, then change the state */ + phost->Control.state = CTRL_STATUS_IN; + } + + /* handle error cases */ + else if (URB_Status == URB_STALL) + { + /* In stall case, return to previous machine state*/ + phost->gState = phost->gStateBkp; + } + else if (URB_Status == URB_NOTREADY) + { + /* Nack received from device */ + phost->Control.state = CTRL_DATA_OUT; + } + else if (URB_Status == URB_ERROR) + { + /* device error */ + phost->Control.state = CTRL_ERROR; + } + break; + + + case CTRL_STATUS_IN: + /* Send 0 bytes out packet */ + USBH_CtlReceiveData (pdev, + 0, + 0, + phost->Control.hc_num_in); + + phost->Control.state = CTRL_STATUS_IN_WAIT; + + break; + + case CTRL_STATUS_IN_WAIT: + + URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in); + + if ( URB_Status == URB_DONE) + { /* Control transfers completed, Exit the State Machine */ + phost->gState = phost->gStateBkp; + } + + else if (URB_Status == URB_ERROR) + { + phost->Control.state = CTRL_ERROR; + } + + else if((HCD_GetCurrentFrame(pdev)\ + - phost->Control.timer) > timeout) + { + phost->Control.state = CTRL_ERROR; + } + else if(URB_Status == URB_STALL) + { + /* Control transfers completed, Exit the State Machine */ + phost->gState = phost->gStateBkp; + phost->Control.status = CTRL_STALL; + status = USBH_NOT_SUPPORTED; + } + break; + + case CTRL_STATUS_OUT: + pdev->host.hc[phost->Control.hc_num_out].toggle_out ^= 1; + USBH_CtlSendData (pdev, + 0, + 0, + phost->Control.hc_num_out); + + phost->Control.state = CTRL_STATUS_OUT_WAIT; + break; + + case CTRL_STATUS_OUT_WAIT: + + URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out); + if (URB_Status == URB_DONE) + { + phost->gState = phost->gStateBkp; + } + else if (URB_Status == URB_NOTREADY) + { + phost->Control.state = CTRL_STATUS_OUT; + } + else if (URB_Status == URB_ERROR) + { + phost->Control.state = CTRL_ERROR; + } + break; + + case CTRL_ERROR: + /* + After a halt condition is encountered or an error is detected by the + host, a control endpoint is allowed to recover by accepting the next Setup + PID; i.e., recovery actions via some other pipe are not required for control + endpoints. For the Default Control Pipe, a device reset will ultimately be + required to clear the halt or error condition if the next Setup PID is not + accepted. + */ + if (++ phost->Control.errorcount <= USBH_MAX_ERROR_COUNT) + { + /* Do the transmission again, starting from SETUP Packet */ + phost->Control.state = CTRL_SETUP; + } + else + { + phost->Control.status = CTRL_FAIL; + phost->gState = phost->gStateBkp; + + status = USBH_FAIL; + } + break; + + default: + break; + } + return status; +} + + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + + + diff --git a/Libraries/STM32_USB_HOST_Library/Core/src/usbh_hcs.c b/Libraries/STM32_USB_HOST_Library/Core/src/usbh_hcs.c new file mode 100644 index 0000000..c703d39 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Core/src/usbh_hcs.c @@ -0,0 +1,253 @@ +/** + ****************************************************************************** + * @file usbh_hcs.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file implements functions for opening and closing host channels + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_hcs.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_HCS + * @brief This file includes opening and closing host channels + * @{ + */ + +/** @defgroup USBH_HCS_Private_Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_HCS_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_HCS_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_HCS_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBH_HCS_Private_FunctionPrototypes + * @{ + */ +static uint16_t USBH_GetFreeChannel (USB_OTG_CORE_HANDLE *pdev); +/** + * @} + */ + + +/** @defgroup USBH_HCS_Private_Functions + * @{ + */ + + + +/** + * @brief USBH_Open_Channel + * Open a pipe + * @param pdev : Selected device + * @param hc_num: Host channel Number + * @param dev_address: USB Device address allocated to attached device + * @param speed : USB device speed (Full/Low) + * @param ep_type: end point type (Bulk/int/ctl) + * @param mps: max pkt size + * @retval Status + */ +uint8_t USBH_Open_Channel (USB_OTG_CORE_HANDLE *pdev, + uint8_t hc_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + + pdev->host.hc[hc_num].ep_num = pdev->host.channel[hc_num]& 0x7F; + pdev->host.hc[hc_num].ep_is_in = (pdev->host.channel[hc_num] & 0x80 ) == 0x80; + pdev->host.hc[hc_num].dev_addr = dev_address; + pdev->host.hc[hc_num].ep_type = ep_type; + pdev->host.hc[hc_num].max_packet = mps; + pdev->host.hc[hc_num].speed = speed; + pdev->host.hc[hc_num].toggle_in = 0; + pdev->host.hc[hc_num].toggle_out = 0; + if(speed == HPRT0_PRTSPD_HIGH_SPEED) + { + pdev->host.hc[hc_num].do_ping = 1; + } + + USB_OTG_HC_Init(pdev, hc_num) ; + + return HC_OK; + +} + +/** + * @brief USBH_Modify_Channel + * Modify a pipe + * @param pdev : Selected device + * @param hc_num: Host channel Number + * @param dev_address: USB Device address allocated to attached device + * @param speed : USB device speed (Full/Low) + * @param ep_type: end point type (Bulk/int/ctl) + * @param mps: max pkt size + * @retval Status + */ +uint8_t USBH_Modify_Channel (USB_OTG_CORE_HANDLE *pdev, + uint8_t hc_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + + if(dev_address != 0) + { + pdev->host.hc[hc_num].dev_addr = dev_address; + } + + if((pdev->host.hc[hc_num].max_packet != mps) && (mps != 0)) + { + pdev->host.hc[hc_num].max_packet = mps; + } + + if((pdev->host.hc[hc_num].speed != speed ) && (speed != 0 )) + { + pdev->host.hc[hc_num].speed = speed; + } + + USB_OTG_HC_Init(pdev, hc_num); + return HC_OK; + +} + +/** + * @brief USBH_Alloc_Channel + * Allocate a new channel for the pipe + * @param ep_addr: End point for which the channel to be allocated + * @retval hc_num: Host channel number + */ +uint8_t USBH_Alloc_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr) +{ + uint16_t hc_num; + + hc_num = USBH_GetFreeChannel(pdev); + + if (hc_num != HC_ERROR) + { + pdev->host.channel[hc_num] = HC_USED | ep_addr; + } + return hc_num; +} + +/** + * @brief USBH_Free_Pipe + * Free the USB host channel + * @param idx: Channel number to be freed + * @retval Status + */ +uint8_t USBH_Free_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t idx) +{ + if(idx < HC_MAX) + { + pdev->host.channel[idx] &= HC_USED_MASK; + } + return USBH_OK; +} + + +/** + * @brief USBH_DeAllocate_AllChannel + * Free all USB host channel +* @param pdev : core instance + * @retval Status + */ +uint8_t USBH_DeAllocate_AllChannel (USB_OTG_CORE_HANDLE *pdev) +{ + uint8_t idx; + + for (idx = 2; idx < HC_MAX ; idx ++) + { + pdev->host.channel[idx] = 0; + } + return USBH_OK; +} + +/** + * @brief USBH_GetFreeChannel + * Get a free channel number for allocation to a device endpoint + * @param None + * @retval idx: Free Channel number + */ +static uint16_t USBH_GetFreeChannel (USB_OTG_CORE_HANDLE *pdev) +{ + uint8_t idx = 0; + + for (idx = 0 ; idx < HC_MAX ; idx++) + { + if ((pdev->host.channel[idx] & HC_USED) == 0) + { + return idx; + } + } + return HC_ERROR; +} + + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + diff --git a/Libraries/STM32_USB_HOST_Library/Core/src/usbh_ioreq.c b/Libraries/STM32_USB_HOST_Library/Core/src/usbh_ioreq.c new file mode 100644 index 0000000..a890848 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Core/src/usbh_ioreq.c @@ -0,0 +1,419 @@ +/** + ****************************************************************************** + * @file usbh_ioreq.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file handles the issuing of the USB transactions + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ + +#include "usbh_ioreq.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_IOREQ + * @brief This file handles the standard protocol processing (USB v2.0) + * @{ + */ + + +/** @defgroup USBH_IOREQ_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBH_IOREQ_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Private_Variables + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Private_FunctionPrototypes + * @{ + */ +static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost, + uint8_t* buff, + uint16_t length); + +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Private_Functions + * @{ + */ + + +/** + * @brief USBH_CtlReq + * USBH_CtlReq sends a control request and provide the status after + * completion of the request + * @param pdev: Selected device + * @param req: Setup Request Structure + * @param buff: data buffer address to store the response + * @param length: length of the response + * @retval Status + */ +USBH_Status USBH_CtlReq (USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t *buff, + uint16_t length) +{ + USBH_Status status; + URB_STATE URB_Status = URB_IDLE; + + URB_Status = HCD_GetURB_State(pdev, phost->Control.hc_num_out); + + status = USBH_BUSY; + + switch (phost->RequestState) + { + case CMD_SEND: + /* Start a SETUP transfer */ + USBH_SubmitSetupRequest(phost, buff, length); + phost->RequestState = CMD_WAIT; + status = USBH_BUSY; + break; + + case CMD_WAIT: + if (URB_Status == URB_DONE) + { + /* Commands successfully sent and Response Received */ + phost->RequestState = CMD_SEND; + status = USBH_OK; + } + else if (URB_Status == URB_ERROR) + { + /* Failure Mode */ + phost->RequestState = CMD_SEND; + status = USBH_FAIL; + } + else if (URB_Status == URB_STALL) + { + /* Commands successfully sent and Response Received */ + phost->RequestState = CMD_SEND; + status = USBH_NOT_SUPPORTED; + } + break; + + default: + break; + } + return status; +} + +/** + * @brief USBH_CtlSendSetup + * Sends the Setup Packet to the Device + * @param pdev: Selected device + * @param buff: Buffer pointer from which the Data will be send to Device + * @param hc_num: Host channel Number + * @retval Status + */ +USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t hc_num){ + pdev->host.hc[hc_num].ep_is_in = 0; + pdev->host.hc[hc_num].data_pid = HC_PID_SETUP; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = USBH_SETUP_PKT_SIZE; + + return (USBH_Status)HCD_SubmitRequest (pdev , hc_num); +} + + +/** + * @brief USBH_CtlSendData + * Sends a data Packet to the Device + * @param pdev: Selected device + * @param buff: Buffer pointer from which the Data will be sent to Device + * @param length: Length of the data to be sent + * @param hc_num: Host channel Number + * @retval Status + */ +USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t length, + uint8_t hc_num) +{ + pdev->host.hc[hc_num].ep_is_in = 0; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + if ( length == 0 ) + { /* For Status OUT stage, Length==0, Status Out PID = 1 */ + pdev->host.hc[hc_num].toggle_out = 1; + } + + /* Set the Data Toggle bit as per the Flag */ + if ( pdev->host.hc[hc_num].toggle_out == 0) + { /* Put the PID 0 */ + pdev->host.hc[hc_num].data_pid = HC_PID_DATA0; + } + else + { /* Put the PID 1 */ + pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ; + } + + HCD_SubmitRequest (pdev , hc_num); + + return USBH_OK; +} + + +/** + * @brief USBH_CtlReceiveData + * Receives the Device Response to the Setup Packet + * @param pdev: Selected device + * @param buff: Buffer pointer in which the response needs to be copied + * @param length: Length of the data to be received + * @param hc_num: Host channel Number + * @retval Status. + */ +USBH_Status USBH_CtlReceiveData(USB_OTG_CORE_HANDLE *pdev, + uint8_t* buff, + uint8_t length, + uint8_t hc_num) +{ + + pdev->host.hc[hc_num].ep_is_in = 1; + pdev->host.hc[hc_num].data_pid = HC_PID_DATA1; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + HCD_SubmitRequest (pdev , hc_num); + + return USBH_OK; + +} + + +/** + * @brief USBH_BulkSendData + * Sends the Bulk Packet to the device + * @param pdev: Selected device + * @param buff: Buffer pointer from which the Data will be sent to Device + * @param length: Length of the data to be sent + * @param hc_num: Host channel Number + * @retval Status + */ +USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint16_t length, + uint8_t hc_num) +{ + pdev->host.hc[hc_num].ep_is_in = 0; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + /* Set the Data Toggle bit as per the Flag */ + if ( pdev->host.hc[hc_num].toggle_out == 0) + { /* Put the PID 0 */ + pdev->host.hc[hc_num].data_pid = HC_PID_DATA0; + } + else + { /* Put the PID 1 */ + pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ; + } + + HCD_SubmitRequest (pdev , hc_num); + return USBH_OK; +} + + +/** + * @brief USBH_BulkReceiveData + * Receives IN bulk packet from device + * @param pdev: Selected device + * @param buff: Buffer pointer in which the received data packet to be copied + * @param length: Length of the data to be received + * @param hc_num: Host channel Number + * @retval Status. + */ +USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint16_t length, + uint8_t hc_num) +{ + pdev->host.hc[hc_num].ep_is_in = 1; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + + if( pdev->host.hc[hc_num].toggle_in == 0) + { + pdev->host.hc[hc_num].data_pid = HC_PID_DATA0; + } + else + { + pdev->host.hc[hc_num].data_pid = HC_PID_DATA1; + } + + HCD_SubmitRequest (pdev , hc_num); + return USBH_OK; +} + + +/** + * @brief USBH_InterruptReceiveData + * Receives the Device Response to the Interrupt IN token + * @param pdev: Selected device + * @param buff: Buffer pointer in which the response needs to be copied + * @param length: Length of the data to be received + * @param hc_num: Host channel Number + * @retval Status. + */ +USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t length, + uint8_t hc_num) +{ + + pdev->host.hc[hc_num].ep_is_in = 1; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + + + if(pdev->host.hc[hc_num].toggle_in == 0) + { + pdev->host.hc[hc_num].data_pid = HC_PID_DATA0; + } + else + { + pdev->host.hc[hc_num].data_pid = HC_PID_DATA1; + } + + /* toggle DATA PID */ + pdev->host.hc[hc_num].toggle_in ^= 1; + + HCD_SubmitRequest (pdev , hc_num); + + return USBH_OK; +} + +/** + * @brief USBH_InterruptSendData + * Sends the data on Interrupt OUT Endpoint + * @param pdev: Selected device + * @param buff: Buffer pointer from where the data needs to be copied + * @param length: Length of the data to be sent + * @param hc_num: Host channel Number + * @retval Status. + */ +USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t length, + uint8_t hc_num) +{ + + pdev->host.hc[hc_num].ep_is_in = 0; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + if(pdev->host.hc[hc_num].toggle_in == 0) + { + pdev->host.hc[hc_num].data_pid = HC_PID_DATA0; + } + else + { + pdev->host.hc[hc_num].data_pid = HC_PID_DATA1; + } + + pdev->host.hc[hc_num].toggle_in ^= 1; + + HCD_SubmitRequest (pdev , hc_num); + + return USBH_OK; +} + + +/** + * @brief USBH_SubmitSetupRequest + * Start a setup transfer by changing the state-machine and + * initializing the required variables needed for the Control Transfer + * @param pdev: Selected device + * @param setup: Setup Request Structure + * @param buff: Buffer used for setup request + * @param length: Length of the data + * @retval Status. +*/ +static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost, + uint8_t* buff, + uint16_t length) +{ + + /* Save Global State */ + phost->gStateBkp = phost->gState; + + /* Prepare the Transactions */ + phost->gState = HOST_CTRL_XFER; + phost->Control.buff = buff; + phost->Control.length = length; + phost->Control.state = CTRL_SETUP; + + return USBH_OK; +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + + diff --git a/Libraries/STM32_USB_HOST_Library/Core/src/usbh_stdreq.c b/Libraries/STM32_USB_HOST_Library/Core/src/usbh_stdreq.c new file mode 100644 index 0000000..fb90c4b --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Core/src/usbh_stdreq.c @@ -0,0 +1,551 @@ +/** + ****************************************************************************** + * @file usbh_stdreq.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file implements the standard requests for device enumeration + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ + +#include "usbh_ioreq.h" +#include "usbh_stdreq.h" + +/** @addtogroup USBH_LIB +* @{ +*/ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_STDREQ +* @brief This file implements the standard requests for device enumeration +* @{ +*/ + + +/** @defgroup USBH_STDREQ_Private_Defines +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_STDREQ_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + + +/** @defgroup USBH_STDREQ_Private_Macros +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_STDREQ_Private_Variables +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_STDREQ_Private_FunctionPrototypes +* @{ +*/ +static void USBH_ParseDevDesc (USBH_DevDesc_TypeDef* , uint8_t *buf, uint16_t length); + +static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc, + USBH_InterfaceDesc_TypeDef* itf_desc, + USBH_EpDesc_TypeDef* ep_desc, + uint8_t *buf, + uint16_t length); +static USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf, + uint16_t *ptr); + +static void USBH_ParseInterfaceDesc (USBH_InterfaceDesc_TypeDef *if_descriptor, uint8_t *buf); +static void USBH_ParseEPDesc (USBH_EpDesc_TypeDef *ep_descriptor, uint8_t *buf); + +static void USBH_ParseStringDesc (uint8_t* psrc, uint8_t* pdest, uint16_t length); +/** +* @} +*/ + + +/** @defgroup USBH_STDREQ_Private_Functions +* @{ +*/ + + +/** +* @brief USBH_Get_DevDesc +* Issue Get Device Descriptor command to the device. Once the response +* received, it parses the device descriptor and updates the status. +* @param pdev: Selected device +* @param dev_desc: Device Descriptor buffer address +* @param pdev->host.Rx_Buffer: Receive Buffer address +* @param length: Length of the descriptor +* @retval Status +*/ +USBH_Status USBH_Get_DevDesc(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t length) +{ + + USBH_Status status; + + if((status = USBH_GetDescriptor(pdev, + phost, + USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, + USB_DESC_DEVICE, + pdev->host.Rx_Buffer, + length)) == USBH_OK) + { + /* Commands successfully sent and Response Received */ + USBH_ParseDevDesc(&phost->device_prop.Dev_Desc, pdev->host.Rx_Buffer, length); + } + return status; +} + +/** +* @brief USBH_Get_CfgDesc +* Issues Configuration Descriptor to the device. Once the response +* received, it parses the configuartion descriptor and updates the +* status. +* @param pdev: Selected device +* @param cfg_desc: Configuration Descriptor address +* @param itf_desc: Interface Descriptor address +* @param ep_desc: Endpoint Descriptor address +* @param length: Length of the descriptor +* @retval Status +*/ +USBH_Status USBH_Get_CfgDesc(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint16_t length) + +{ + USBH_Status status; + + if((status = USBH_GetDescriptor(pdev, + phost, + USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, + USB_DESC_CONFIGURATION, + pdev->host.Rx_Buffer, + length)) == USBH_OK) + { + /* Commands successfully sent and Response Received */ + USBH_ParseCfgDesc (&phost->device_prop.Cfg_Desc, + phost->device_prop.Itf_Desc, + phost->device_prop.Ep_Desc[0], + pdev->host.Rx_Buffer, + length); + + } + return status; +} + + +/** +* @brief USBH_Get_StringDesc +* Issues string Descriptor command to the device. Once the response +* received, it parses the string descriptor and updates the status. +* @param pdev: Selected device +* @param string_index: String index for the descriptor +* @param buff: Buffer address for the descriptor +* @param length: Length of the descriptor +* @retval Status +*/ +USBH_Status USBH_Get_StringDesc(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t string_index, + uint8_t *buff, + uint16_t length) +{ + USBH_Status status; + + if((status = USBH_GetDescriptor(pdev, + phost, + USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, + USB_DESC_STRING | string_index, + pdev->host.Rx_Buffer, + length)) == USBH_OK) + { + /* Commands successfully sent and Response Received */ + USBH_ParseStringDesc(pdev->host.Rx_Buffer,buff, length); + } + return status; +} + +/** +* @brief USBH_GetDescriptor +* Issues Descriptor command to the device. Once the response received, +* it parses the descriptor and updates the status. +* @param pdev: Selected device +* @param req_type: Descriptor type +* @param value_idx: wValue for the GetDescriptr request +* @param buff: Buffer to store the descriptor +* @param length: Length of the descriptor +* @retval Status +*/ +USBH_Status USBH_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t req_type, + uint16_t value_idx, + uint8_t* buff, + uint16_t length ) +{ + phost->Control.setup.b.bmRequestType = USB_D2H | req_type; + phost->Control.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR; + phost->Control.setup.b.wValue.w = value_idx; + + if ((value_idx & 0xff00) == USB_DESC_STRING) + { + phost->Control.setup.b.wIndex.w = 0x0409; + } + else + { + phost->Control.setup.b.wIndex.w = 0; + } + phost->Control.setup.b.wLength.w = length; + return USBH_CtlReq(pdev, phost, buff , length ); +} + +/** +* @brief USBH_SetAddress +* This command sets the address to the connected device +* @param pdev: Selected device +* @param DeviceAddress: Device address to assign +* @retval Status +*/ +USBH_Status USBH_SetAddress(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t DeviceAddress) +{ + phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | \ + USB_REQ_TYPE_STANDARD; + + phost->Control.setup.b.bRequest = USB_REQ_SET_ADDRESS; + + phost->Control.setup.b.wValue.w = (uint16_t)DeviceAddress; + phost->Control.setup.b.wIndex.w = 0; + phost->Control.setup.b.wLength.w = 0; + + return USBH_CtlReq(pdev, phost, 0 , 0 ); +} + +/** +* @brief USBH_SetCfg +* The command sets the configuration value to the connected device +* @param pdev: Selected device +* @param cfg_idx: Configuration value +* @retval Status +*/ +USBH_Status USBH_SetCfg(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint16_t cfg_idx) +{ + + phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE |\ + USB_REQ_TYPE_STANDARD; + phost->Control.setup.b.bRequest = USB_REQ_SET_CONFIGURATION; + phost->Control.setup.b.wValue.w = cfg_idx; + phost->Control.setup.b.wIndex.w = 0; + phost->Control.setup.b.wLength.w = 0; + + return USBH_CtlReq(pdev, phost, 0 , 0 ); +} + +/** +* @brief USBH_ClrFeature +* This request is used to clear or disable a specific feature. + +* @param pdev: Selected device +* @param ep_num: endpoint number +* @param hc_num: Host channel number +* @retval Status +*/ +USBH_Status USBH_ClrFeature(USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t ep_num, + uint8_t hc_num) +{ + + phost->Control.setup.b.bmRequestType = USB_H2D | + USB_REQ_RECIPIENT_ENDPOINT | + USB_REQ_TYPE_STANDARD; + + phost->Control.setup.b.bRequest = USB_REQ_CLEAR_FEATURE; + phost->Control.setup.b.wValue.w = FEATURE_SELECTOR_ENDPOINT; + phost->Control.setup.b.wIndex.w = ep_num; + phost->Control.setup.b.wLength.w = 0; + + if ((ep_num & USB_REQ_DIR_MASK ) == USB_D2H) + { /* EP Type is IN */ + pdev->host.hc[hc_num].toggle_in = 0; + } + else + {/* EP Type is OUT */ + pdev->host.hc[hc_num].toggle_out = 0; + } + + return USBH_CtlReq(pdev, phost, 0 , 0 ); +} + +/** +* @brief USBH_ParseDevDesc +* This function Parses the device descriptor +* @param dev_desc: device_descriptor destinaton address +* @param buf: Buffer where the source descriptor is available +* @param length: Length of the descriptor +* @retval None +*/ +static void USBH_ParseDevDesc (USBH_DevDesc_TypeDef* dev_desc, + uint8_t *buf, + uint16_t length) +{ + dev_desc->bLength = *(uint8_t *) (buf + 0); + dev_desc->bDescriptorType = *(uint8_t *) (buf + 1); + dev_desc->bcdUSB = LE16 (buf + 2); + dev_desc->bDeviceClass = *(uint8_t *) (buf + 4); + dev_desc->bDeviceSubClass = *(uint8_t *) (buf + 5); + dev_desc->bDeviceProtocol = *(uint8_t *) (buf + 6); + dev_desc->bMaxPacketSize = *(uint8_t *) (buf + 7); + + if (length > 8) + { /* For 1st time after device connection, Host may issue only 8 bytes for + Device Descriptor Length */ + dev_desc->idVendor = LE16 (buf + 8); + dev_desc->idProduct = LE16 (buf + 10); + dev_desc->bcdDevice = LE16 (buf + 12); + dev_desc->iManufacturer = *(uint8_t *) (buf + 14); + dev_desc->iProduct = *(uint8_t *) (buf + 15); + dev_desc->iSerialNumber = *(uint8_t *) (buf + 16); + dev_desc->bNumConfigurations = *(uint8_t *) (buf + 17); + } +} + +/** +* @brief USBH_ParseCfgDesc +* This function Parses the configuration descriptor +* @param cfg_desc: Configuration Descriptor address +* @param itf_desc: Interface Descriptor address +* @param ep_desc: Endpoint Descriptor address +* @param buf: Buffer where the source descriptor is available +* @param length: Length of the descriptor +* @retval None +*/ +static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc, + USBH_InterfaceDesc_TypeDef* itf_desc, + USBH_EpDesc_TypeDef* ep_desc, + uint8_t *buf, + uint16_t length) +{ + USBH_InterfaceDesc_TypeDef *pif ; + USBH_EpDesc_TypeDef *pep; + USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf; + uint16_t ptr; + int8_t if_ix; + int8_t ep_ix; + + pdesc = (USBH_DescHeader_t *)buf; + + /* Parse configuration descriptor */ + cfg_desc->bLength = *(uint8_t *) (buf + 0); + cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1); + cfg_desc->wTotalLength = LE16 (buf + 2); + cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4); + cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5); + cfg_desc->iConfiguration = *(uint8_t *) (buf + 6); + cfg_desc->bmAttributes = *(uint8_t *) (buf + 7); + cfg_desc->bMaxPower = *(uint8_t *) (buf + 8); + + + if (length > USB_CONFIGURATION_DESC_SIZE) + { + ptr = USB_LEN_CFG_DESC; + + if ( cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES) + { + if_ix = 0; + pif = (USBH_InterfaceDesc_TypeDef *)0; + + /* Parse Interface descriptor relative to the current configuration */ + if(cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES) + { + while (if_ix < cfg_desc->bNumInterfaces) + { + pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr); + if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE) + { + pif = &itf_desc[if_ix]; + USBH_ParseInterfaceDesc (pif, (uint8_t *)pdesc); + ep_ix = 0; + + /* Parse Ep descriptors relative to the current interface */ + if(pif->bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) + { + while (ep_ix < pif->bNumEndpoints) + { + pdesc = USBH_GetNextDesc((void* )pdesc, &ptr); + if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) + { + pep = &ep_desc[ep_ix]; + USBH_ParseEPDesc (pep, (uint8_t *)pdesc); + ep_ix++; + } + else + { + ptr += pdesc->bLength; + } + } + } + if_ix++; + } + else + { + ptr += pdesc->bLength; + } + } + } + } + } +} + + +/** +* @brief USBH_ParseInterfaceDesc +* This function Parses the interface descriptor +* @param if_descriptor : Interface descriptor destination +* @param buf: Buffer where the descriptor data is available +* @retval None +*/ +static void USBH_ParseInterfaceDesc (USBH_InterfaceDesc_TypeDef *if_descriptor, + uint8_t *buf) +{ + if_descriptor->bLength = *(uint8_t *) (buf + 0); + if_descriptor->bDescriptorType = *(uint8_t *) (buf + 1); + if_descriptor->bInterfaceNumber = *(uint8_t *) (buf + 2); + if_descriptor->bAlternateSetting = *(uint8_t *) (buf + 3); + if_descriptor->bNumEndpoints = *(uint8_t *) (buf + 4); + if_descriptor->bInterfaceClass = *(uint8_t *) (buf + 5); + if_descriptor->bInterfaceSubClass = *(uint8_t *) (buf + 6); + if_descriptor->bInterfaceProtocol = *(uint8_t *) (buf + 7); + if_descriptor->iInterface = *(uint8_t *) (buf + 8); +} + +/** +* @brief USBH_ParseEPDesc +* This function Parses the endpoint descriptor +* @param ep_descriptor: Endpoint descriptor destination address +* @param buf: Buffer where the parsed descriptor stored +* @retval None +*/ +static void USBH_ParseEPDesc (USBH_EpDesc_TypeDef *ep_descriptor, + uint8_t *buf) +{ + + ep_descriptor->bLength = *(uint8_t *) (buf + 0); + ep_descriptor->bDescriptorType = *(uint8_t *) (buf + 1); + ep_descriptor->bEndpointAddress = *(uint8_t *) (buf + 2); + ep_descriptor->bmAttributes = *(uint8_t *) (buf + 3); + ep_descriptor->wMaxPacketSize = LE16 (buf + 4); + ep_descriptor->bInterval = *(uint8_t *) (buf + 6); +} + +/** +* @brief USBH_ParseStringDesc +* This function Parses the string descriptor +* @param psrc: Source pointer containing the descriptor data +* @param pdest: Destination address pointer +* @param length: Length of the descriptor +* @retval None +*/ +static void USBH_ParseStringDesc (uint8_t* psrc, + uint8_t* pdest, + uint16_t length) +{ + uint16_t strlength; + uint16_t idx; + + /* The UNICODE string descriptor is not NULL-terminated. The string length is + computed by substracting two from the value of the first byte of the descriptor. + */ + + /* Check which is lower size, the Size of string or the length of bytes read + from the device */ + + if ( psrc[1] == USB_DESC_TYPE_STRING) + { /* Make sure the Descriptor is String Type */ + + /* psrc[0] contains Size of Descriptor, subtract 2 to get the length of string */ + strlength = ( ( (psrc[0]-2) <= length) ? (psrc[0]-2) :length); + psrc += 2; /* Adjust the offset ignoring the String Len and Descriptor type */ + + for (idx = 0; idx < strlength; idx+=2 ) + {/* Copy Only the string and ignore the UNICODE ID, hence add the src */ + *pdest = psrc[idx]; + pdest++; + } + *pdest = 0; /* mark end of string */ + } +} + +/** +* @brief USBH_GetNextDesc +* This function return the next descriptor header +* @param buf: Buffer where the cfg descriptor is available +* @param ptr: data popinter inside the cfg descriptor +* @retval next header +*/ +static USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf, uint16_t *ptr) +{ + USBH_DescHeader_t *pnext; + + *ptr += ((USBH_DescHeader_t *)pbuf)->bLength; + pnext = (USBH_DescHeader_t *)((uint8_t *)pbuf + \ + ((USBH_DescHeader_t *)pbuf)->bLength); + + return(pnext); +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + + + diff --git a/Libraries/STM32_USB_HOST_Library/Release_Notes.html b/Libraries/STM32_USB_HOST_Library/Release_Notes.html new file mode 100644 index 0000000..88cc335 --- /dev/null +++ b/Libraries/STM32_USB_HOST_Library/Release_Notes.html @@ -0,0 +1,944 @@ + + + + + + + + +Release Notes for STM32F105/7xx and STM32F2xx USB Host Library + + + + + +
+ +

 

+ +
+ + + + + +
+ + + + + + + +
+

Back to Release page

+
+

Release Notes for STM32F105/7xx and STM32F2xx USB Host Library

+

Copyright + 2011 STMicroelectronics

+

+
+

 

+ + + + +
+

Contents

+
    +
  1. STM32F105/7xx and STM32F2xx USB Host Library update History
  2. +
  3. License
  4. +
+

STM32F105/7xx and STM32F2xx USB Host Library  update History

V2.0.0 / 22-July-2011

Main +Changes

+
  • Second official version supporting STM32F105/7 and STM32F2xx devices
  • Add support for STM32F2xx devices
  • Add multi interface feature
  • Add dynamic configuration parsing
  • Add +USBH_DeAllocate_AllChannel function in the Host channel management +layer to clean up channels allocation table when de-initializing the +library
  • Change the core layer to stop correctly the host core and free all allocated channels
  • Add usbh_conf.h file in the application layer to customize some user parameters

V1.0.0 - 11/29/2010

+
  • Created 

License

+

The use of this STM32 software is governed by the terms and conditions of the License Agreement "MCD-ST Liberty SW License Agreement 20Jul2011 v0.1.pdf" available in the root of this package. 

+
+
+
+

For + complete documentation on STM32(CORTEX M3) 32-Bit + Microcontrollers visit www.st.com/STM32

+
+

+
+ +
+ +

 

+ +
+ + \ No newline at end of file diff --git a/Libraries/STM32_USB_OTG_Driver/Release_Notes.html b/Libraries/STM32_USB_OTG_Driver/Release_Notes.html new file mode 100644 index 0000000..17d2a08 --- /dev/null +++ b/Libraries/STM32_USB_OTG_Driver/Release_Notes.html @@ -0,0 +1,941 @@ + + + + + + + + +Release Notes for STM32F105/7xx and STM32F2xx USB OTG Driver + + + + + +
+ +

 

+ +
+ + + + + +
+ + + + + + + +
+

Back to Release page

+
+

Release Notes for STM32F105/7xx and STM32F2xx USB OTG Driver

+

Copyright + 2011 STMicroelectronics

+

+
+

 

+ + + + +
+

Contents

+
    +
  1. STM32F105/7xx and STM32F2xx USB OTG Driver update History
  2. +
  3. License
  4. +
+

STM32F105/7xx and STM32F2xx USB OTG Driver  update History

V2.0.0 / 22-July-2011

Main +Changes

+
  • Second official version supporting STM32F105/7 and STM32F2xx devices
  • Rename the Library from "STM32_USB_HOST_Driver" to "STM32_USB_OTG_Driver"
  • Add support for STM32F2xx devices
  • Add support for Device and OTG modes
  • Change HCD layer to support High speed core
  • Change the Low level driver to support multi core support for Host mode
  • Add Stop mechanism for Host and Device modes
  • Change VBUS enabling method, to use the external or the internal VBUS when using the ULPI

V1.0.0 - 11/29/2010

+
  • Created 

License

+

The use of this STM32 software is governed by the terms and conditions of the License Agreement "MCD-ST Liberty SW License Agreement 20Jul2011 v0.1.pdf" available in the root of this package. 

+
+
+
+

For + complete documentation on STM32(CORTEX M3) 32-Bit + Microcontrollers visit www.st.com/STM32

+
+

+
+ +
+ +

 

+ +
+ + \ No newline at end of file diff --git a/Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h b/Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h new file mode 100644 index 0000000..0e7c12e --- /dev/null +++ b/Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h @@ -0,0 +1,97 @@ +/** + ****************************************************************************** + * @file usb_bsp.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Specific api's relative to the used hardware platform + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

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

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_defines.h" +#include "usb_regs.h" +#include "usb_core.h" +#include "usb_otg.h" + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_OTG + * @brief This file is the interface between EFSL ans Host mass-storage class + * @{ + */ + + +/** @defgroup USB_OTG_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_OTG_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USB_OTG_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_OTG_Private_Variables + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_OTG_Private_FunctionPrototypes + * @{ + */ + +static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev); + +/** + * @} + */ + + +/** @defgroup USB_OTG_Private_Functions + * @{ + */ + + +/* OTG Interrupt Handler */ + + +/** + * @brief STM32_USBO_OTG_ISR_Handler + * + * @param None + * @retval : None + */ +uint32_t STM32_USBO_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev) +{ + uint32_t retval = 0; + USB_OTG_GINTSTS_TypeDef gintsts ; + gintsts.d32 = 0; + + gintsts.d32 = USB_OTG_Read_itr(pdev); + if (gintsts.d32 == 0) + { + return 0; + } + if (gintsts.b.otgintr) + { + retval |= 1;//USB_OTG_HandleOTG_ISR(pdev); + } + if (gintsts.b.conidstschng) + { + retval |= 2;//USB_OTG_HandleConnectorIDStatusChange_ISR(pdev); + } + if (gintsts.b.sessreqintr) + { + retval |= 3;//USB_OTG_HandleSessionRequest_ISR(pdev); + } + return retval; +} + + +/** + * @brief USB_OTG_Read_itr + * returns the Core Interrupt register + * @param None + * @retval : status + */ +static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintsts; + USB_OTG_GINTMSK_TypeDef gintmsk; + USB_OTG_GINTMSK_TypeDef gintmsk_common; + + + gintsts.d32 = 0; + gintmsk.d32 = 0; + gintmsk_common.d32 = 0; + + /* OTG interrupts */ + gintmsk_common.b.sessreqintr = 1; + gintmsk_common.b.conidstschng = 1; + gintmsk_common.b.otgintr = 1; + + gintsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS); + gintmsk.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK); + return ((gintsts.d32 & gintmsk.d32 ) & gintmsk_common.d32); +} + + +/** + * @brief USB_OTG_GetCurrentState + * Return current OTG State + * @param None + * @retval : None + */ +uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *pdev) +{ + return pdev->otg.OTG_State; +} + + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/System/arm_common_tables.h b/System/arm_common_tables.h new file mode 100644 index 0000000..7245c4f --- /dev/null +++ b/System/arm_common_tables.h @@ -0,0 +1,35 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010 ARM Limited. All rights reserved. +* +* $Date: 11. November 2010 +* $Revision: V1.0.2 +* +* Project: CMSIS DSP Library +* Title: arm_common_tables.h +* +* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* Version 1.0.2 2010/11/11 +* Documentation updated. +* +* Version 1.0.1 2010/10/05 +* Production release and review comments incorporated. +* +* Version 1.0.0 2010/09/20 +* Production release and review comments incorporated. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +extern uint16_t armBitRevTable[256]; +extern q15_t armRecipTableQ15[64]; +extern q31_t armRecipTableQ31[64]; +extern const q31_t realCoefAQ31[1024]; +extern const q31_t realCoefBQ31[1024]; + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/System/arm_math.h b/System/arm_math.h new file mode 100644 index 0000000..ffa03b6 --- /dev/null +++ b/System/arm_math.h @@ -0,0 +1,7051 @@ +/* ---------------------------------------------------------------------- + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * $Date: 15. July 2011 + * $Revision: V1.0.10 + * + * Project: CMSIS DSP Library + * Title: arm_math.h + * + * Description: Public header file for CMSIS DSP Library + * + * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 + * + * Version 1.0.10 2011/7/15 + * Big Endian support added and Merged M0 and M3/M4 Source code. + * + * Version 1.0.3 2010/11/29 + * Re-organized the CMSIS folders and updated documentation. + * + * Version 1.0.2 2010/11/11 + * Documentation updated. + * + * Version 1.0.1 2010/10/05 + * Production release and review comments incorporated. + * + * Version 1.0.0 2010/09/20 + * Production release and review comments incorporated. + * -------------------------------------------------------------------- */ + +/** + \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 modules 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. + * + * Processor Support + * + * The library is completely written in C and is fully CMSIS compliant. + * High performance is achieved through maximum use of Cortex-M4 intrinsics. + * + * The supplied library source code also builds and runs on the Cortex-M3 and Cortex-M0 processor, + * with the DSP intrinsics being emulated through software. + * + * + * Toolchain Support + * + * The library has been developed and tested with MDK-ARM version 4.21. + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Using the Library + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4l_math.lib (Little endian on Cortex-M4) + * - arm_cortexM4b_math.lib (Big endian on Cortex-M4) + * - arm_cortexM3l_math.lib (Little endian on Cortex-M3) + * - arm_cortexM3b_math.lib (Big endian on Cortex-M3) + * - arm_cortexM0l_math.lib (Little endian on Cortex-M0) + * - arm_cortexM0b_math.lib (Big endian on Cortex-M3) + * + * 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-M4/M3/M0 with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * Define the appropriate pre processor MACRO ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 depending on the target processor in the application. + * + * Examples + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Building the Library + * + * The library installer contains project files to re build libraries on MDK Tool chain in the CMSIS\DSP_Lib\Source\ARM folder. + * - arm_cortexM0b_math.uvproj + * - arm_cortexM0l_math.uvproj + * - arm_cortexM3b_math.uvproj + * - arm_cortexM3l_math.uvproj + * - arm_cortexM4b_math.uvproj + * - arm_cortexM4l_math.uvproj + * - arm_cortexM4bf_math.uvproj + * - arm_cortexM4lf_math.uvproj + * + * Each library project have differant pre-processor macros. + * + * 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_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 for checking on the input and output sizes of matrices + * + * ARM_MATH_ROUNDING: + * Define macro for rounding on support functions + * + * __FPU_PRESENT: + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries + * + * + * The project can be built by opening the appropriate project in MDK-ARM 4.21 chain and defining the optional pre processor MACROs detailed above. + * + * Copyright Notice + * + * Copyright (C) 2010 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 + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined (ARM_MATH_CM4) + #include "core_cm4.h" +#elif defined (ARM_MATH_CM3) + #include "core_cm3.h" +#elif defined (ARM_MATH_CM0) + #include "core_cm0.h" +#else +#include "ARMCM4.h" +#warning "Define either ARM_MATH_CM4 OR ARM_MATH_CM3...By Default building on ARM_MATH_CM4....." +#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 +#define PI 3.14159265358979f + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define TABLE_SIZE 256 +#define TABLE_SPACING_Q31 0x800000 +#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 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. + */ +#define __SIMD32(addr) (*(int32_t **) & (addr)) + +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0) + /** + * @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) ) + +#endif + + + /** + * @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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + + static __INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + + +#if defined (ARM_MATH_CM0) && defined ( __CC_ARM ) +#define __CLZ __clz +#endif + +#if defined (ARM_MATH_CM0) && ((defined (__ICCARM__)) ||(defined (__GNUC__)) || defined (__TASKING__) ) + + static __INLINE uint32_t __CLZ(q31_t data); + + + static __INLINE uint32_t __CLZ(q31_t data) + { + uint32_t count = 0; + uint32_t mask = 0x80000000; + + while((data & mask) == 0) + { + count += 1u; + mask = mask >> 1u; + } + + return(count); + + } + +#endif + + /** + * @brief Function to Calculates 1/in(reciprocal) value of Q31 Data type. + */ + + static __INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + + uint32_t out, tempVal; + uint32_t index, i; + uint32_t signBits; + + if(in > 0) + { + signBits = __CLZ(in) - 1; + } + else + { + signBits = __CLZ(-in) - 1; + } + + /* Convert input sample to 1.31 format */ + in = in << signBits; + + /* calculation of index for initial approximated Val */ + index = (uint32_t) (in >> 24u); + 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 = (q31_t) (((q63_t) in * out) >> 31u); + tempVal = 0x7FFFFFFF - tempVal; + /* 1.31 with exp 1 */ + //out = (q31_t) (((q63_t) out * tempVal) >> 30u); + out = (q31_t) clip_q63_to_q31(((q63_t) out * tempVal) >> 30u); + } + + /* 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. + */ + static __INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + + uint32_t out = 0, tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if(in > 0) + { + signBits = __CLZ(in) - 17; + } + else + { + signBits = __CLZ(-in) - 17; + } + + /* Convert input sample to 1.15 format */ + in = in << signBits; + + /* calculation of index for initial approximated Val */ + index = 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 = 0; i < 2; i++) + { + tempVal = (q15_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFF - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((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 intrinisic function for only M0 processors + */ +#if defined(ARM_MATH_CM0) + + static __INLINE q31_t __SSAT( + q31_t x, + uint32_t y) + { + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + for (i = 0; i < (y - 1); i++) + { + posMax = posMax * 2; + } + + if(x > 0) + { + posMax = (posMax - 1); + + if(x > posMax) + { + x = posMax; + } + } + else + { + negMin = -posMax; + + if(x < negMin) + { + x = negMin; + } + } + return (x); + + + } + +#endif /* end of ARM_MATH_CM0 */ + + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + static __INLINE q31_t __QADD8( + q31_t x, + q31_t y) + { + + q31_t sum; + q7_t r, s, t, u; + + r = (char) x; + s = (char) y; + + r = __SSAT((q31_t) (r + s), 8); + s = __SSAT(((q31_t) (((x << 16) >> 24) + ((y << 16) >> 24))), 8); + t = __SSAT(((q31_t) (((x << 8) >> 24) + ((y << 8) >> 24))), 8); + u = __SSAT(((q31_t) ((x >> 24) + (y >> 24))), 8); + + sum = (((q31_t) u << 24) & 0xFF000000) | (((q31_t) t << 16) & 0x00FF0000) | + (((q31_t) s << 8) & 0x0000FF00) | (r & 0x000000FF); + + return sum; + + } + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + static __INLINE q31_t __QSUB8( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s, t, u; + + r = (char) x; + s = (char) y; + + r = __SSAT((r - s), 8); + s = __SSAT(((q31_t) (((x << 16) >> 24) - ((y << 16) >> 24))), 8) << 8; + t = __SSAT(((q31_t) (((x << 8) >> 24) - ((y << 8) >> 24))), 8) << 16; + u = __SSAT(((q31_t) ((x >> 24) - (y >> 24))), 8) << 24; + + sum = + (u & 0xFF000000) | (t & 0x00FF0000) | (s & 0x0000FF00) | (r & 0x000000FF); + + return sum; + } + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + static __INLINE q31_t __QADD16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = __SSAT(r + s, 16); + s = __SSAT(((q31_t) ((x >> 16) + (y >> 16))), 16) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + + } + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + static __INLINE q31_t __SHADD16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) + (s >> 1)); + s = ((q31_t) ((x >> 17) + (y >> 17))) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + + } + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + static __INLINE q31_t __QSUB16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = __SSAT(r - s, 16); + s = __SSAT(((q31_t) ((x >> 16) - (y >> 16))), 16) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + static __INLINE q31_t __SHSUB16( + q31_t x, + q31_t y) + { + + q31_t diff; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) - (s >> 1)); + s = (((x >> 17) - (y >> 17)) << 16); + + diff = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return diff; + } + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + static __INLINE q31_t __QASX( + q31_t x, + q31_t y) + { + + q31_t sum = 0; + + sum = ((sum + clip_q31_to_q15((q31_t) ((short) (x >> 16) + (short) y))) << 16) + + clip_q31_to_q15((q31_t) ((short) x - (short) (y >> 16))); + + return sum; + } + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + static __INLINE q31_t __SHASX( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) - (y >> 17)); + s = (((x >> 17) + (s >> 1)) << 16); + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + static __INLINE q31_t __QSAX( + q31_t x, + q31_t y) + { + + q31_t sum = 0; + + sum = ((sum + clip_q31_to_q15((q31_t) ((short) (x >> 16) - (short) y))) << 16) + + clip_q31_to_q15((q31_t) ((short) x + (short) (y >> 16))); + + return sum; + } + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + static __INLINE q31_t __SHSAX( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) + (y >> 17)); + s = (((x >> 17) - (s >> 1)) << 16); + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + static __INLINE q31_t __SMUSDX( + q31_t x, + q31_t y) + { + + return ((q31_t)(((short) x * (short) (y >> 16)) - + ((short) (x >> 16) * (short) y))); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + static __INLINE q31_t __SMUADX( + q31_t x, + q31_t y) + { + + return ((q31_t)(((short) x * (short) (y >> 16)) + + ((short) (x >> 16) * (short) y))); + } + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + static __INLINE q31_t __QADD( + q31_t x, + q31_t y) + { + return clip_q63_to_q31((q63_t) x + y); + } + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + static __INLINE q31_t __QSUB( + q31_t x, + q31_t y) + { + return clip_q63_to_q31((q63_t) x - y); + } + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + static __INLINE q31_t __SMLAD( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y >> 16)) + + ((short) x * (short) y)); + } + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + static __INLINE q31_t __SMLADX( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y)) + + ((short) x * (short) (y >> 16))); + } + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + static __INLINE q31_t __SMLSDX( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum - ((short) (x >> 16) * (short) (y)) + + ((short) x * (short) (y >> 16))); + } + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + static __INLINE q63_t __SMLALD( + q31_t x, + q31_t y, + q63_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y >> 16)) + + ((short) x * (short) y)); + } + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + static __INLINE q63_t __SMLALDX( + q31_t x, + q31_t y, + q63_t sum) + { + + return (sum + ((short) (x >> 16) * (short) y)) + + ((short) x * (short) (y >> 16)); + } + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + static __INLINE q31_t __SMUAD( + q31_t x, + q31_t y) + { + + return (((x >> 16) * (y >> 16)) + + (((x << 16) >> 16) * ((y << 16) >> 16))); + } + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + static __INLINE q31_t __SMUSD( + q31_t x, + q31_t y) + { + + return (-((x >> 16) * (y >> 16)) + + (((x << 16) >> 16) * ((y << 16) >> 16))); + } + + + + +#endif /* (ARM_MATH_CM3) || defined (ARM_MATH_CM0) */ + + + /** + * @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. + * @return none. + */ + 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. + * @return none + */ + 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. + * @return none. + */ + 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. + * @return none. + */ + 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. + * @return none. + */ + 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. + * @return none. + */ + 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. + * @return none. + */ + 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. + * @return none. + */ + 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. + * @return none. + */ + 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. + * @return none. + */ + + 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 + * @return none + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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 + * @return none + */ + + 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. + * @return none. + */ + + 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. + * @return none + */ + + 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 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 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 + * @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. + * @return none + */ + + 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. + * @return none + */ + + 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. + * @return none + */ + + 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 . */ + #ifdef ARM_MATH_CM0 + 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. + * @return none. + */ + 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 + * @return none + */ + 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. + * @return none. + */ + 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 + * @return none + */ + + 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. + * @return none. + */ + 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 + * @return none + */ + 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; + float32_t x1; + float32_t 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 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; + + /** + * @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; + + /** + * @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; + + /** + * @brief Processing function for the Q15 CFFT/CIFFT. + * @param[in] *S points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Initialization function for the Q15 CFFT/CIFFT. + * @param[in,out] *S points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. + */ + + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Processing function for the Q31 CFFT/CIFFT. + * @param[in] *S points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Initialization function for the Q31 CFFT/CIFFT. + * @param[in,out] *S points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. + */ + + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Processing function for the floating-point CFFT/CIFFT. + * @param[in] *S points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Initialization function for the floating-point CFFT/CIFFT. + * @param[in,out] *S points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. + */ + + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + + + /*---------------------------------------------------------------------- + * Internal functions prototypes FFT function + ----------------------------------------------------------------------*/ + + /** + * @brief Core function for the floating-point CFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to the twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_f32( + float32_t * pSrc, + uint16_t fftLen, + float32_t * pCoef, + uint16_t twidCoefModifier); + + /** + * @brief Core function for the floating-point CIFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @param[in] onebyfftLen value of 1/fftLen. + * @return none. + */ + + void arm_radix4_butterfly_inverse_f32( + float32_t * pSrc, + uint16_t fftLen, + float32_t * pCoef, + uint16_t twidCoefModifier, + float32_t onebyfftLen); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftSize length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table. + * @param[in] *pBitRevTab points to the bit reversal table. + * @return none. + */ + + void arm_bitreversal_f32( + float32_t *pSrc, + uint16_t fftSize, + uint16_t bitRevFactor, + uint16_t *pBitRevTab); + + /** + * @brief Core function for the Q31 CFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_q31( + q31_t *pSrc, + uint32_t fftLen, + q31_t *pCoef, + uint32_t twidCoefModifier); + + /** + * @brief Core function for the Q31 CIFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + q31_t * pCoef, + uint32_t twidCoefModifier); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table + * @param[in] *pBitRevTab points to bit reversal table. + * @return none. + */ + + void arm_bitreversal_q31( + q31_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + uint16_t *pBitRevTab); + + /** + * @brief Core function for the Q15 CFFT butterfly process. + * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef16 points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_q15( + q15_t *pSrc16, + uint32_t fftLen, + q15_t *pCoef16, + uint32_t twidCoefModifier); + + /** + * @brief Core function for the Q15 CIFFT butterfly process. + * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef16 points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_inverse_q15( + q15_t *pSrc16, + uint32_t fftLen, + q15_t *pCoef16, + uint32_t twidCoefModifier); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table + * @param[in] *pBitRevTab points to bit reversal table. + * @return none. + */ + + void arm_bitreversal_q15( + q15_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + uint16_t *pBitRevTab); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint32_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. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint32_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. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + /** + * @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; + + /** + * @brief Processing function for the Q15 RFFT/RIFFT. + * @param[in] *S points to an instance of the Q15 RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Initialization function for the Q15 RFFT/RIFFT. + * @param[in, out] *S points to an instance of the Q15 RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. + */ + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + /** + * @brief Processing function for the Q31 RFFT/RIFFT. + * @param[in] *S points to an instance of the Q31 RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Initialization function for the Q31 RFFT/RIFFT. + * @param[in, out] *S points to an instance of the Q31 RFFT/RIFFT structure. + * @param[in, out] *S_CFFT points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. + */ + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + /** + * @brief Initialization function for the floating-point RFFT/RIFFT. + * @param[in,out] *S points to an instance of the floating-point RFFT/RIFFT structure. + * @param[in,out] *S_CFFT points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. + */ + + 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); + + /** + * @brief Processing function for the floating-point RFFT/RIFFT. + * @param[in] *S points to an instance of the floating-point RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + 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 + * @return none. + */ + 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 + * @return none. + */ + 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 + * @return none. + */ + 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 + * @return none. + */ + 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 + * @return none. + */ + 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 + * @return none. + */ + 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 + * @return none. + */ + 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. + * @return none. + */ + + 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 location where the output result is written. Length srcALen+srcBLen-1. + * @return none. + */ + + 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. + * @return none. + */ + + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @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 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. + * @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. + * @return none + */ + + 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. + * @return none + */ + + 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. + * @return none + */ + + 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. + * @return none + */ + + 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. + * @return none + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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 + * @return none + */ + + 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 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. + * @return none. + */ + + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_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. + * @return none + */ + + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_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. + * @return none. + */ + + 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. + * @return none. + */ + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none + */ + + 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. + * @return none. + */ + + 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. + * @return none + */ + + 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. + * @return none. + */ + + 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. + * @return none + */ + + 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. + * @return none. + */ + + 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. + * @return none + */ + + 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. + * @return none. + */ + + void arm_sin_cos_f32( + float32_t theta, + float32_t *pSinVal, + float32_t *pCcosVal); + + /* + * @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. + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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. + */ + + + 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. + */ + + 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. + */ + + static __INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + + /* Implementation of PID controller */ + + #ifdef ARM_MATH_CM0 + + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0 )* in ; + + #else + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD(S->A0, in); + + #endif + + #ifdef ARM_MATH_CM0 + + /* 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] ; + + #else + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc = __SMLALD(S->A1, (q31_t)__SIMD32(S->state), acc); + + #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); + + + + /** + * @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 + * @return none. + */ + + 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 + * @return none. + * + * 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. + */ + + 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 + * @return none. + */ + 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 + * @return none. + */ + + + 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.5 * Ialpha + (float32_t) 0.8660254039 *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 + * @return none. + * + * 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. + */ + + 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 + * @return none. + */ + 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 + * @return none. + * + * The function implements the forward Park transform. + * + */ + + 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 + * @return none. + * + * 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. + */ + + + 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 + * @return none. + */ + 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 + * @return none. + */ + + 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 + * @return none. + * + * 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. + */ + + + 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 + * @return none. + */ + 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. + * + */ + + 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 = (x - S->x1) / xSpacing; + + if(i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if(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. + * + */ + + + 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 & 0xFFF00000) >> 20); + + if(index >= (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 + 1u]; + + /* 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. + * + */ + + + 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 & 0xFFF00000) >> 20u); + + if(index >= (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 + 1u]; + + /* 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 (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. + */ + + + 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 */ + 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 & 0xFFF00000) >> 20u); + + + if(index >= (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 and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* 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 (y >> 20u); + + } + + } + /** + * @} 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. + */ + + static __INLINE arm_status arm_sqrt_f32( + float32_t in, float32_t *pOut) + { + if(in > 0) + { + +// #if __FPU_USED + #if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(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. + */ + + 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 = wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + 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. + */ + + 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 = wOffset; + } + + + + /** + * @brief Q15 Circular Read function. + */ + 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. + */ + + 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 = wOffset; + } + + + + /** + * @brief Q7 Circular Read function. + */ + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + 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. + * @return none. + */ + 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. + * @return none. + */ + 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. + * @return none. + */ + + 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. + * @return none. + */ + + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_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. + * @return none. + */ + + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q31_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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + + 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. + * @return none. + */ + 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. + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + + 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 + * @return none. + */ + 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 + * @return none + */ + 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 + * @return none + */ + 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 + * @return none. + */ + 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 + * @return none. + */ + 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 + * @return none. + */ + 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 + * @return none. + */ + 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 + * @return none. + */ + 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. + */ + + + 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. + */ + + 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 & 0xFFF00000) >> 20u); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20u); + + /* 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) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + /* 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) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* 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 (acc << 2u); + + } + + /** + * @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. + */ + + 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 & 0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 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[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + + /* 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[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* 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 (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. + */ + + 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 & 0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 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[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + + /* 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[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* 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 (acc >> 40); + + } + + /** + * @} end of BilinearInterpolate group + */ + + + + + + +#ifdef __cplusplus +} +#endif + + +#endif /* _ARM_MATH_H */ + + +/** + * + * End of file. + */ diff --git a/System/core_cm0.h b/System/core_cm0.h new file mode 100644 index 0000000..9d7a19f --- /dev/null +++ b/System/core_cm0.h @@ -0,0 +1,665 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + + +/** \mainpage CMSIS Cortex-M0 + + This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. + It consists of: + + - Cortex-M Core Register Definitions + - Cortex-M functions + - Cortex-M instructions + + The CMSIS Cortex-M0 Core Peripheral Access Layer contains C and assembly functions that ease + access to the Cortex-M Core + */ + +/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions + CMSIS violates following MISRA-C2004 Rules: + + - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \defgroup CMSIS_core_definitions CMSIS Core Definitions + This file defines all structures and symbols for CMSIS core: + - CMSIS version number + - Cortex-M core + - Cortex-M core Revision Number + @{ + */ + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | __CM0_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00) /*!< Cortex core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + +#endif + +/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + /* add preprocessor checks */ +#endif + +#include /*!< standard types definitions */ +#include "core_cmInstr.h" /*!< Core Instruction Access */ +#include "core_cmFunc.h" /*!< Core Function Access */ + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000 + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +#ifdef __cplusplus + #define __I volatile /*!< defines 'read only' permissions */ +#else + #define __I volatile const /*!< defines 'read only' permissions */ +#endif +#define __O volatile /*!< defines 'write only' permissions */ +#define __IO volatile /*!< defines 'read / write' permissions */ + +/*@} end of group CMSIS_core_definitions */ + + + +/******************************************************************************* + * Register Abstraction + ******************************************************************************/ +/** \defgroup CMSIS_core_register CMSIS Core Register + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE CMSIS Core + Type definitions for the Cortex-M Core Registers + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC CMSIS NVIC + Type definitions for the Cortex-M NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB CMSIS SCB + Type definitions for the Cortex-M System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick CMSIS SysTick + Type definitions for the Cortex-M System Timer Registers + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug CMSIS Core Debug + Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP + and not via processor. Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + @{ + */ + +/* Memory mapping of Cortex-M0 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space 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 */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 ) +#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + + +/** \brief Enable External Interrupt + + This function enables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to enable + */ +static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Disable External Interrupt + + This function disables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to disable + */ +static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Get Pending Interrupt + + This function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Number of the interrupt for get pending + \return 0 Interrupt status is not pending + \return 1 Interrupt status is pending + */ +static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + + +/** \brief Set Pending Interrupt + + This function sets the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for set pending + */ +static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Clear Pending Interrupt + + This function clears the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for clear pending + */ +static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Set Interrupt Priority + + This function sets the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + Note: The priority cannot be set for every core interrupt. + + \param [in] IRQn Number of the interrupt for set priority + \param [in] priority Priority to set + */ +static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } + else { + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } +} + + +/** \brief Get Interrupt Priority + + This function reads the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + The returned priority value is automatically aligned to the implemented + priority bits of the microcontroller. + + \param [in] IRQn Number of the interrupt for get priority + \return Interrupt Priority + */ +static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ + else { + return((uint32_t)((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief System Reset + + This function initiate a system reset request to reset the MCU. + */ +static __INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + This function initialises the system tick timer and its interrupt and start the system tick timer. + Counter is in free running mode to generate periodical interrupts. + + \param [in] ticks Number of ticks between two interrupts + \return 0 Function succeeded + \return 1 Function failed + */ +static __INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/System/core_cm3.h b/System/core_cm3.h new file mode 100644 index 0000000..1c68818 --- /dev/null +++ b/System/core_cm3.h @@ -0,0 +1,1236 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + + +/** \mainpage CMSIS Cortex-M3 + + This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. + It consists of: + + - Cortex-M Core Register Definitions + - Cortex-M functions + - Cortex-M instructions + + The CMSIS Cortex-M3 Core Peripheral Access Layer contains C and assembly functions that ease + access to the Cortex-M Core + */ + +/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions + CMSIS violates following MISRA-C2004 Rules: + + - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \defgroup CMSIS_core_definitions CMSIS Core Definitions + This file defines all structures and symbols for CMSIS core: + - CMSIS version number + - Cortex-M core + - Cortex-M core Revision Number + @{ + */ + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x03) /*!< Cortex core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + +#endif + +/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + /* add preprocessor checks */ +#endif + +#include /*!< standard types definitions */ +#include "core_cmInstr.h" /*!< Core Instruction Access */ +#include "core_cmFunc.h" /*!< Core Function Access */ + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200 + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +#ifdef __cplusplus + #define __I volatile /*!< defines 'read only' permissions */ +#else + #define __I volatile const /*!< defines 'read only' permissions */ +#endif +#define __O volatile /*!< defines 'write only' permissions */ +#define __IO volatile /*!< defines 'read / write' permissions */ + +/*@} end of group CMSIS_core_definitions */ + + + +/******************************************************************************* + * Register Abstraction + ******************************************************************************/ +/** \defgroup CMSIS_core_register CMSIS Core Register + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE CMSIS Core + Type definitions for the Cortex-M Core Registers + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC CMSIS NVIC + Type definitions for the Cortex-M NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB CMSIS SCB + Type definitions for the Cortex-M System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB CMSIS System Control and ID Register not in the SCB + Type definitions for the Cortex-M System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if ((defined __CM3_REV) && (__CM3_REV >= 0x200)) + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick CMSIS SysTick + Type definitions for the Cortex-M System Timer Registers + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM CMSIS ITM + Type definitions for the Cortex-M Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_TXENA_Pos 3 /*!< ITM TCR: TXENA Position */ +#define ITM_TCR_TXENA_Msk (1UL << ITM_TCR_TXENA_Pos) /*!< ITM TCR: TXENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU CMSIS MPU + Type definitions for the Cortex-M Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug CMSIS Core Debug + Type definitions for the Cortex-M Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions + @{ + */ + +/** \brief Set Priority Grouping + + This function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field + */ +static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + This function gets the priority grouping from NVIC Interrupt Controller. + Priority grouping is SCB->AIRCR [10:8] PRIGROUP field. + + \return Priority grouping field + */ +static __INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + This function enables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to enable + */ +static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + This function disables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to disable + */ +static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + This function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Number of the interrupt for get pending + \return 0 Interrupt status is not pending + \return 1 Interrupt status is pending + */ +static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + This function sets the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for set pending + */ +static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + This function clears the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for clear pending + */ +static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + This function reads the active register in NVIC and returns the active bit. + \param [in] IRQn Number of the interrupt for get active + \return 0 Interrupt status is not active + \return 1 Interrupt status is active + */ +static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + This function sets the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + Note: The priority cannot be set for every core interrupt. + + \param [in] IRQn Number of the interrupt for set priority + \param [in] priority Priority to set + */ +static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + This function reads the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + The returned priority value is automatically aligned to the implemented + priority bits of the microcontroller. + + \param [in] IRQn Number of the interrupt for get priority + \return Interrupt Priority + */ +static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + This function encodes the priority for an interrupt with the given priority group, + preemptive priority value and sub priority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + The returned priority value can be used for NVIC_SetPriority(...) function + + \param [in] PriorityGroup Used priority group + \param [in] PreemptPriority Preemptive priority value (starting from 0) + \param [in] SubPriority Sub priority value (starting from 0) + \return Encoded priority for the interrupt + */ +static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + This function decodes an interrupt priority value with the given priority group to + preemptive priority value and sub priority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + The priority value can be retrieved with NVIC_GetPriority(...) function + + \param [in] Priority Priority value + \param [in] PriorityGroup Used priority group + \param [out] pPreemptPriority Preemptive priority value (starting from 0) + \param [out] pSubPriority Sub priority value (starting from 0) + */ +static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + This function initiate a system reset request to reset the MCU. + */ +static __INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + This function initialises the system tick timer and its interrupt and start the system tick timer. + Counter is in free running mode to generate periodical interrupts. + + \param [in] ticks Number of ticks between two interrupts + \return 0 Function succeeded + \return 1 Function failed + */ +static __INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions CMSIS Core Debug Functions + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< external variable to receive characters */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */ + + +/** \brief ITM Send Character + + This function transmits a character via the ITM channel 0. + It just returns when no debugger is connected that has booked the output. + It is blocking when a debugger is connected, but the previous character send is not transmitted. + + \param [in] ch Character to transmit + \return Character to transmit + */ +static __INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */ + (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + This function inputs a character via external variable ITM_RxBuffer. + It just returns when no debugger is connected that has booked the output. + It is blocking when a debugger is connected, but the previous character send is not transmitted. + + \return Received character + \return -1 No character received + */ +static __INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + This function checks external variable ITM_RxBuffer whether a character is available or not. + It returns '1' if a character is available and '0' if no character is available. + + \return 0 No character available + \return 1 Character available + */ +static __INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/System/core_cm4.h b/System/core_cm4.h new file mode 100644 index 0000000..bf022ba --- /dev/null +++ b/System/core_cm4.h @@ -0,0 +1,1378 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + + +/** \mainpage CMSIS Cortex-M4 + + This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. + It consists of: + + - Cortex-M Core Register Definitions + - Cortex-M functions + - Cortex-M instructions + - Cortex-M SIMD instructions + + The CMSIS Cortex-M4 Core Peripheral Access Layer contains C and assembly functions that ease + access to the Cortex-M Core + */ + +/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions + CMSIS violates following MISRA-C2004 Rules: + + - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \defgroup CMSIS_core_definitions CMSIS Core Definitions + This file defines all structures and symbols for CMSIS core: + - CMSIS version number + - Cortex-M core + - Cortex-M core Revision Number + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | __CM4_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04) /*!< Cortex core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + +#endif + +/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TASKING__ ) + /* add preprocessor checks to define __FPU_USED */ + #define __FPU_USED 0 +#endif + +#include /*!< standard types definitions */ +#include /*!< Core Instruction Access */ +#include /*!< Core Function Access */ +#include /*!< Compiler specific SIMD Intrinsics */ + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000 + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0 + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +#ifdef __cplusplus + #define __I volatile /*!< defines 'read only' permissions */ +#else + #define __I volatile const /*!< defines 'read only' permissions */ +#endif +#define __O volatile /*!< defines 'write only' permissions */ +#define __IO volatile /*!< defines 'read / write' permissions */ + +/*@} end of group CMSIS_core_definitions */ + + + +/******************************************************************************* + * Register Abstraction + ******************************************************************************/ +/** \defgroup CMSIS_core_register CMSIS Core Register + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE CMSIS Core + Type definitions for the Cortex-M Core Registers + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC CMSIS NVIC + Type definitions for the Cortex-M NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB CMSIS SCB + Type definitions for the Cortex-M System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB CMSIS System Control and ID Register not in the SCB + Type definitions for the Cortex-M System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick CMSIS SysTick + Type definitions for the Cortex-M System Timer Registers + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM CMSIS ITM + Type definitions for the Cortex-M Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_TXENA_Pos 3 /*!< ITM TCR: TXENA Position */ +#define ITM_TCR_TXENA_Msk (1UL << ITM_TCR_TXENA_Pos) /*!< ITM TCR: TXENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU CMSIS MPU + Type definitions for the Cortex-M Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if (__FPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_FPU CMSIS FPU + Type definitions for the Cortex-M Floating Point Unit (FPU) + @{ + */ + +/** \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register */ +#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register */ +#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register */ +#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug CMSIS Core Debug + Type definitions for the Cortex-M Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions + @{ + */ + +/** \brief Set Priority Grouping + + This function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field + */ +static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + This function gets the priority grouping from NVIC Interrupt Controller. + Priority grouping is SCB->AIRCR [10:8] PRIGROUP field. + + \return Priority grouping field + */ +static __INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + This function enables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to enable + */ +static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ +/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + This function disables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to disable + */ +static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + This function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Number of the interrupt for get pending + \return 0 Interrupt status is not pending + \return 1 Interrupt status is pending + */ +static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + This function sets the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for set pending + */ +static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + This function clears the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for clear pending + */ +static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + This function reads the active register in NVIC and returns the active bit. + \param [in] IRQn Number of the interrupt for get active + \return 0 Interrupt status is not active + \return 1 Interrupt status is active + */ +static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + This function sets the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + Note: The priority cannot be set for every core interrupt. + + \param [in] IRQn Number of the interrupt for set priority + \param [in] priority Priority to set + */ +static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + This function reads the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + The returned priority value is automatically aligned to the implemented + priority bits of the microcontroller. + + \param [in] IRQn Number of the interrupt for get priority + \return Interrupt Priority + */ +static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + This function encodes the priority for an interrupt with the given priority group, + preemptive priority value and sub priority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + The returned priority value can be used for NVIC_SetPriority(...) function + + \param [in] PriorityGroup Used priority group + \param [in] PreemptPriority Preemptive priority value (starting from 0) + \param [in] SubPriority Sub priority value (starting from 0) + \return Encoded priority for the interrupt + */ +static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + This function decodes an interrupt priority value with the given priority group to + preemptive priority value and sub priority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + The priority value can be retrieved with NVIC_GetPriority(...) function + + \param [in] Priority Priority value + \param [in] PriorityGroup Used priority group + \param [out] pPreemptPriority Preemptive priority value (starting from 0) + \param [out] pSubPriority Sub priority value (starting from 0) + */ +static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + This function initiate a system reset request to reset the MCU. + */ +static __INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + This function initialises the system tick timer and its interrupt and start the system tick timer. + Counter is in free running mode to generate periodical interrupts. + + \param [in] ticks Number of ticks between two interrupts + \return 0 Function succeeded + \return 1 Function failed + */ +static __INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions CMSIS Core Debug Functions + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< external variable to receive characters */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */ + + +/** \brief ITM Send Character + + This function transmits a character via the ITM channel 0. + It just returns when no debugger is connected that has booked the output. + It is blocking when a debugger is connected, but the previous character send is not transmitted. + + \param [in] ch Character to transmit + \return Character to transmit + */ +static __INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */ + (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + This function inputs a character via external variable ITM_RxBuffer. + It just returns when no debugger is connected that has booked the output. + It is blocking when a debugger is connected, but the previous character send is not transmitted. + + \return Received character + \return -1 No character received + */ +static __INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + This function checks external variable ITM_RxBuffer whether a character is available or not. + It returns '1' if a character is available and '0' if no character is available. + + \return 0 No character available + \return 1 Character available + */ +static __INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/System/core_cm4_simd.h b/System/core_cm4_simd.h new file mode 100644 index 0000000..e7b6765 --- /dev/null +++ b/System/core_cm4_simd.h @@ -0,0 +1,701 @@ +/**************************************************************************//** + * @file core_cm4_simd.h + * @brief CMSIS Cortex-M4 SIMD Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM4_SIMD_H +#define __CORE_CM4_SIMD_H + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +/*------ CM4 SOMD Intrinsics -----------------------------------------------------*/ +#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) ) + + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + +/*------ CM4 SIMDDSP Intrinsics -----------------------------------------------------*/ +/* intrinsic __SADD8 see intrinsics.h */ +/* intrinsic __QADD8 see intrinsics.h */ +/* intrinsic __SHADD8 see intrinsics.h */ +/* intrinsic __UADD8 see intrinsics.h */ +/* intrinsic __UQADD8 see intrinsics.h */ +/* intrinsic __UHADD8 see intrinsics.h */ +/* intrinsic __SSUB8 see intrinsics.h */ +/* intrinsic __QSUB8 see intrinsics.h */ +/* intrinsic __SHSUB8 see intrinsics.h */ +/* intrinsic __USUB8 see intrinsics.h */ +/* intrinsic __UQSUB8 see intrinsics.h */ +/* intrinsic __UHSUB8 see intrinsics.h */ +/* intrinsic __SADD16 see intrinsics.h */ +/* intrinsic __QADD16 see intrinsics.h */ +/* intrinsic __SHADD16 see intrinsics.h */ +/* intrinsic __UADD16 see intrinsics.h */ +/* intrinsic __UQADD16 see intrinsics.h */ +/* intrinsic __UHADD16 see intrinsics.h */ +/* intrinsic __SSUB16 see intrinsics.h */ +/* intrinsic __QSUB16 see intrinsics.h */ +/* intrinsic __SHSUB16 see intrinsics.h */ +/* intrinsic __USUB16 see intrinsics.h */ +/* intrinsic __UQSUB16 see intrinsics.h */ +/* intrinsic __UHSUB16 see intrinsics.h */ +/* intrinsic __SASX see intrinsics.h */ +/* intrinsic __QASX see intrinsics.h */ +/* intrinsic __SHASX see intrinsics.h */ +/* intrinsic __UASX see intrinsics.h */ +/* intrinsic __UQASX see intrinsics.h */ +/* intrinsic __UHASX see intrinsics.h */ +/* intrinsic __SSAX see intrinsics.h */ +/* intrinsic __QSAX see intrinsics.h */ +/* intrinsic __SHSAX see intrinsics.h */ +/* intrinsic __USAX see intrinsics.h */ +/* intrinsic __UQSAX see intrinsics.h */ +/* intrinsic __UHSAX see intrinsics.h */ +/* intrinsic __USAD8 see intrinsics.h */ +/* intrinsic __USADA8 see intrinsics.h */ +/* intrinsic __SSAT16 see intrinsics.h */ +/* intrinsic __USAT16 see intrinsics.h */ +/* intrinsic __UXTB16 see intrinsics.h */ +/* intrinsic __SXTB16 see intrinsics.h */ +/* intrinsic __UXTAB16 see intrinsics.h */ +/* intrinsic __SXTAB16 see intrinsics.h */ +/* intrinsic __SMUAD see intrinsics.h */ +/* intrinsic __SMUADX see intrinsics.h */ +/* intrinsic __SMLAD see intrinsics.h */ +/* intrinsic __SMLADX see intrinsics.h */ +/* intrinsic __SMLALD see intrinsics.h */ +/* intrinsic __SMLALDX see intrinsics.h */ +/* intrinsic __SMUSD see intrinsics.h */ +/* intrinsic __SMUSDX see intrinsics.h */ +/* intrinsic __SMLSD see intrinsics.h */ +/* intrinsic __SMLSDX see intrinsics.h */ +/* intrinsic __SMLSLD see intrinsics.h */ +/* intrinsic __SMLSLDX see intrinsics.h */ +/* intrinsic __SEL see intrinsics.h */ +/* intrinsic __QADD see intrinsics.h */ +/* intrinsic __QSUB see intrinsics.h */ +/* intrinsic __PKHBT see intrinsics.h */ +/* intrinsic __PKHTB see intrinsics.h */ + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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) \ +({ \ + uint32_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; \ + }) + +__attribute__( ( always_inline ) ) static __INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +#define __SMLALD(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +#define __SMLALDX(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +#define __SMLSLD(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +#define __SMLSLDX(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +__attribute__( ( always_inline ) ) static __INLINE 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); +} + +__attribute__( ( always_inline ) ) static __INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) static __INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#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; \ + }) + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +/* not yet supported */ +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + +#endif + +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CORE_CM4_SIMD_H */ + +#ifdef __cplusplus +} +#endif diff --git a/System/core_cmFunc.h b/System/core_cmFunc.h new file mode 100644 index 0000000..88819f9 --- /dev/null +++ b/System/core_cmFunc.h @@ -0,0 +1,609 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V2.10 + * @date 26. July 2011 + * + * @note + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** \brief Get Control Register + + This function 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 + + This function 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 ISPR Register + + This function returns the content of the ISPR Register. + + \return ISPR Register value + */ +static __INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** \brief Get APSR Register + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function 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 + + This function 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 + + This function 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 + + This function 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 & 0xff); +} + + +/** \brief Get Fault Mask + + This function 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 + + This function 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)1); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function 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 (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function 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 (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief Enable IRQ Interrupts + + This function enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i"); +} + + +/** \brief Disable IRQ Interrupts + + This function disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i"); +} + + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) ); +} + + +/** \brief Get ISPR Register + + This function returns the content of the ISPR Register. + + \return ISPR Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) ); +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) ); +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f"); +} + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f"); +} + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) ); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) ); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +#endif /* __CORE_CMFUNC_H */ diff --git a/System/core_cmInstr.h b/System/core_cmInstr.h new file mode 100644 index 0000000..78d2ef8 --- /dev/null +++ b/System/core_cmInstr.h @@ -0,0 +1,585 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +static __INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +static __INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW(value, ptr) __strex(value, ptr) + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#define __CLREX __clrex + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +#endif /* (__CORTEX_M >= 0x03) */ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__( ( always_inline ) ) static __INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) static __INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) static __INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__( ( always_inline ) ) static __INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +__attribute__( ( always_inline ) ) static __INLINE void __ISB(void) +{ + __ASM volatile ("isb"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__( ( always_inline ) ) static __INLINE void __DSB(void) +{ + __ASM volatile ("dsb"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__( ( always_inline ) ) static __INLINE void __DMB(void) +{ + __ASM volatile ("dmb"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value) +{ + uint32_t result; + + __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint8_t result; + + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint16_t result; + + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void) +{ + __ASM volatile ("clrex"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value) +{ + uint8_t result; + + __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/System/startup_stm32f4xx.s b/System/startup_stm32f4xx.s new file mode 100644 index 0000000..d6e2ac8 --- /dev/null +++ b/System/startup_stm32f4xx.s @@ -0,0 +1,427 @@ +;******************** (C) COPYRIGHT 2011 STMicroelectronics ******************** +;* File Name : startup_stm32f4xx.s +;* Author : MCD Application Team +;* Version : V1.0.0 +;* Date : 30-September-2011 +;* Description : STM32F4xx devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Configure the system clock and the external SRAM mounted on +;* STM324xG-EVAL board to be used as data memory (optional, +;* to be enabled by user) +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the CortexM4 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;* <<< Use Configuration Wizard in Context Menu >>> +;******************************************************************************* +; THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +; WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +; AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +; INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +; CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +; INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +;******************************************************************************* + +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00004000 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000000 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_IRQHandler ; PVD through EXTI Line detection + DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line + DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line + DCD FLASH_IRQHandler ; FLASH + DCD RCC_IRQHandler ; RCC + DCD EXTI0_IRQHandler ; EXTI Line0 + DCD EXTI1_IRQHandler ; EXTI Line1 + DCD EXTI2_IRQHandler ; EXTI Line2 + DCD EXTI3_IRQHandler ; EXTI Line3 + DCD EXTI4_IRQHandler ; EXTI Line4 + DCD DMA1_Stream0_IRQHandler ; DMA1 Stream 0 + DCD DMA1_Stream1_IRQHandler ; DMA1 Stream 1 + DCD DMA1_Stream2_IRQHandler ; DMA1 Stream 2 + DCD DMA1_Stream3_IRQHandler ; DMA1 Stream 3 + DCD DMA1_Stream4_IRQHandler ; DMA1 Stream 4 + DCD DMA1_Stream5_IRQHandler ; DMA1 Stream 5 + DCD DMA1_Stream6_IRQHandler ; DMA1 Stream 6 + DCD ADC_IRQHandler ; ADC1, ADC2 and ADC3s + DCD CAN1_TX_IRQHandler ; CAN1 TX + DCD CAN1_RX0_IRQHandler ; CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; CAN1 RX1 + DCD CAN1_SCE_IRQHandler ; CAN1 SCE + DCD EXTI9_5_IRQHandler ; External Line[9:5]s + DCD TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9 + DCD TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10 + DCD TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11 + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare + DCD TIM2_IRQHandler ; TIM2 + DCD TIM3_IRQHandler ; TIM3 + DCD TIM4_IRQHandler ; TIM4 + DCD I2C1_EV_IRQHandler ; I2C1 Event + DCD I2C1_ER_IRQHandler ; I2C1 Error + DCD I2C2_EV_IRQHandler ; I2C2 Event + DCD I2C2_ER_IRQHandler ; I2C2 Error + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART3_IRQHandler ; USART3 + DCD EXTI15_10_IRQHandler ; External Line[15:10]s + DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line + DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line + DCD TIM8_BRK_TIM12_IRQHandler ; TIM8 Break and TIM12 + DCD TIM8_UP_TIM13_IRQHandler ; TIM8 Update and TIM13 + DCD TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation and TIM14 + DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare + DCD DMA1_Stream7_IRQHandler ; DMA1 Stream7 + DCD FSMC_IRQHandler ; FSMC + DCD SDIO_IRQHandler ; SDIO + DCD TIM5_IRQHandler ; TIM5 + DCD SPI3_IRQHandler ; SPI3 + DCD UART4_IRQHandler ; UART4 + DCD UART5_IRQHandler ; UART5 + DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors + DCD TIM7_IRQHandler ; TIM7 + DCD DMA2_Stream0_IRQHandler ; DMA2 Stream 0 + DCD DMA2_Stream1_IRQHandler ; DMA2 Stream 1 + DCD DMA2_Stream2_IRQHandler ; DMA2 Stream 2 + DCD DMA2_Stream3_IRQHandler ; DMA2 Stream 3 + DCD DMA2_Stream4_IRQHandler ; DMA2 Stream 4 + DCD ETH_IRQHandler ; Ethernet + DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line + DCD CAN2_TX_IRQHandler ; CAN2 TX + DCD CAN2_RX0_IRQHandler ; CAN2 RX0 + DCD CAN2_RX1_IRQHandler ; CAN2 RX1 + DCD CAN2_SCE_IRQHandler ; CAN2 SCE + DCD OTG_FS_IRQHandler ; USB OTG FS + DCD DMA2_Stream5_IRQHandler ; DMA2 Stream 5 + DCD DMA2_Stream6_IRQHandler ; DMA2 Stream 6 + DCD DMA2_Stream7_IRQHandler ; DMA2 Stream 7 + DCD USART6_IRQHandler ; USART6 + DCD I2C3_EV_IRQHandler ; I2C3 event + DCD I2C3_ER_IRQHandler ; I2C3 error + DCD OTG_HS_EP1_OUT_IRQHandler ; USB OTG HS End Point 1 Out + DCD OTG_HS_EP1_IN_IRQHandler ; USB OTG HS End Point 1 In + DCD OTG_HS_WKUP_IRQHandler ; USB OTG HS Wakeup through EXTI + DCD OTG_HS_IRQHandler ; USB OTG HS + DCD DCMI_IRQHandler ; DCMI + DCD CRYP_IRQHandler ; CRYP crypto + DCD HASH_RNG_IRQHandler ; Hash and Rng + DCD FPU_IRQHandler ; FPU + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_IRQHandler [WEAK] + EXPORT TAMP_STAMP_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA1_Stream0_IRQHandler [WEAK] + EXPORT DMA1_Stream1_IRQHandler [WEAK] + EXPORT DMA1_Stream2_IRQHandler [WEAK] + EXPORT DMA1_Stream3_IRQHandler [WEAK] + EXPORT DMA1_Stream4_IRQHandler [WEAK] + EXPORT DMA1_Stream5_IRQHandler [WEAK] + EXPORT DMA1_Stream6_IRQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT CAN1_TX_IRQHandler [WEAK] + EXPORT CAN1_RX0_IRQHandler [WEAK] + EXPORT CAN1_RX1_IRQHandler [WEAK] + EXPORT CAN1_SCE_IRQHandler [WEAK] + EXPORT EXTI9_5_IRQHandler [WEAK] + EXPORT TIM1_BRK_TIM9_IRQHandler [WEAK] + EXPORT TIM1_UP_TIM10_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_TIM11_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM4_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT EXTI15_10_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT OTG_FS_WKUP_IRQHandler [WEAK] + EXPORT TIM8_BRK_TIM12_IRQHandler [WEAK] + EXPORT TIM8_UP_TIM13_IRQHandler [WEAK] + EXPORT TIM8_TRG_COM_TIM14_IRQHandler [WEAK] + EXPORT TIM8_CC_IRQHandler [WEAK] + EXPORT DMA1_Stream7_IRQHandler [WEAK] + EXPORT FSMC_IRQHandler [WEAK] + EXPORT SDIO_IRQHandler [WEAK] + EXPORT TIM5_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT UART5_IRQHandler [WEAK] + EXPORT TIM6_DAC_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT DMA2_Stream0_IRQHandler [WEAK] + EXPORT DMA2_Stream1_IRQHandler [WEAK] + EXPORT DMA2_Stream2_IRQHandler [WEAK] + EXPORT DMA2_Stream3_IRQHandler [WEAK] + EXPORT DMA2_Stream4_IRQHandler [WEAK] + EXPORT ETH_IRQHandler [WEAK] + EXPORT ETH_WKUP_IRQHandler [WEAK] + EXPORT CAN2_TX_IRQHandler [WEAK] + EXPORT CAN2_RX0_IRQHandler [WEAK] + EXPORT CAN2_RX1_IRQHandler [WEAK] + EXPORT CAN2_SCE_IRQHandler [WEAK] + EXPORT OTG_FS_IRQHandler [WEAK] + EXPORT DMA2_Stream5_IRQHandler [WEAK] + EXPORT DMA2_Stream6_IRQHandler [WEAK] + EXPORT DMA2_Stream7_IRQHandler [WEAK] + EXPORT USART6_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT OTG_HS_EP1_OUT_IRQHandler [WEAK] + EXPORT OTG_HS_EP1_IN_IRQHandler [WEAK] + EXPORT OTG_HS_WKUP_IRQHandler [WEAK] + EXPORT OTG_HS_IRQHandler [WEAK] + EXPORT DCMI_IRQHandler [WEAK] + EXPORT CRYP_IRQHandler [WEAK] + EXPORT HASH_RNG_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_IRQHandler +TAMP_STAMP_IRQHandler +RTC_WKUP_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA1_Stream0_IRQHandler +DMA1_Stream1_IRQHandler +DMA1_Stream2_IRQHandler +DMA1_Stream3_IRQHandler +DMA1_Stream4_IRQHandler +DMA1_Stream5_IRQHandler +DMA1_Stream6_IRQHandler +ADC_IRQHandler +CAN1_TX_IRQHandler +CAN1_RX0_IRQHandler +CAN1_RX1_IRQHandler +CAN1_SCE_IRQHandler +EXTI9_5_IRQHandler +TIM1_BRK_TIM9_IRQHandler +TIM1_UP_TIM10_IRQHandler +TIM1_TRG_COM_TIM11_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +TIM3_IRQHandler +TIM4_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +EXTI15_10_IRQHandler +RTC_Alarm_IRQHandler +OTG_FS_WKUP_IRQHandler +TIM8_BRK_TIM12_IRQHandler +TIM8_UP_TIM13_IRQHandler +TIM8_TRG_COM_TIM14_IRQHandler +TIM8_CC_IRQHandler +DMA1_Stream7_IRQHandler +FSMC_IRQHandler +SDIO_IRQHandler +TIM5_IRQHandler +SPI3_IRQHandler +UART4_IRQHandler +UART5_IRQHandler +TIM6_DAC_IRQHandler +TIM7_IRQHandler +DMA2_Stream0_IRQHandler +DMA2_Stream1_IRQHandler +DMA2_Stream2_IRQHandler +DMA2_Stream3_IRQHandler +DMA2_Stream4_IRQHandler +ETH_IRQHandler +ETH_WKUP_IRQHandler +CAN2_TX_IRQHandler +CAN2_RX0_IRQHandler +CAN2_RX1_IRQHandler +CAN2_SCE_IRQHandler +OTG_FS_IRQHandler +DMA2_Stream5_IRQHandler +DMA2_Stream6_IRQHandler +DMA2_Stream7_IRQHandler +USART6_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +OTG_HS_EP1_OUT_IRQHandler +OTG_HS_EP1_IN_IRQHandler +OTG_HS_WKUP_IRQHandler +OTG_HS_IRQHandler +DCMI_IRQHandler +CRYP_IRQHandler +HASH_RNG_IRQHandler +FPU_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END + +;******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE***** diff --git a/System/stm32f4xx.h b/System/stm32f4xx.h new file mode 100644 index 0000000..f9441e8 --- /dev/null +++ b/System/stm32f4xx.h @@ -0,0 +1,7011 @@ +/** + ****************************************************************************** + * @file stm32f4xx.h + * @author MCD Application Team + * @version V1.0.0 + * @date 30-September-2011 + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File. + * This file contains all the peripheral register's definitions, bits + * definitions and memory mapping for STM32F4xx devices. + * + * The file is the unique include file that the application programmer + * is using in the C source code, usually in main.c. This file contains: + * - Configuration section that allows to select: + * - The device used in the target application + * - To use or not the peripherals drivers in application code(i.e. + * code will be based on direct access to peripherals registers + * rather than drivers API), this option is controlled by + * "#define USE_STDPERIPH_DRIVER" + * - To change few application-specific parameters such as the HSE + * crystal frequency + * - Data structures and the address mapping for all peripherals + * - Peripheral's registers declarations and bits definition + * - Macros to access peripherals registers hardware + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx + * @{ + */ + +#ifndef __STM32F4xx_H +#define __STM32F4xx_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/* Uncomment the line below according to the target STM32 device used in your + application + */ + +#if !defined (STM32F4XX) + #define STM32F4XX +#endif + +/* Tip: To avoid modifying this file each time you need to switch between these + devices, you can define the device in your toolchain compiler preprocessor. + */ + +#if !defined (STM32F4XX) + #error "Please select first the target STM32F4XX device used in your application (in stm32f4xx.h file)" +#endif + +#if !defined (USE_STDPERIPH_DRIVER) +/** + * @brief Comment the line below if you will not use the peripherals drivers. + In this case, these drivers will not be included and the application code will + be based on direct access to peripherals registers + */ + /*#define USE_STDPERIPH_DRIVER*/ +#endif /* USE_STDPERIPH_DRIVER */ + +/** + * @brief In the following line adjust the value of External High Speed oscillator (HSE) + used in your application + + Tip: To avoid modifying this file each time you need to use different HSE, you + can define the HSE value in your toolchain compiler preprocessor. + */ + +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + Timeout value + */ +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */ +#endif /* HSE_STARTUP_TIMEOUT */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief STM32F4XX Standard Peripherals Library version number V1.0.0 + */ +#define __STM32F4XX_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __STM32F4XX_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __STM32F4XX_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32F4XX_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __STM32F4XX_STDPERIPH_VERSION ((__STM32F4XX_STDPERIPH_VERSION_MAIN << 24)\ + |(__STM32F4XX_STDPERIPH_VERSION_SUB1 << 16)\ + |(__STM32F4XX_STDPERIPH_VERSION_SUB2 << 8)\ + |(__STM32F4XX_STDPERIPH_VERSION_RC)) + +/** + * @} + */ + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ + +/** + * @brief Configuration of the Cortex-M4 Processor and Core Peripherals + */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< STM32F4XX provides an MPU */ +#define __NVIC_PRIO_BITS 4 /*!< STM32F4XX uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +#if !defined (__FPU_PRESENT) + #define __FPU_PRESENT 1 /*!< FPU present */ +#endif /* __FPU_PRESENT */ + + + +/** + * @brief STM32F4XX Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ +typedef enum IRQn +{ +/****** Cortex-M4 Processor Exceptions Numbers ****************************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M4 System Tick Interrupt */ +/****** STM32 specific Interrupt Numbers **********************************************************************/ + WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ + PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ + TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp interrupts through the EXTI line */ + RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */ + FLASH_IRQn = 4, /*!< FLASH global Interrupt */ + RCC_IRQn = 5, /*!< RCC global Interrupt */ + EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ + EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ + EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ + EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ + EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ + DMA1_Stream0_IRQn = 11, /*!< DMA1 Stream 0 global Interrupt */ + DMA1_Stream1_IRQn = 12, /*!< DMA1 Stream 1 global Interrupt */ + DMA1_Stream2_IRQn = 13, /*!< DMA1 Stream 2 global Interrupt */ + DMA1_Stream3_IRQn = 14, /*!< DMA1 Stream 3 global Interrupt */ + DMA1_Stream4_IRQn = 15, /*!< DMA1 Stream 4 global Interrupt */ + DMA1_Stream5_IRQn = 16, /*!< DMA1 Stream 5 global Interrupt */ + DMA1_Stream6_IRQn = 17, /*!< DMA1 Stream 6 global Interrupt */ + ADC_IRQn = 18, /*!< ADC1, ADC2 and ADC3 global Interrupts */ + CAN1_TX_IRQn = 19, /*!< CAN1 TX Interrupt */ + CAN1_RX0_IRQn = 20, /*!< CAN1 RX0 Interrupt */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */ + TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */ + TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ + TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */ + TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */ + TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ + TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ + DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ + FSMC_IRQn = 48, /*!< FSMC global Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */ + TIM7_IRQn = 55, /*!< TIM7 global interrupt */ + DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ + DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ + DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ + DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ + DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ + ETH_IRQn = 61, /*!< Ethernet global Interrupt */ + ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ + CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ + CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ + CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ + CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ + OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ + DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ + DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ + DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ + USART6_IRQn = 71, /*!< USART6 global interrupt */ + I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ + I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ + OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */ + OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */ + OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI interrupt */ + OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */ + DCMI_IRQn = 78, /*!< DCMI global interrupt */ + CRYP_IRQn = 79, /*!< CRYP crypto global interrupt */ + HASH_RNG_IRQn = 80, /*!< Hash and Rng global interrupt */ + FPU_IRQn = 81 /*!< FPU global interrupt */ +} IRQn_Type; + +/** + * @} + */ + +#include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ +#include "system_stm32f4xx.h" +#include + +/** @addtogroup Exported_types + * @{ + */ +/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ +typedef int64_t s64; +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef int64_t int64; +typedef int32_t int32; +typedef int16_t int16; +typedef int8_t int8; + +typedef const int32_t sc32; /*!< Read Only */ +typedef const int16_t sc16; /*!< Read Only */ +typedef const int8_t sc8; /*!< Read Only */ + +typedef __IO int32_t vs32; +typedef __IO int16_t vs16; +typedef __IO int8_t vs8; + +typedef __I int32_t vsc32; /*!< Read Only */ +typedef __I int16_t vsc16; /*!< Read Only */ +typedef __I int8_t vsc8; /*!< Read Only */ + +//typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef const uint32_t uc32; /*!< Read Only */ +typedef const uint16_t uc16; /*!< Read Only */ +typedef const uint8_t uc8; /*!< Read Only */ + +typedef __IO uint32_t vu32; +typedef __IO uint16_t vu16; +typedef __IO uint8_t vu8; + +typedef __I uint32_t vuc32; /*!< Read Only */ +typedef __I uint16_t vuc16; /*!< Read Only */ +typedef __I uint8_t vuc8; /*!< Read Only */ + +typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; + +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; + +/** + * @} + */ + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/** + * @brief Analog to Digital Converter + */ + +typedef struct +{ + __IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */ + __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */ + __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */ + __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */ + __IO uint32_t JOFR1; /*!< ADC injected channel data offset register 1, Address offset: 0x14 */ + __IO uint32_t JOFR2; /*!< ADC injected channel data offset register 2, Address offset: 0x18 */ + __IO uint32_t JOFR3; /*!< ADC injected channel data offset register 3, Address offset: 0x1C */ + __IO uint32_t JOFR4; /*!< ADC injected channel data offset register 4, Address offset: 0x20 */ + __IO uint32_t HTR; /*!< ADC watchdog higher threshold register, Address offset: 0x24 */ + __IO uint32_t LTR; /*!< ADC watchdog lower threshold register, Address offset: 0x28 */ + __IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x2C */ + __IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x30 */ + __IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x34 */ + __IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x38*/ + __IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x3C */ + __IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x40 */ + __IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x44 */ + __IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x48 */ + __IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x4C */ +} ADC_TypeDef; + +typedef struct +{ + __IO uint32_t CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */ + __IO uint32_t CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ + __IO uint32_t CDR; /*!< ADC common regular data register for dual + AND triple modes, Address offset: ADC1 base address + 0x308 */ +} ADC_Common_TypeDef; + + +/** + * @brief Controller Area Network TxMailBox + */ + +typedef struct +{ + __IO uint32_t TIR; /*!< CAN TX mailbox identifier register */ + __IO uint32_t TDTR; /*!< CAN mailbox data length control and time stamp register */ + __IO uint32_t TDLR; /*!< CAN mailbox data low register */ + __IO uint32_t TDHR; /*!< CAN mailbox data high register */ +} CAN_TxMailBox_TypeDef; + +/** + * @brief Controller Area Network FIFOMailBox + */ + +typedef struct +{ + __IO uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */ + __IO uint32_t RDTR; /*!< CAN receive FIFO mailbox data length control and time stamp register */ + __IO uint32_t RDLR; /*!< CAN receive FIFO mailbox data low register */ + __IO uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */ +} CAN_FIFOMailBox_TypeDef; + +/** + * @brief Controller Area Network FilterRegister + */ + +typedef struct +{ + __IO uint32_t FR1; /*!< CAN Filter bank register 1 */ + __IO uint32_t FR2; /*!< CAN Filter bank register 1 */ +} CAN_FilterRegister_TypeDef; + +/** + * @brief Controller Area Network + */ + +typedef struct +{ + __IO uint32_t MCR; /*!< CAN master control register, Address offset: 0x00 */ + __IO uint32_t MSR; /*!< CAN master status register, Address offset: 0x04 */ + __IO uint32_t TSR; /*!< CAN transmit status register, Address offset: 0x08 */ + __IO uint32_t RF0R; /*!< CAN receive FIFO 0 register, Address offset: 0x0C */ + __IO uint32_t RF1R; /*!< CAN receive FIFO 1 register, Address offset: 0x10 */ + __IO uint32_t IER; /*!< CAN interrupt enable register, Address offset: 0x14 */ + __IO uint32_t ESR; /*!< CAN error status register, Address offset: 0x18 */ + __IO uint32_t BTR; /*!< CAN bit timing register, Address offset: 0x1C */ + uint32_t RESERVED0[88]; /*!< Reserved, 0x020 - 0x17F */ + CAN_TxMailBox_TypeDef sTxMailBox[3]; /*!< CAN Tx MailBox, Address offset: 0x180 - 0x1AC */ + CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; /*!< CAN FIFO MailBox, Address offset: 0x1B0 - 0x1CC */ + uint32_t RESERVED1[12]; /*!< Reserved, 0x1D0 - 0x1FF */ + __IO uint32_t FMR; /*!< CAN filter master register, Address offset: 0x200 */ + __IO uint32_t FM1R; /*!< CAN filter mode register, Address offset: 0x204 */ + uint32_t RESERVED2; /*!< Reserved, 0x208 */ + __IO uint32_t FS1R; /*!< CAN filter scale register, Address offset: 0x20C */ + uint32_t RESERVED3; /*!< Reserved, 0x210 */ + __IO uint32_t FFA1R; /*!< CAN filter FIFO assignment register, Address offset: 0x214 */ + uint32_t RESERVED4; /*!< Reserved, 0x218 */ + __IO uint32_t FA1R; /*!< CAN filter activation register, Address offset: 0x21C */ + uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */ + CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register, Address offset: 0x240-0x31C */ +} CAN_TypeDef; + +/** + * @brief CRC calculation unit + */ + +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + uint8_t RESERVED0; /*!< Reserved, 0x05 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ +} CRC_TypeDef; + +/** + * @brief Digital to Analog Converter + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ + __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ + __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ + __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ + __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ + __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ + __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ + __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ + __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ + __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ + __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ + __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ + __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ + __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ +} DAC_TypeDef; + +/** + * @brief Debug MCU + */ + +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */ + __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */ +}DBGMCU_TypeDef; + +/** + * @brief DCMI + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */ + __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */ + __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */ + __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */ + __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */ + __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */ + __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */ + __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */ + __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */ + __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */ +} DCMI_TypeDef; + +/** + * @brief DMA Controller + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DMA stream x configuration register */ + __IO uint32_t NDTR; /*!< DMA stream x number of data register */ + __IO uint32_t PAR; /*!< DMA stream x peripheral address register */ + __IO uint32_t M0AR; /*!< DMA stream x memory 0 address register */ + __IO uint32_t M1AR; /*!< DMA stream x memory 1 address register */ + __IO uint32_t FCR; /*!< DMA stream x FIFO control register */ +} DMA_Stream_TypeDef; + +typedef struct +{ + __IO uint32_t LISR; /*!< DMA low interrupt status register, Address offset: 0x00 */ + __IO uint32_t HISR; /*!< DMA high interrupt status register, Address offset: 0x04 */ + __IO uint32_t LIFCR; /*!< DMA low interrupt flag clear register, Address offset: 0x08 */ + __IO uint32_t HIFCR; /*!< DMA high interrupt flag clear register, Address offset: 0x0C */ +} DMA_TypeDef; + +/** + * @brief Ethernet MAC + */ + +typedef struct +{ + __IO uint32_t MACCR; + __IO uint32_t MACFFR; + __IO uint32_t MACHTHR; + __IO uint32_t MACHTLR; + __IO uint32_t MACMIIAR; + __IO uint32_t MACMIIDR; + __IO uint32_t MACFCR; + __IO uint32_t MACVLANTR; /* 8 */ + uint32_t RESERVED0[2]; + __IO uint32_t MACRWUFFR; /* 11 */ + __IO uint32_t MACPMTCSR; + uint32_t RESERVED1[2]; + __IO uint32_t MACSR; /* 15 */ + __IO uint32_t MACIMR; + __IO uint32_t MACA0HR; + __IO uint32_t MACA0LR; + __IO uint32_t MACA1HR; + __IO uint32_t MACA1LR; + __IO uint32_t MACA2HR; + __IO uint32_t MACA2LR; + __IO uint32_t MACA3HR; + __IO uint32_t MACA3LR; /* 24 */ + uint32_t RESERVED2[40]; + __IO uint32_t MMCCR; /* 65 */ + __IO uint32_t MMCRIR; + __IO uint32_t MMCTIR; + __IO uint32_t MMCRIMR; + __IO uint32_t MMCTIMR; /* 69 */ + uint32_t RESERVED3[14]; + __IO uint32_t MMCTGFSCCR; /* 84 */ + __IO uint32_t MMCTGFMSCCR; + uint32_t RESERVED4[5]; + __IO uint32_t MMCTGFCR; + uint32_t RESERVED5[10]; + __IO uint32_t MMCRFCECR; + __IO uint32_t MMCRFAECR; + uint32_t RESERVED6[10]; + __IO uint32_t MMCRGUFCR; + uint32_t RESERVED7[334]; + __IO uint32_t PTPTSCR; + __IO uint32_t PTPSSIR; + __IO uint32_t PTPTSHR; + __IO uint32_t PTPTSLR; + __IO uint32_t PTPTSHUR; + __IO uint32_t PTPTSLUR; + __IO uint32_t PTPTSAR; + __IO uint32_t PTPTTHR; + __IO uint32_t PTPTTLR; + __IO uint32_t RESERVED8; + __IO uint32_t PTPTSSR; + uint32_t RESERVED9[565]; + __IO uint32_t DMABMR; + __IO uint32_t DMATPDR; + __IO uint32_t DMARPDR; + __IO uint32_t DMARDLAR; + __IO uint32_t DMATDLAR; + __IO uint32_t DMASR; + __IO uint32_t DMAOMR; + __IO uint32_t DMAIER; + __IO uint32_t DMAMFBOCR; + __IO uint32_t DMARSWTR; + uint32_t RESERVED10[8]; + __IO uint32_t DMACHTDR; + __IO uint32_t DMACHRDR; + __IO uint32_t DMACHTBAR; + __IO uint32_t DMACHRBAR; +} ETH_TypeDef; + +/** + * @brief External Interrupt/Event Controller + */ + +typedef struct +{ + __IO uint32_t IMR; /*!< EXTI Interrupt mask register, Address offset: 0x00 */ + __IO uint32_t EMR; /*!< EXTI Event mask register, Address offset: 0x04 */ + __IO uint32_t RTSR; /*!< EXTI Rising trigger selection register, Address offset: 0x08 */ + __IO uint32_t FTSR; /*!< EXTI Falling trigger selection register, Address offset: 0x0C */ + __IO uint32_t SWIER; /*!< EXTI Software interrupt event register, Address offset: 0x10 */ + __IO uint32_t PR; /*!< EXTI Pending register, Address offset: 0x14 */ +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ + +typedef struct +{ + __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __IO uint32_t KEYR; /*!< FLASH key register, Address offset: 0x04 */ + __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< FLASH status register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< FLASH control register, Address offset: 0x10 */ + __IO uint32_t OPTCR; /*!< FLASH option control register, Address offset: 0x14 */ +} FLASH_TypeDef; + +/** + * @brief Flexible Static Memory Controller + */ + +typedef struct +{ + __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ +} FSMC_Bank1_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank1E + */ + +typedef struct +{ + __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ +} FSMC_Bank1E_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank2 + */ + +typedef struct +{ + __IO uint32_t PCR2; /*!< NAND Flash control register 2, Address offset: 0x60 */ + __IO uint32_t SR2; /*!< NAND Flash FIFO status and interrupt register 2, Address offset: 0x64 */ + __IO uint32_t PMEM2; /*!< NAND Flash Common memory space timing register 2, Address offset: 0x68 */ + __IO uint32_t PATT2; /*!< NAND Flash Attribute memory space timing register 2, Address offset: 0x6C */ + uint32_t RESERVED0; /*!< Reserved, 0x70 */ + __IO uint32_t ECCR2; /*!< NAND Flash ECC result registers 2, Address offset: 0x74 */ +} FSMC_Bank2_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank3 + */ + +typedef struct +{ + __IO uint32_t PCR3; /*!< NAND Flash control register 3, Address offset: 0x80 */ + __IO uint32_t SR3; /*!< NAND Flash FIFO status and interrupt register 3, Address offset: 0x84 */ + __IO uint32_t PMEM3; /*!< NAND Flash Common memory space timing register 3, Address offset: 0x88 */ + __IO uint32_t PATT3; /*!< NAND Flash Attribute memory space timing register 3, Address offset: 0x8C */ + uint32_t RESERVED0; /*!< Reserved, 0x90 */ + __IO uint32_t ECCR3; /*!< NAND Flash ECC result registers 3, Address offset: 0x94 */ +} FSMC_Bank3_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank4 + */ + +typedef struct +{ + __IO uint32_t PCR4; /*!< PC Card control register 4, Address offset: 0xA0 */ + __IO uint32_t SR4; /*!< PC Card FIFO status and interrupt register 4, Address offset: 0xA4 */ + __IO uint32_t PMEM4; /*!< PC Card Common memory space timing register 4, Address offset: 0xA8 */ + __IO uint32_t PATT4; /*!< PC Card Attribute memory space timing register 4, Address offset: 0xAC */ + __IO uint32_t PIO4; /*!< PC Card I/O space timing register 4, Address offset: 0xB0 */ +} FSMC_Bank4_TypeDef; + +/** + * @brief General Purpose I/O + */ + +typedef struct +{ + __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ + __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ + __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ +} GPIO_TypeDef; + +/** + * @brief System configuration controller + */ + +typedef struct +{ + __IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */ + __IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */ + __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */ + uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */ + __IO uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */ +} SYSCFG_TypeDef; + +/** + * @brief Inter-integrated Circuit Interface + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t DR; /*!< I2C Data register, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ +} I2C_TypeDef; + +/** + * @brief Independent WATCHDOG + */ + +typedef struct +{ + __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ + __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */ + __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ +} IWDG_TypeDef; + +/** + * @brief Power Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< PWR power control register, Address offset: 0x00 */ + __IO uint32_t CSR; /*!< PWR power control/status register, Address offset: 0x04 */ +} PWR_TypeDef; + +/** + * @brief Reset and Clock Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */ + __IO uint32_t PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ + __IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ + __IO uint32_t CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ + __IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ + __IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ + __IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ + uint32_t RESERVED0; /*!< Reserved, 0x1C */ + __IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x28-0x2C */ + __IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ + __IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ + __IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ + uint32_t RESERVED2; /*!< Reserved, 0x3C */ + __IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ + __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ + uint32_t RESERVED3[2]; /*!< Reserved, 0x48-0x4C */ + __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ + __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ + __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ + uint32_t RESERVED4; /*!< Reserved, 0x5C */ + __IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ + uint32_t RESERVED5[2]; /*!< Reserved, 0x68-0x6C */ + __IO uint32_t BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ + __IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ + uint32_t RESERVED6[2]; /*!< Reserved, 0x78-0x7C */ + __IO uint32_t SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */ + __IO uint32_t PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */ +} RCC_TypeDef; + +/** + * @brief Real-Time Clock + */ + +typedef struct +{ + __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ + __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ + __IO uint32_t CALIBR; /*!< RTC calibration register, Address offset: 0x18 */ + __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x28 */ + __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ + __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ + __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ + __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ + __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x3C */ + __IO uint32_t TAFCR; /*!< RTC tamper and alternate function configuration register, Address offset: 0x40 */ + __IO uint32_t ALRMASSR;/*!< RTC alarm A sub second register, Address offset: 0x44 */ + __IO uint32_t ALRMBSSR;/*!< RTC alarm B sub second register, Address offset: 0x48 */ + uint32_t RESERVED7; /*!< Reserved, 0x4C */ + __IO uint32_t BKP0R; /*!< RTC backup register 1, Address offset: 0x50 */ + __IO uint32_t BKP1R; /*!< RTC backup register 1, Address offset: 0x54 */ + __IO uint32_t BKP2R; /*!< RTC backup register 2, Address offset: 0x58 */ + __IO uint32_t BKP3R; /*!< RTC backup register 3, Address offset: 0x5C */ + __IO uint32_t BKP4R; /*!< RTC backup register 4, Address offset: 0x60 */ + __IO uint32_t BKP5R; /*!< RTC backup register 5, Address offset: 0x64 */ + __IO uint32_t BKP6R; /*!< RTC backup register 6, Address offset: 0x68 */ + __IO uint32_t BKP7R; /*!< RTC backup register 7, Address offset: 0x6C */ + __IO uint32_t BKP8R; /*!< RTC backup register 8, Address offset: 0x70 */ + __IO uint32_t BKP9R; /*!< RTC backup register 9, Address offset: 0x74 */ + __IO uint32_t BKP10R; /*!< RTC backup register 10, Address offset: 0x78 */ + __IO uint32_t BKP11R; /*!< RTC backup register 11, Address offset: 0x7C */ + __IO uint32_t BKP12R; /*!< RTC backup register 12, Address offset: 0x80 */ + __IO uint32_t BKP13R; /*!< RTC backup register 13, Address offset: 0x84 */ + __IO uint32_t BKP14R; /*!< RTC backup register 14, Address offset: 0x88 */ + __IO uint32_t BKP15R; /*!< RTC backup register 15, Address offset: 0x8C */ + __IO uint32_t BKP16R; /*!< RTC backup register 16, Address offset: 0x90 */ + __IO uint32_t BKP17R; /*!< RTC backup register 17, Address offset: 0x94 */ + __IO uint32_t BKP18R; /*!< RTC backup register 18, Address offset: 0x98 */ + __IO uint32_t BKP19R; /*!< RTC backup register 19, Address offset: 0x9C */ +} RTC_TypeDef; + +/** + * @brief SD host Interface + */ + +typedef struct +{ + __IO uint32_t POWER; /*!< SDIO power control register, Address offset: 0x00 */ + __IO uint32_t CLKCR; /*!< SDI clock control register, Address offset: 0x04 */ + __IO uint32_t ARG; /*!< SDIO argument register, Address offset: 0x08 */ + __IO uint32_t CMD; /*!< SDIO command register, Address offset: 0x0C */ + __I uint32_t RESPCMD; /*!< SDIO command response register, Address offset: 0x10 */ + __I uint32_t RESP1; /*!< SDIO response 1 register, Address offset: 0x14 */ + __I uint32_t RESP2; /*!< SDIO response 2 register, Address offset: 0x18 */ + __I uint32_t RESP3; /*!< SDIO response 3 register, Address offset: 0x1C */ + __I uint32_t RESP4; /*!< SDIO response 4 register, Address offset: 0x20 */ + __IO uint32_t DTIMER; /*!< SDIO data timer register, Address offset: 0x24 */ + __IO uint32_t DLEN; /*!< SDIO data length register, Address offset: 0x28 */ + __IO uint32_t DCTRL; /*!< SDIO data control register, Address offset: 0x2C */ + __I uint32_t DCOUNT; /*!< SDIO data counter register, Address offset: 0x30 */ + __I uint32_t STA; /*!< SDIO status register, Address offset: 0x34 */ + __IO uint32_t ICR; /*!< SDIO interrupt clear register, Address offset: 0x38 */ + __IO uint32_t MASK; /*!< SDIO mask register, Address offset: 0x3C */ + uint32_t RESERVED0[2]; /*!< Reserved, 0x40-0x44 */ + __I uint32_t FIFOCNT; /*!< SDIO FIFO counter register, Address offset: 0x48 */ + uint32_t RESERVED1[13]; /*!< Reserved, 0x4C-0x7C */ + __IO uint32_t FIFO; /*!< SDIO data FIFO register, Address offset: 0x80 */ +} SDIO_TypeDef; + +/** + * @brief Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< SPI control register 1 (not used in I2S mode), Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< SPI control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t SR; /*!< SPI status register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t DR; /*!< SPI data register, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t CRCPR; /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t RXCRCR; /*!< SPI RX CRC register (not used in I2S mode), Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t TXCRCR; /*!< SPI TX CRC register (not used in I2S mode), Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t I2SCFGR; /*!< SPI_I2S configuration register, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ +} SPI_TypeDef; + +/** + * @brief TIM + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t SR; /*!< TIM status register, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ + __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ + __IO uint16_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ + uint16_t RESERVED9; /*!< Reserved, 0x2A */ + __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ + __IO uint16_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ + uint16_t RESERVED10; /*!< Reserved, 0x32 */ + __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ + __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ + __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ + __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ + __IO uint16_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ + uint16_t RESERVED11; /*!< Reserved, 0x46 */ + __IO uint16_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ + uint16_t RESERVED12; /*!< Reserved, 0x4A */ + __IO uint16_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */ + uint16_t RESERVED13; /*!< Reserved, 0x4E */ + __IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */ + uint16_t RESERVED14; /*!< Reserved, 0x52 */ +} TIM_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ + +typedef struct +{ + __IO uint16_t SR; /*!< USART Status register, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t DR; /*!< USART Data register, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t CR1; /*!< USART Control register 1, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t CR2; /*!< USART Control register 2, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t CR3; /*!< USART Control register 3, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ +} USART_TypeDef; + +/** + * @brief Window WATCHDOG + */ + +typedef struct +{ + __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ + __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ + __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ +} WWDG_TypeDef; + +/** + * @brief Crypto Processor + */ + +typedef struct +{ + __IO uint32_t CR; /*!< CRYP control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< CRYP status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< CRYP data input register, Address offset: 0x08 */ + __IO uint32_t DOUT; /*!< CRYP data output register, Address offset: 0x0C */ + __IO uint32_t DMACR; /*!< CRYP DMA control register, Address offset: 0x10 */ + __IO uint32_t IMSCR; /*!< CRYP interrupt mask set/clear register, Address offset: 0x14 */ + __IO uint32_t RISR; /*!< CRYP raw interrupt status register, Address offset: 0x18 */ + __IO uint32_t MISR; /*!< CRYP masked interrupt status register, Address offset: 0x1C */ + __IO uint32_t K0LR; /*!< CRYP key left register 0, Address offset: 0x20 */ + __IO uint32_t K0RR; /*!< CRYP key right register 0, Address offset: 0x24 */ + __IO uint32_t K1LR; /*!< CRYP key left register 1, Address offset: 0x28 */ + __IO uint32_t K1RR; /*!< CRYP key right register 1, Address offset: 0x2C */ + __IO uint32_t K2LR; /*!< CRYP key left register 2, Address offset: 0x30 */ + __IO uint32_t K2RR; /*!< CRYP key right register 2, Address offset: 0x34 */ + __IO uint32_t K3LR; /*!< CRYP key left register 3, Address offset: 0x38 */ + __IO uint32_t K3RR; /*!< CRYP key right register 3, Address offset: 0x3C */ + __IO uint32_t IV0LR; /*!< CRYP initialization vector left-word register 0, Address offset: 0x40 */ + __IO uint32_t IV0RR; /*!< CRYP initialization vector right-word register 0, Address offset: 0x44 */ + __IO uint32_t IV1LR; /*!< CRYP initialization vector left-word register 1, Address offset: 0x48 */ + __IO uint32_t IV1RR; /*!< CRYP initialization vector right-word register 1, Address offset: 0x4C */ +} CRYP_TypeDef; + +/** + * @brief HASH + */ + +typedef struct +{ + __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */ + __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */ + __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */ + __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */ + __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */ + __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */ + uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */ + __IO uint32_t CSR[51]; /*!< HASH context swap registers, Address offset: 0x0F8-0x1C0 */ +} HASH_TypeDef; + +/** + * @brief HASH + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ +} RNG_TypeDef; + +/** + * @} + */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ +#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH(up to 1 MB) base address in the alias region */ +#define CCMDATARAM_BASE ((uint32_t)0x10000000) /*!< CCM(core coupled memory) data RAM(64 KB) base address in the alias region */ +#define SRAM1_BASE ((uint32_t)0x20000000) /*!< SRAM1(112 KB) base address in the alias region */ +#define SRAM2_BASE ((uint32_t)0x2001C000) /*!< SRAM2(16 KB) base address in the alias region */ +#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */ +#define BKPSRAM_BASE ((uint32_t)0x40024000) /*!< Backup SRAM(4 KB) base address in the alias region */ +#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */ + +#define CCMDATARAM_BB_BASE ((uint32_t)0x12000000) /*!< CCM(core coupled memory) data RAM(64 KB) base address in the bit-band region */ +#define SRAM1_BB_BASE ((uint32_t)0x22000000) /*!< SRAM1(112 KB) base address in the bit-band region */ +#define SRAM2_BB_BASE ((uint32_t)0x2201C000) /*!< SRAM2(16 KB) base address in the bit-band region */ +#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */ +#define BKPSRAM_BB_BASE ((uint32_t)0x42024000) /*!< Backup SRAM(4 KB) base address in the bit-band region */ + +/* Legacy defines */ +#define SRAM_BASE SRAM1_BASE +#define SRAM_BB_BASE SRAM1_BB_BASE + + +/*!< Peripheral memory map */ +#define APB1PERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) +#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000) + +/*!< APB1 peripherals */ +#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) +#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) +#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) +#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) +#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) +#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) +#define TIM12_BASE (APB1PERIPH_BASE + 0x1800) +#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00) +#define TIM14_BASE (APB1PERIPH_BASE + 0x2000) +#define RTC_BASE (APB1PERIPH_BASE + 0x2800) +#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) +#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) +#define I2S2ext_BASE (APB1PERIPH_BASE + 0x3400) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define I2S3ext_BASE (APB1PERIPH_BASE + 0x4000) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800) +#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) +#define UART5_BASE (APB1PERIPH_BASE + 0x5000) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define I2C3_BASE (APB1PERIPH_BASE + 0x5C00) +#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) +#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) +#define PWR_BASE (APB1PERIPH_BASE + 0x7000) +#define DAC_BASE (APB1PERIPH_BASE + 0x7400) + +/*!< APB2 peripherals */ +#define TIM1_BASE (APB2PERIPH_BASE + 0x0000) +#define TIM8_BASE (APB2PERIPH_BASE + 0x0400) +#define USART1_BASE (APB2PERIPH_BASE + 0x1000) +#define USART6_BASE (APB2PERIPH_BASE + 0x1400) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2000) +#define ADC2_BASE (APB2PERIPH_BASE + 0x2100) +#define ADC3_BASE (APB2PERIPH_BASE + 0x2200) +#define ADC_BASE (APB2PERIPH_BASE + 0x2300) +#define SDIO_BASE (APB2PERIPH_BASE + 0x2C00) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define SYSCFG_BASE (APB2PERIPH_BASE + 0x3800) +#define EXTI_BASE (APB2PERIPH_BASE + 0x3C00) +#define TIM9_BASE (APB2PERIPH_BASE + 0x4000) +#define TIM10_BASE (APB2PERIPH_BASE + 0x4400) +#define TIM11_BASE (APB2PERIPH_BASE + 0x4800) + +/*!< AHB1 peripherals */ +#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) +#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400) +#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) +#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00) +#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000) +#define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400) +#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800) +#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00) +#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000) +#define CRC_BASE (AHB1PERIPH_BASE + 0x3000) +#define RCC_BASE (AHB1PERIPH_BASE + 0x3800) +#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00) +#define DMA1_BASE (AHB1PERIPH_BASE + 0x6000) +#define DMA1_Stream0_BASE (DMA1_BASE + 0x010) +#define DMA1_Stream1_BASE (DMA1_BASE + 0x028) +#define DMA1_Stream2_BASE (DMA1_BASE + 0x040) +#define DMA1_Stream3_BASE (DMA1_BASE + 0x058) +#define DMA1_Stream4_BASE (DMA1_BASE + 0x070) +#define DMA1_Stream5_BASE (DMA1_BASE + 0x088) +#define DMA1_Stream6_BASE (DMA1_BASE + 0x0A0) +#define DMA1_Stream7_BASE (DMA1_BASE + 0x0B8) +#define DMA2_BASE (AHB1PERIPH_BASE + 0x6400) +#define DMA2_Stream0_BASE (DMA2_BASE + 0x010) +#define DMA2_Stream1_BASE (DMA2_BASE + 0x028) +#define DMA2_Stream2_BASE (DMA2_BASE + 0x040) +#define DMA2_Stream3_BASE (DMA2_BASE + 0x058) +#define DMA2_Stream4_BASE (DMA2_BASE + 0x070) +#define DMA2_Stream5_BASE (DMA2_BASE + 0x088) +#define DMA2_Stream6_BASE (DMA2_BASE + 0x0A0) +#define DMA2_Stream7_BASE (DMA2_BASE + 0x0B8) +#define ETH_BASE (AHB1PERIPH_BASE + 0x8000) +#define ETH_MAC_BASE (ETH_BASE) +#define ETH_MMC_BASE (ETH_BASE + 0x0100) +#define ETH_PTP_BASE (ETH_BASE + 0x0700) +#define ETH_DMA_BASE (ETH_BASE + 0x1000) + +/*!< AHB2 peripherals */ +#define DCMI_BASE (AHB2PERIPH_BASE + 0x50000) +#define CRYP_BASE (AHB2PERIPH_BASE + 0x60000) +#define HASH_BASE (AHB2PERIPH_BASE + 0x60400) +#define RNG_BASE (AHB2PERIPH_BASE + 0x60800) + +/*!< FSMC Bankx registers base address */ +#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) +#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) +#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) +#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) +#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) + +/* Debug MCU registers base address */ +#define DBGMCU_BASE ((uint32_t )0xE0042000) + +/** + * @} + */ + +/** @addtogroup Peripheral_declaration + * @{ + */ +#define TIM2 ((TIM_TypeDef *) TIM2_BASE) +#define TIM3 ((TIM_TypeDef *) TIM3_BASE) +#define TIM4 ((TIM_TypeDef *) TIM4_BASE) +#define TIM5 ((TIM_TypeDef *) TIM5_BASE) +#define TIM6 ((TIM_TypeDef *) TIM6_BASE) +#define TIM7 ((TIM_TypeDef *) TIM7_BASE) +#define TIM12 ((TIM_TypeDef *) TIM12_BASE) +#define TIM13 ((TIM_TypeDef *) TIM13_BASE) +#define TIM14 ((TIM_TypeDef *) TIM14_BASE) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define WWDG ((WWDG_TypeDef *) WWDG_BASE) +#define IWDG ((IWDG_TypeDef *) IWDG_BASE) +#define I2S2ext ((SPI_TypeDef *) I2S2ext_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define I2S3ext ((SPI_TypeDef *) I2S3ext_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define USART3 ((USART_TypeDef *) USART3_BASE) +#define UART4 ((USART_TypeDef *) UART4_BASE) +#define UART5 ((USART_TypeDef *) UART5_BASE) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define I2C3 ((I2C_TypeDef *) I2C3_BASE) +#define CAN1 ((CAN_TypeDef *) CAN1_BASE) +#define CAN2 ((CAN_TypeDef *) CAN2_BASE) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define DAC ((DAC_TypeDef *) DAC_BASE) +#define TIM1 ((TIM_TypeDef *) TIM1_BASE) +#define TIM8 ((TIM_TypeDef *) TIM8_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define USART6 ((USART_TypeDef *) USART6_BASE) +#define ADC ((ADC_Common_TypeDef *) ADC_BASE) +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define ADC2 ((ADC_TypeDef *) ADC2_BASE) +#define ADC3 ((ADC_TypeDef *) ADC3_BASE) +#define SDIO ((SDIO_TypeDef *) SDIO_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) +#define EXTI ((EXTI_TypeDef *) EXTI_BASE) +#define TIM9 ((TIM_TypeDef *) TIM9_BASE) +#define TIM10 ((TIM_TypeDef *) TIM10_BASE) +#define TIM11 ((TIM_TypeDef *) TIM11_BASE) +#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) +#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) +#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) +#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) +#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) +#define GPIOI ((GPIO_TypeDef *) GPIOI_BASE) +#define CRC ((CRC_TypeDef *) CRC_BASE) +#define RCC ((RCC_TypeDef *) RCC_BASE) +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) +#define DMA1 ((DMA_TypeDef *) DMA1_BASE) +#define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE) +#define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE) +#define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE) +#define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE) +#define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE) +#define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE) +#define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE) +#define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE) +#define DMA2 ((DMA_TypeDef *) DMA2_BASE) +#define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE) +#define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE) +#define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE) +#define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE) +#define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE) +#define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE) +#define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE) +#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE) +#define ETH ((ETH_TypeDef *) ETH_BASE) +#define DCMI ((DCMI_TypeDef *) DCMI_BASE) +#define CRYP ((CRYP_TypeDef *) CRYP_BASE) +#define HASH ((HASH_TypeDef *) HASH_BASE) +#define RNG ((RNG_TypeDef *) RNG_BASE) +#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) +#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) +#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE) +#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE) +#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE) +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + +/** + * @} + */ + +/** @addtogroup Exported_constants + * @{ + */ + + /** @addtogroup Peripheral_Registers_Bits_Definition + * @{ + */ + +/******************************************************************************/ +/* Peripheral Registers_Bits_Definition */ +/******************************************************************************/ + +/******************************************************************************/ +/* */ +/* Analog to Digital Converter */ +/* */ +/******************************************************************************/ +/******************** Bit definition for ADC_SR register ********************/ +#define ADC_SR_AWD ((uint8_t)0x01) /*!
© COPYRIGHT 2011 STMicroelectronics
+ ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx_system + * @{ + */ + +/** + * @brief Define to prevent recursive inclusion + */ +#ifndef __SYSTEM_STM32F4XX_H +#define __SYSTEM_STM32F4XX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup STM32F4xx_System_Includes + * @{ + */ + +/** + * @} + */ + + +/** @addtogroup STM32F4xx_System_Exported_types + * @{ + */ + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Exported_Constants + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Exported_Functions + * @{ + */ + +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__SYSTEM_STM32F4XX_H */ + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/User/AT45DB/at45db.c b/User/AT45DB/at45db.c new file mode 100644 index 0000000..7c73dbc --- /dev/null +++ b/User/AT45DB/at45db.c @@ -0,0 +1,347 @@ +/*C***************************************************************************** +* NAME: at45db.c +*------------------------------------------------------------------------------- +* RELEASE: +* REVISION: 1.0 +*------------------------------------------------------------------------------- +* PURPOSE: +* at45Db +*******************************************************************************/ +/*_____ I N C L U D E S ______________________________________________________*/ +#include "config.h" //ȫ +u8 FlashType = 0; +F_uniGlobal_Typedef F_uniGlobal; +#define Data_INIT +const u8 initATDB45_Flag = 0x38; +const PREXDATA_Type initPREXDATA = {0,0,0,0,0,0,0,0,0}; +const AT45DBDataIndex AT45DBTab[20] = +{ ///FRAM1(ݲԲƵ) +/// pInitData; upData pData firstAdr; len; Tpye; //(ע,Уݰβ) + {(u8*)&initATDB45_Flag, (u8*)(&buf_ATDB45_Flag), (u8*)(&TXHData.ATDB45_Flag), ATDB45_Flag_FADR, ATDB45_Flag_LEN, ATDB45_Flag_Group, CA_ATDB45_Flag}, + {(u8*)&initATDB45_Flag, (u8*)(&buf_Frame), (u8*)(&TXHData.Frame), Frame_FADR, Frame_LEN, Frame_Group, CA_Frame}, + {(u8*)&initPREXDATA, (u8*)(&buf_PREXDATA), (u8*)(&TXHData.PREXDATA), PREXDATA_FADR, PREXDATA_LEN, PREXDATA_Group, CA_PREXDATA}, + {(u8*)&initATDB45_Flag, (u8*)(&buf_DeviceFrame), (u8*)(&TXHData.Frame), DeviceFrame_FADR, DeviceFrame_LEN, DeviceFrame_Group, CA_DeviceFrame}, +}; + +////============================================================================== + +/** + * @brief ָȵУͼ + * + * @param pData ָָ + * @param len ij + * @return u8 Уͽ + */ +u8 AT45DBDataCheck(volatile u8* pData, u16 len) +{ + u8 result; // Уͱ + result = *pData; // ʼΪһֽڵֵ + while(len--) + { + result += *pData++; // ۼÿֽڵֵ + } + return result; // Уͽ +} + +/**************************************************** +AT45DB_SendByte + Flash洢õSPIͺ + dt Ҫ͵ +ֵ +****************************************************/ +u8 AT45DB_SendByte(u8 dt) +{ + while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); + SPI_I2S_SendData(SPI1, dt); + while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); + return SPI_I2S_ReceiveData(SPI1); +} + +//F***************************************************************************** +//* NAME: ReadDFStatus +//*----------------------------------------------------------------------------- +//* PURPOSE: +//* ȡ45db״̬ +//*----------------------------------------------------------------------------- +//* PARAMS: +//* return: ֵ0,˵ +//*----------------------------------------------------------------------------- +//* NOTE: +//****************************************************************************** +u8 ReadDFStatus (void) +{ + u8 result; + CLI(); + AT45DB_CS_EN; + AT45DB_SendByte(0xd7); + result = AT45DB_SendByte(0xff);//ҪΣȻҪ10msʱʱ֪Ϊʲô + //delay_ms(10); + AT45DB_CS_DIS; + SEI(); + return result; +} +//F***************************************************************************** +//* NAME: ReadDriverID +//*----------------------------------------------------------------------------- +//* PURPOSE: +//* ȡ45dbID жϴ洢 +//*----------------------------------------------------------------------------- +//* PARAMS: +//* return: Drive ID(Byte 1)Family Code Density Code +// 0 0 1((AT45D) 0 0 1 0 0 (4-Mbit) +// 0 0 1((AT45D) 0 0 1 1 1 (32-Mbit) +//*----------------------------------------------------------------------------- +//* NOTE: +//****************************************************************************** +u16 ii = 0; +u8 resultF = 0; +u8 ReadDriverID (void) +{ + CLI(); + for(ii = 0;ii < 200;ii ++) + { + if(ReadDFStatus() & 0x80) + break; + delay_ms(1); + } + if(ii < 200) + { + AT45DB_CS_EN; + AT45DB_SendByte(0x9F); + AT45DB_SendByte(0xFF); + resultF = AT45DB_SendByte(0xFF); + AT45DB_CS_DIS; + SEI(); + return resultF; + } + SEI(); + return 0; +} +u8 AT45DB_SetPageByte (void) +{ + CLI(); + for(ii = 0;ii < 200;ii ++) + { + if(ReadDFStatus() & 0x80) + break; + delay_ms(1); + } + if(ii < 200) + { + AT45DB_CS_EN; + AT45DB_SendByte(0x3D); + AT45DB_SendByte(0x2A); + AT45DB_SendByte(0x80); + AT45DB_SendByte(0xA7);//A6:512;A7:528 + AT45DB_CS_DIS; + SEI(); + return 1; + } + SEI(); + return 0; +} +u8 AT45DB_WriteBuff(u8 *Buff,u16 Len) +{ + u16 i = 0; + CLI(); + for(ii = 0;ii < 200;ii ++) + { + if(ReadDFStatus() & 0x80) + break; + delay_ms(1); + } + if(ii < 200) + { + AT45DB_CS_EN; + AT45DB_SendByte(0x84); + AT45DB_SendByte(0x00); + AT45DB_SendByte(0x00); + AT45DB_SendByte(0x00); + for(i = 0;i < Len;i ++) + AT45DB_SendByte(*(Buff + i)); + AT45DB_CS_DIS; + SEI(); + return 1; + } + SEI(); + return 0; +} + +u8 AT45DB_WritePage(u8 *Buff,u16 Page,u16 Len)//len = 10,79us +{ + CLI(); + if(AT45DB_WriteBuff(Buff,Len) == 0) + return 0; + for(ii = 0;ii < 200;ii ++) + { + if(ReadDFStatus() & 0x80) + break; + delay_ms(1); + } + if(ii < 200) + { + AT45DB_CS_EN; + AT45DB_SendByte(0x83); + AT45DB_SendByte((u8)(Page >> 6)); + AT45DB_SendByte((u8)(Page << 2)); + AT45DB_SendByte(0x00); + AT45DB_CS_DIS; + + SEI(); + return 1; + } + SEI(); + return 0; +} + +u8 AT45DB_ReadPage(u8 *Buff,u16 Page,u16 Len)//len = 10,75us +{ + u16 i = 0; + CLI(); + for(ii = 0;ii < 200;ii ++) + { + if(ReadDFStatus() & 0x80) + break; + delay_ms(1); + } + if(ii < 200) + { + AT45DB_CS_EN; + AT45DB_SendByte(0xE8); + AT45DB_SendByte((u8)(Page >> 6)); + AT45DB_SendByte((u8)(Page << 2)); + AT45DB_SendByte(0x00); + for(i = 0;i < 4;i ++) + AT45DB_SendByte(0x00); + for(i = 0;i < Len;i ++) + *(Buff + i) = AT45DB_SendByte(0xff); + AT45DB_CS_DIS; + SEI(); + return 1; + } + SEI(); + return 0; +} +void AT45DB_Data_Init(void) +{ + volatile u16 i = 0,j = 0,Item = 0; + u8 Temp_Buff[660]; + u8 Temp = 0; + for(Item = 0;Item< FramItemEnd;Item ++) + { + for(i = 0;i < AT45DBTab[Item].Group;i ++) + { + for(j = 0;j < AT45DBTab[Item].len - checkLen_1;j ++) + Temp_Buff[j] = *(AT45DBTab[Item].upData + j) = *(AT45DBTab[Item].pInitData+j); + Temp_Buff[AT45DBTab[Item].len - checkLen_1] = AT45DBDataCheck(Temp_Buff,AT45DBTab[Item].len - checkLen_1); + AT45DB_WritePage(Temp_Buff,AT45DBTab[Item].firstAdr + i,AT45DBTab[Item].len); + } + } +// __set_FAULTMASK(1); +// NVIC_SystemReset(); + } +u8 AT45DBItemWrite(AT45DBItem Type, u16 Group) +{ + u16 i = 0,j = 0,k = 0; + u8 Temp_Buff[660]; + u8 Temp = 0; + if(Group >= AT45DBTab[Type].Group) + return 0; + for(i = 0;i < AT45DBTab[Type].len - checkLen_1;i ++) + { + *(AT45DBTab[Type].upData + i) = *(AT45DBTab[Type].pData + i); + Temp_Buff[i] = *(AT45DBTab[Type].upData + i); + } + Temp_Buff[AT45DBTab[Type].len - checkLen_1] = AT45DBDataCheck(Temp_Buff,AT45DBTab[Type].len - checkLen_1); + for(j = 0;j < 6;j ++) + { + AT45DB_WritePage(Temp_Buff,AT45DBTab[Type].firstAdr + Group,AT45DBTab[Type].len); + + if(AT45DBItemRead(Type,Group) == 1) + { + return 1; + } + delay_ms(100); + } + // TXHData.ErrState.Flag.e_errFlashParameter = 1; + return 0; +} +u8 CRCTemp = 0; +u8 AT45DBItemRead(AT45DBItem Type, u16 Group) +{ + volatile u16 i = 0,j = 0; + u8 Temp_Buff[660]; + u8 Temp_Buff1[660]; + + u8 CRCTemp1 = 0; + + if(Group >= AT45DBTab[Type].Group) + return 0; + for(j = 0;j < 6;j ++) + { + AT45DB_ReadPage(FuniGlobal.Global,AT45DBTab[Type].firstAdr + Group,AT45DBTab[Type].len); + for(i = 0;i < AT45DBTab[Type].len;i ++) + *(Temp_Buff+i) = *(AT45DBTab[Type].upData+i); + CRCTemp = AT45DBDataCheck(Temp_Buff,AT45DBTab[Type].len - checkLen_1); + if(CRCTemp == Temp_Buff[AT45DBTab[Type].len - checkLen_1]) + { + for(i = 0;i < AT45DBTab[Type].len - checkLen_1;i ++) + *(AT45DBTab[Type].pData+i) = *(AT45DBTab[Type].upData+i); + return 1; + } + delay_ms(100); + } + // pGun.ErrState.Flag.e_errFlashParameter = 1; + return 0; +} +u8 ExChangeByte(u8 data) +{ + u8 Temp = 0; + Temp = data; + data = (Temp >> 4) | (Temp << 4); + return data; +} +u8 NotByte(u8 data) +{ + if(data == 0 || data == 0xff) + return data; + else + return ~data; +} + +void AT45DB_Init(void) +{ + volatile u16 Frame = 0; + u8* pBuff; + u8 Temp_Buff[660]; + FlashType = ReadDriverID(); + AT45DB_SetPageByte(); + switch(FlashType) + { + case 0x24: TXHData.ATDB45Type = At45DB041;break; + case 0x27: TXHData.ATDB45Type = At45DB321;break; + case 0x28: TXHData.ATDB45Type = At45DB641;break; + } +// if(SWF8 == SWF_ON) +// { +// if(TXHData.ATDB45Type >= At45DB321) +// { +// for(Frame = 0;Frame < 1024;Frame ++) +// { +// ReadFlashNx512Btye(&TXHData.Frame[0],FLASH_APP_ADDR + Frame *512); +// switch(Frame%8) +// { +// case 0:TXHData.Frame[2] = ExChangeByte(TXHData.Frame[2]); +// TXHData.Frame[54] = NotByte(TXHData.Frame[54]); +// TXHData.Frame[288] = ExChangeByte(TXHData.Frame[288]);GPIO_SetBits(GPIOE,GPIO_Pin_2);break; +// case 1:TXHData.Frame[469] = NotByte(TXHData.Frame[469]);break; +// case 2:TXHData.Frame[104] = ExChangeByte(TXHData.Frame[104]);break; +// case 3:break; +// case 4:TXHData.Frame[0] = NotByte(TXHData.Frame[0]);break; +// case 5:TXHData.Frame[253] = ExChangeByte(TXHData.Frame[253]);GPIO_ResetBits(GPIOE,GPIO_Pin_2);break; +// } +// AT45DBItemWrite(CA_Frame,Frame + (TXHData.ROM_UpData.ROM_UpData_State.RomAddrNow * 1024)); +// } +// } +// } +} diff --git a/User/AT45DB/at45db.h b/User/AT45DB/at45db.h new file mode 100644 index 0000000..8d6bc60 --- /dev/null +++ b/User/AT45DB/at45db.h @@ -0,0 +1,95 @@ +#ifndef _AT45DB_H_ +#define _AT45DB_H_ +/*H***************************************************************************** +* NAME: at45db.h +*******************************************************************************/ + +//***************************************************************************** +/*_____ M A C R O S __________________________________________________________*/ + +//˿ڶ +#define AT45DB_CS_EN GPIO_ResetBits(GPIOA, GPIO_Pin_4);GPIO_SetBits(GPIOA, GPIO_Pin_3); +#define AT45DB_CS_DIS GPIO_SetBits(GPIOA, GPIO_Pin_4); + +//****************************************************************************** +// +#define FLASH_APP_ADDR 0x08008000 //һӦóʼַ(FLASH) + +#define RomUpDataAddr_Old 0 +#define RomUpDataAddr_New 1024 + + +#define FuniGlobal F_uniGlobal.u + +//****************************************************************************** +// AT45DB_DATA_MAP +#define checkLen_1 1 ///У,1byte + +//洢ñ +///ȫֻеֵ +#define buf_ATDB45_Flag FuniGlobal.ATDB45_Flag +///ṹ嶨 +#define ATDB45_Flag_FADR (0) +#define ATDB45_Flag_LEN (sizeof(buf_ATDB45_Flag) + checkLen_1) +#define ATDB45_Flag_Group 1 // + +///ȫֻеֵ +#define buf_Frame FuniGlobal.Frame +///ṹ嶨 +#define Frame_FADR (ATDB45_Flag_FADR + ATDB45_Flag_Group) +#define Frame_LEN sizeof(buf_Frame) + checkLen_1 +#define Frame_Group 2048 // + +///ȫֻеֵ +#define buf_PREXDATA FuniGlobal.PREXDATA +///ṹ嶨 +#define PREXDATA_FADR (Frame_FADR + Frame_Group) +#define PREXDATA_LEN sizeof(buf_PREXDATA) + checkLen_1 +#define PREXDATA_Group 2000 // + +///ȫֻеֵ +#define buf_DeviceFrame FuniGlobal.Frame +///ṹ嶨 +#define DeviceFrame_FADR (PREXDATA_FADR + PREXDATA_Group) +#define DeviceFrame_LEN sizeof(buf_DeviceFrame) + checkLen_1 +#define DeviceFrame_Group 800*5 // + +typedef struct +{ + union + { + u8 Global[530]; //ȫ + u8 ATDB45_Flag; + u8 Frame[512]; + PREXDATA_Type PREXDATA[5]; + }u; + u8 CheckAdd; +}F_uniGlobal_Typedef; //洢д湲 + +typedef enum +{ + CA_ATDB45_Flag, + CA_Frame, + CA_PREXDATA, + CA_DeviceFrame, + + AT45DBItemEnd, +}AT45DBItem; + +//******************************************************************************** +typedef struct +{ + u8* pInitData;//ʼָ + u8* upData; //ݻָ + u8* pData; //pGunָ + u32 firstAdr; //һַ + u16 len; // + u16 Group; + u8 Tpye; // +}AT45DBDataIndex; + +u8 AT45DBItemWrite(AT45DBItem Type, u16 Group); +u8 AT45DBItemRead(AT45DBItem Type, u16 Group); +void AT45DB_Data_Init(void); +void AT45DB_Init(void); +#endif diff --git a/User/Analog/Analog.c b/User/Analog/Analog.c new file mode 100644 index 0000000..98e507d --- /dev/null +++ b/User/Analog/Analog.c @@ -0,0 +1,275 @@ +/*C***************************************************************************** +* NAME: .c +*------------------------------------------------------------------------------- +* RELEASE: +* REVISION: 1.0 +*------------------------------------------------------------------------------- +* PURPOSE: +* +*******************************************************************************/ +/*_____ I N C L U D E S ______________________________________________________*/ + +#include "config.h" //ȫ + +/*_____ M A C R O S __________________________________________________________*/ + + +/*_____ D E F I N I T I O N __________________________________________________*/ + + +//ADοѹ2.5V,ѹ4-20ӦѹΧ0.48-2.4v +/*_____ D E C L A R A T I O N ________________________________________________*/ + + + +u16 PressureAdcBuf[20];//ѹADC棬ÿǹC_PressureAdcBuf + +u16 PressureADCValue[2];//ѹֵ +u32 pressureCalibrate = 3932; //10ADӦ2.4V 40MP 2979 +u32 pressureBass = (3932/5); //10Ӧ0.48V 0MP + +u8 PrssureTask_Flag = 0;//ѹ񿪹 + +#define C_timerPressure 5 //ѹ쳣ʱֵ + +/**************************************************** +Pressure_IO_Configuration + ѹIO + +ֵ +****************************************************/ +void Pressure_IO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; + GPIO_Init(GPIOC, &GPIO_InitStructure); +} +/**************************************************** +Pressure_IO_Configuration + ѹADCDMA + +ֵ +****************************************************/ +void Pressure_DMA_Configuration(void) +{ + DMA_InitTypeDef DMA_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); + + DMA_DeInit(DMA2_Stream0); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = 20; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_2; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)PressureAdcBuf; + + + DMA_Init(DMA2_Stream0, &DMA_InitStructure); + DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); + DMA_ClearFlag(DMA2_Stream0, DMA_IT_TCIF0); + DMA_Cmd(DMA2_Stream0, ENABLE); +} +/**************************************************** +Pressure_IO_Configuration + ѹADC + +ֵ +****************************************************/ +void Pressure_ADC_Configuration(void) +{ + ADC_CommonInitTypeDef ADC_CommonInitStructure; + ADC_InitTypeDef ADC_InitStructure; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //ʹ ADC1 ʱ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC1 λ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //λ + //ڳʼͨ + ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//ģʽ + ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//׶֮ӳ 5 ʱ + ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA ʧ + ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//ԤƵ 4 Ƶ + //ADCCLK=PCLK2/4=84/4=21Mhz,ADC ʱòҪ 36Mhz + ADC_CommonInit(&ADC_CommonInitStructure);//ʼ + //۳ʼ ADC1 ز + ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12 λģʽ + ADC_InitStructure.ADC_ScanConvMode = ENABLE;//ɨģʽ + ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//ת + ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//ֹ⣬ʹ + ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//Ҷ + ADC_InitStructure.ADC_NbrOfConversion = 6;//6 תڹ + ADC_Init(ADC3, &ADC_InitStructure);//ADC ʼ + ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_480Cycles); + ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_480Cycles); + ADC_DMACmd(ADC1, ENABLE);//ADC1DMA + //ܿ ADC ת + ADC_Cmd(ADC1, ENABLE);// AD ת + ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE); + + ADC_SoftwareStartConv(ADC1); //ʹָ ADC1 ת +} +/**************************************************** +Pressure_NVIC_Configuration + DMAж + +ֵ +****************************************************/ +void Pressure_NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; //жýṹ + + //ADC1_DMA + + NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn; //ADC3_DMA + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + +} +/**************************************************** +Pressure_IO_Configuration + ѹʼ + +ֵ +****************************************************/ +void Pressure_Init(void) +{ + u8 Number = 0; + Pressure_IO_Configuration(); + Pressure_ADC_Configuration(); + Pressure_DMA_Configuration(); + Pressure_NVIC_Configuration(); + /**********ѹʱʼ**********/ + TXHData.AnalogTimer.Cycle = 1; + TXHData.AnalogTimer.Flag = 0; + TXHData.AnalogTimer.ON_OFF = 1; + TXHData.AnalogTimer.Init = 0; + TXHData.AnalogTimer.TimerCount = 0; + TXHData.AnalogTimer.TimerCountMax = 500;//2002S +} +/**************************************************** +Pressure_IO_Configuration + ѹDMAж + +ֵ +****************************************************/ + +void Pressure_ADCDMA_IRQHandler(void) +{ + PrssureTask_Flag = 1; //ѹ + DMA_ClearFlag(DMA2_Stream0, DMA_IT_TCIF0); +} +/**************************************************** +Pressure_IO_Configuration + ѹ + +ֵ +****************************************************/ +void PrssureTask(void) +{ + volatile u8 Number = 0; + volatile u8 i; + u16 *pBuf = PressureAdcBuf; + volatile u32 sum[2]= {0,0},Temp[2]={0,0}; + if(PrssureTask_Flag) + { + PrssureTask_Flag = 0; + for(Number = 0;Number < 2;Number ++) + { + sum[Number] = 0; + for(i = 0; i < 20; i += 2 ) + sum[Number] += *(pBuf+i+Number); // + PressureADCValue[Number] =(sum[Number] ) / 160;//ƽֵ +// if((PressureADCValue[Number] > (pressureBass-470)) && (PressureADCValue[Number] < pressureCalibrate))//ѹ0С2.5ѹ +// { +// switch(Number) +// { +// case 0: +// { +// JQJData.ErrState.Flag.e_errPressure_InCut = 0;//ѹ߱־λ +// if(PressureADCValue[Number] > pressureBass) +// { +// JQJData.AnalogValue.Pressure_In = ((PressureADCValue[Number]- pressureBass) * JQJData.Pressure_Range.Pressure_In_Range * 10)/(pressureCalibrate - pressureBass); // +// if(JQJData.AnalogValue.Pressure_In > (JQJData.Pressure_Limit.Pressure_In_Limit * 10)) +// { +// JQJData.ErrState.Flag.e_errPressure_InPass = 1; +// if(JQJData.FuelState.Flag.StartFlag == 1) +// JQJData.ValveClose_Flag = 1; +// } +// else +// JQJData.ErrState.Flag.e_errPressure_InPass = 0; +// } +// else +// { +// JQJData.AnalogValue.Pressure_In = 0; +// } +// if(JQJData.AnalogValue.Pressure_In > JQJData.Pressure_Limit.Pressure_Out_Stop) +// { +// if(V_Moto_State == 1) +// JQJData.ValveClose_Flag = 1; +// } +// } +// break; +// case 1: +// { +// JQJData.ErrState.Flag.e_errPressure_OutCut = 0;//ѹ߱־λ +// if(PressureADCValue[Number] > pressureBass) +// { +// JQJData.AnalogValue.Pressure_Out = ((PressureADCValue[Number]- pressureBass) * JQJData.Pressure_Range.Pressure_Out_Range * 10)/(pressureCalibrate - pressureBass); // +// if(JQJData.AnalogValue.Pressure_Out > JQJData.Pressure_Limit.Pressure_Out_Limit) +// { +// JQJData.ErrState.Flag.e_errPressure_OutPass = 1; +// if(JQJData.FuelState.Flag.StartFlag == 1) +// JQJData.ValveClose_Flag = 1; +// } +// else +// { +// JQJData.ErrState.Flag.e_errPressure_OutPass = 0; +// } +// if(JQJData.AnalogValue.Pressure_Out > JQJData.Pressure_Limit.Pressure_Out_Stop) +// { +// if(V_Moto_State == 1) +// JQJData.ValveClose_Flag = 1; +// } +// } +// else +// { +// JQJData.AnalogValue.Pressure_Out = 0; +// } +// } +// break; +// } +// } +// else///ѹⲻ쳣ʱ +// { +// switch(Number) +// { +// case 0: +// { +// } +// break; +// case 1: +// { +// } +// break; +// +// } +// } + } + } +} + diff --git a/User/Analog/Analog.h b/User/Analog/Analog.h new file mode 100644 index 0000000..0c91901 --- /dev/null +++ b/User/Analog/Analog.h @@ -0,0 +1,26 @@ +#ifndef __Analog_H_ +#define __Analog_H_ +/*H****************************************************************************** +* NAME: pressure.h +*********************************************************************************/ + +//3.3V,LMV358 ,ԷΧ0.2~2.6v,4~40ms ѡ120ŷ +//****************************************************************************** +//*-------------- ----------------------------------------------------- +//****************************************************************************** +extern u16 PressureAdcBuf[20]; +extern u16 PressureADCValue[2]; +extern u8 PrssureTask_Flag; + +#define Prssure_DMAAddrSet(x) (DMA2_Stream0->M0AR = x) //÷ͻַ +#define Prssure_DMALenSet(x) (DMA2_Stream0->NDTR = x) //DMAͳ +#define Prssure_DMAStart() DMA_Cmd(DMA2_Stream0,ENABLE) //DMA +#define Prssure_DMAStop() DMA_Cmd(DMA2_Stream0,DISABLE) //رDMA +//****************************************************************************** +//*-------------- ----------------------------------------------------- +//****************************************************************************** +extern void Pressure_Init(void); +extern void Pressure_ADCDMA_IRQHandler(void); +extern void PrssureTask(void); + +#endif //#ifndef diff --git a/User/CH376_Driver/CH376INC.h b/User/CH376_Driver/CH376INC.h new file mode 100644 index 0000000..b306f9f --- /dev/null +++ b/User/CH376_Driver/CH376INC.h @@ -0,0 +1,916 @@ +/****************************** (C) COPYRIGHT 2011 YQDZ ************************** +* : CH376INC.H +* : ȫ +* FAEֳӦùʦ QQ:1027413631 +* 7*24Сʱֵ֧绰:15366066738 +* http://shop57138657.taobao.com/ +* : V1.0 +* : 2011/08/29 +* : CH376оƬض. +*********************************************************************************/ +#ifndef __CH376INC_H__ +#define __CH376INC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ********************************************************************************************************************* */ +/* ͺͳ */ + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif +#ifndef NULL +#define NULL 0 +#endif + +#ifndef UINT8 +typedef unsigned char UINT8; +#endif +#ifndef UINT16 +typedef unsigned short UINT16; +#endif +#ifndef UINT32 +typedef unsigned long UINT32; +#endif +#ifndef PUINT8 +typedef unsigned char *PUINT8; +#endif +#ifndef PUINT16 +typedef unsigned short *PUINT16; +#endif +#ifndef PUINT32 +typedef unsigned long *PUINT32; +#endif +#ifndef UINT8V +typedef unsigned char volatile UINT8V; +#endif +#ifndef PUINT8V +typedef unsigned char volatile *PUINT8V; +#endif + +/* ********************************************************************************************************************* */ +/* Ӳ */ + +#define CH376_DAT_BLOCK_LEN 0x40 /* USBݰ, ݿ󳤶, Ĭϻij */ + +/* ********************************************************************************************************************* */ +/* */ +/* CH375оƬ, ݻݵĿֲܾͬ) */ +/* һ˳: + һ(ڴڷʽ,֮ǰҪͬ), + ɸ(0), + ж֪ͨ ɸ(0), ѡһ, ж֪ͨһû, һж + CMD01_WR_REQ_DATA, ˳: һ, һ, ɸ + : CMDxy_NAME + еxy, x˵ݸ(ֽ), y˵ݸ(ֽ), yH˵ж֪ͨ, + Щܹʵ0ֽڵݿд, ݿ鱾ֽδxy֮ */ +/* ļĬϻͬʱṩCH375оƬݵʽȥxy֮), Ҫ, ôԶ_NO_CH375_COMPATIBLE_ֹ */ + +/* ********************************************************************************************************************* */ +/* Ҫ(ֲһ), */ + +#define CMD01_GET_IC_VER 0x01 /* ȡоƬ̼汾 */ +/* : 汾( λ7Ϊ0, λ6Ϊ1, λ5~λ0Ϊ汾 ) */ +/* CH376ذ汾ŵֵΪ041H汾Ϊ01H */ + +#define CMD21_SET_BAUDRATE 0x02 /* ڷʽ: ôͨѶ(ϵ߸λĬϲΪ9600bps,D4/D5/D6ѡ) */ +/* : ʷƵϵ, ʷƵ */ +/* : ״̬( CMD_RET_SUCCESSCMD_RET_ABORT, ֵ˵δ ) */ + +#define CMD00_ENTER_SLEEP 0x03 /* ˯״̬ */ + +#define CMD00_RESET_ALL 0x05 /* ִӲλ */ + +#define CMD11_CHECK_EXIST 0x06 /* ͨѶӿں͹״̬ */ +/* : */ +/* : ݵİλȡ */ + +#define CMD20_CHK_SUSPEND 0x0B /* 豸ʽ: üUSB߹״̬ķʽ */ +/* : 10H, 鷽ʽ */ +/* 00H=USB, 04H=50mSΪUSB, 05H=10mSΪUSB */ + +#define CMD20_SET_SDO_INT 0x0B /* SPIӿڷʽ: SPISDOŵжϷʽ */ +/* : 16H, жϷʽ */ +/* 10H=ֹSDOж,SCSƬѡЧʱֹ̬, 90H=SDOSCSƬѡЧʱж */ + +#define CMD14_GET_FILE_SIZE 0x0C /* ļģʽ: ȡǰļ */ +/* : 68H */ +/* : ǰļ(ܳ32λ,ֽǰ) */ + +#define CMD50_SET_FILE_SIZE 0x0D /* ļģʽ: õǰļ */ +/* : 68H, ǰļ(ܳ32λ,ֽǰ) */ + +#define CMD11_SET_USB_MODE 0x15 /* USBģʽ */ +//00H=δõ豸ʽ, 01H=õ豸ʽʹⲿ̼ģʽ(ڲ֧), +//02H=õ豸ʽʹù̼ģʽ 03H=SDģʽ/δõģʽ,ڹʹȡSDеļ +//04H=δõʽ, 05H=õʽ, 06H=õʽԶSOF, 07H=õʽҸλUSB */ +//: ״̬( CMD_RET_SUCCESSCMD_RET_ABORT, ֵ˵δ ) + +#define CMD01_GET_STATUS 0x22 /* ȡж״̬ȡж */ +/* : ж״̬ */ + +#define CMD00_UNLOCK_USB 0x23 /* 豸ʽ: ͷŵǰUSB */ + +#define CMD01_RD_USB_DATA0 0x27 /* ӵǰUSBжϵĶ˵㻺˵Ľջȡݿ */ +/* : , */ + +#define CMD01_RD_USB_DATA 0x28 /* 豸ʽ: ӵǰUSBжϵĶ˵㻺ȡݿ, ͷŻ, ൱ CMD01_RD_USB_DATA0 + CMD00_UNLOCK_USB */ +/* : , */ + +#define CMD10_WR_USB_DATA7 0x2B /* 豸ʽ: USB˵2ķͻдݿ */ +/* : , */ + +#define CMD10_WR_HOST_DATA 0x2C /* USB˵ķͻдݿ */ +/* : , */ + +#define CMD01_WR_REQ_DATA 0x2D /* ڲָдݿ */ +/* : */ +/* : */ + +#define CMD20_WR_OFS_DATA 0x2E /* ڲָƫƵַдݿ */ +/* : ƫ, , */ + +#define CMD10_SET_FILE_NAME 0x2F /* ļģʽ: ýҪļļ */ +/* : 0ַ(0ڳȲ14ַ) */ + +/* ********************************************************************************************************************* */ +/* Ҫ(ֲһ), , ڲʱж֪ͨ, û */ + +#define CMD0H_DISK_CONNECT 0x30 /* ļģʽ/֧SD: Ƿ */ +/* ж */ + +#define CMD0H_DISK_MOUNT 0x31 /* ļģʽ: ʼ̲ԴǷ */ +/* ж */ + +#define CMD0H_FILE_OPEN 0x32 /* ļģʽ: ļĿ¼(ļ),öļĿ¼(ļ) */ +/* ж */ + +#define CMD0H_FILE_ENUM_GO 0x33 /* ļģʽ: öļĿ¼(ļ) */ +/* ж */ + +#define CMD0H_FILE_CREATE 0x34 /* ļģʽ: ½ļ,ļѾôɾ */ +/* ж */ + +#define CMD0H_FILE_ERASE 0x35 /* ļģʽ: ɾļ,Ѿֱɾ,ļȴɾ,Ŀ¼ȴ */ +/* ж */ + +#define CMD1H_FILE_CLOSE 0x36 /* ļģʽ: رյǰѾ򿪵ļĿ¼(ļ) */ +/* : Ƿļ */ +/* 00H=ֹ³, 01H=³ */ +/* ж */ + +#define CMD1H_DIR_INFO_READ 0x37 /* ļģʽ: ȡļĿ¼Ϣ */ +/* : ָҪȡĿ¼Ϣṹڵ */ +/* ŷΧΪ00H~0FH, 0FFHΪǰѾ򿪵ļ */ +/* ж */ + +#define CMD0H_DIR_INFO_SAVE 0x38 /* ļģʽ: ļĿ¼Ϣ */ +/* ж */ + +#define CMD4H_BYTE_LOCATE 0x39 /* ļģʽ: ֽΪλƶǰļָ */ +/* : ƫֽ(ܳ32λ,ֽǰ) */ +/* ж */ + +#define CMD2H_BYTE_READ 0x3A /* ļģʽ: ֽΪλӵǰλöȡݿ */ +/* : ȡֽ(ܳ16λ,ֽǰ) */ +/* ж */ + +#define CMD0H_BYTE_RD_GO 0x3B /* ļģʽ: ֽڶ */ +/* ж */ + +#define CMD2H_BYTE_WRITE 0x3C /* ļģʽ: ֽΪλǰλдݿ */ +/* : дֽ(ܳ16λ,ֽǰ) */ +/* ж */ + +#define CMD0H_BYTE_WR_GO 0x3D /* ļģʽ: ֽд */ +/* ж */ + +#define CMD0H_DISK_CAPACITY 0x3E /* ļģʽ: ѯ */ +/* ж */ + +#define CMD0H_DISK_QUERY 0x3F /* ļģʽ: ѯ̿ռϢ */ +/* ж */ + +#define CMD0H_DIR_CREATE 0x40 /* ļģʽ: ½Ŀ¼(ļ),Ŀ¼ѾôֱӴ */ +/* ж */ + +#define CMD4H_SEC_LOCATE 0x4A /* ļģʽ: Ϊλƶǰļָ */ +/* : ƫ(ܳ32λ,ֽǰ) */ +/* ж */ + +#define CMD1H_SEC_READ 0x4B /* ļģʽ/֧SD: Ϊλӵǰλöȡݿ */ +/* : ȡ */ +/* ж */ + +#define CMD1H_SEC_WRITE 0x4C /* ļģʽ/֧SD: Ϊλڵǰλдݿ */ +/* : д */ +/* ж */ + +#define CMD0H_DISK_BOC_CMD 0x50 /* ʽ/֧SD: USB洢ִBulkOnlyЭ */ +/* ж */ + +#define CMD5H_DISK_READ 0x54 /* ʽ/֧SD: USB洢 */ +/* : LBAַ(ܳ32λ, ֽǰ), (01H~FFH) */ +/* ж */ + +#define CMD0H_DISK_RD_GO 0x55 /* ʽ/֧SD: ִUSB洢 */ +/* ж */ + +#define CMD5H_DISK_WRITE 0x56 /* ʽ/֧SD: USB洢д */ +/* : LBAַ(ܳ32λ, ֽǰ), (01H~FFH) */ +/* ж */ + +#define CMD0H_DISK_WR_GO 0x57 /* ʽ/֧SD: ִUSB洢д */ +/* ж */ + +/* ********************************************************************************************************************* */ +/* (ֲ), ̫ûΪCH375CH372 */ + +#define CMD10_SET_USB_SPEED 0x04 /* USBٶ, ÿCMD11_SET_USB_MODEUSBģʽʱԶָ12Mbpsȫ */ +/* : ٶȴ */ +/* 00H=12MbpsȫFullSpeedĬֵ, 01H=1.5Mbps޸Ƶʣ, 02H=1.5MbpsLowSpeed */ + +#define CMD11_GET_DEV_RATE 0x0A /* ʽ: ȡǰӵUSB豸 */ +/* : 07H */ +/* : */ +/* λ4Ϊ11.5MbpsUSB豸, 12MbpsȫUSB豸 */ + +#define CMD11_GET_TOGGLE 0x0A /* ȡOUTͬ״̬ */ +/* : 1AH */ +/* : ͬ״̬ */ +/* λ4Ϊ1OUTͬ, OUTͬ */ + +#define CMD11_READ_VAR8 0x0A /* ȡָ8λļϵͳ */ +/* : ַ */ +/* : */ + +/*#define CMD11_GET_MAX_LUN = CMD11_READ_VAR8( VAR_UDISK_LUN )*/ /* ʽ: ȡUSB洢͵ǰ߼Ԫ */ + +#define CMD20_SET_RETRY 0x0B /* ʽ: USBԴ */ +/* : 25H, Դ */ +/* λ7Ϊ0յNAKʱ, λ7Ϊ1λ6Ϊ0յNAKʱ, λ7Ϊ1λ6Ϊ1յNAKʱ3, λ5~λ0ΪʱԴ */ + +#define CMD20_WRITE_VAR8 0x0B /* ָ8λļϵͳ */ +/* : ַ, */ + +/*#define CMD20_SET_DISK_LUN = CMD20_WRITE_VAR8( VAR_UDISK_LUN )*/ /* ʽ: USB洢ĵǰ߼Ԫ */ + +#define CMD14_READ_VAR32 0x0C /* ȡָ32λļϵͳ */ +/* : ַ */ +/* : (ܳ32λ,ֽǰ) */ + +#define CMD50_WRITE_VAR32 0x0D /* ָ32λļϵͳ */ +/* : ַ, (ܳ32λ,ֽǰ) */ + +#define CMD01_DELAY_100US 0x0F /* ʱ100uS(ڲ֧) */ +/* : ʱڼ0,ʱ0 */ + +#define CMD40_SET_USB_ID 0x12 /* 豸ʽ: USBVIDͲƷPID */ +/* : IDֽ, IDֽ, ƷIDֽ, ƷIDֽ */ + +#define CMD10_SET_USB_ADDR 0x13 /* USBַ */ +/* : ֵַ */ + +#define CMD01_TEST_CONNECT 0x16 /* ʽ/֧SD: USB豸״̬ */ +/* : ״̬( USB_INT_CONNECTUSB_INT_DISCONNECTUSB_INT_USB_READY, ֵ˵δ ) */ + +#define CMD00_ABORT_NAK 0x17 /* ʽ: ǰNAK */ + +#define CMD10_SET_ENDP2 0x18 /* 豸ʽ(ڲ֧): USB˵0Ľ */ +/* : ʽ */ +/* λ7Ϊ1λ6Ϊͬλ, ͬλ */ +/* λ3~λ0ΪӦʽ: 0000-ACK, 1110-æNAK, 1111-STALL */ + +#define CMD10_SET_ENDP3 0x19 /* 豸ʽ(ڲ֧): USB˵0ķ */ +/* : ʽ */ +/* λ7Ϊ1λ6Ϊͬλ, ͬλ */ +/* λ3~λ0ΪӦʽ: 0000~1000-ACK, 1110-æNAK, 1111-STALL */ + +#define CMD10_SET_ENDP4 0x1A /* 豸ʽ(ڲ֧): USB˵1Ľ */ +/* : ʽ */ +/* λ7Ϊ1λ6Ϊͬλ, ͬλ */ +/* λ3~λ0ΪӦʽ: 0000-ACK, 1110-æNAK, 1111-STALL */ + +#define CMD10_SET_ENDP5 0x1B /* 豸ʽ(ڲ֧): USB˵1ķ */ +/* : ʽ */ +/* λ7Ϊ1λ6Ϊͬλ, ͬλ */ +/* λ3~λ0ΪӦʽ: 0000~1000-ACK, 1110-æNAK, 1111-STALL */ + +#define CMD10_SET_ENDP6 0x1C /* USB˵2/˵Ľ */ +/* : ʽ */ +/* λ7Ϊ1λ6Ϊͬλ, ͬλ */ +/* λ3~λ0ΪӦʽ: 0000-ACK, 1101-ACK, 1110-æNAK, 1111-STALL */ + +#define CMD10_SET_ENDP7 0x1D /* USB˵2/˵ķ */ +/* : ʽ */ +/* λ7Ϊ1λ6Ϊͬλ, ͬλ */ +/* λ3~λ0ΪӦʽ: 0000-ACK, 1101-Ӧ, 1110-æNAK, 1111-STALL */ + +#define CMD00_DIRTY_BUFFER 0x25 /* ļģʽ: ڲĴ̺ļ */ + +#define CMD10_WR_USB_DATA3 0x29 /* 豸ʽ(ڲ֧): USB˵0ķͻдݿ */ +/* : , */ + +#define CMD10_WR_USB_DATA5 0x2A /* 豸ʽ(ڲ֧): USB˵1ķͻдݿ */ +/* : , */ + +/* ********************************************************************************************************************* */ +/* (ֲ), ̫ûΪCH375CH372, ڲʱж֪ͨ, û */ + +#define CMD1H_CLR_STALL 0x41 /* ʽ: ƴ-˵ */ +/* : ˵ */ +/* ж */ + +#define CMD1H_SET_ADDRESS 0x45 /* ʽ: ƴ-USBַ */ +/* : ֵַ */ +/* ж */ + +#define CMD1H_GET_DESCR 0x46 /* ʽ: ƴ-ȡ */ +/* : */ +/* ж */ + +#define CMD1H_SET_CONFIG 0x49 /* ʽ: ƴ-USB */ +/* : ֵ */ +/* ж */ + +#define CMD0H_AUTO_SETUP 0x4D /* ʽ/֧SD: ԶUSB豸 */ +/* ж */ + +#define CMD2H_ISSUE_TKN_X 0x4E /* ʽ: ͬ, ִ, ɴ CMD10_SET_ENDP6/CMD10_SET_ENDP7 + CMD1H_ISSUE_TOKEN */ +/* : ͬ־, */ +/* ͬ־λ7Ϊ˵INͬλ, λ6Ϊ˵OUTͬλ, λ5~λ0Ϊ0 */ +/* Եĵ4λ, 4λǶ˵ */ +/* ж */ + +#define CMD1H_ISSUE_TOKEN 0x4F /* ʽ: , ִ, CMD2H_ISSUE_TKN_X */ +/* : */ +/* 4λ, 4λǶ˵ */ +/* ж */ + +#define CMD0H_DISK_INIT 0x51 /* ʽ/֧SD: ʼUSB洢 */ +/* ж */ + +#define CMD0H_DISK_RESET 0x52 /* ʽ/֧SD: ƴ-λUSB洢 */ +/* ж */ + +#define CMD0H_DISK_SIZE 0x53 /* ʽ/֧SD: ȡUSB洢 */ +/* ж */ + +#define CMD0H_DISK_INQUIRY 0x58 /* ʽ/֧SD: ѯUSB洢 */ +/* ж */ + +#define CMD0H_DISK_READY 0x59 /* ʽ/֧SD: USB洢 */ +/* ж */ + +#define CMD0H_DISK_R_SENSE 0x5A /* ʽ/֧SD: USB洢 */ +/* ж */ + +#define CMD0H_RD_DISK_SEC 0x5B /* ļģʽ: Ӵ̶ȡһݵڲ */ +/* ж */ + +#define CMD0H_WR_DISK_SEC 0x5C /* ļģʽ: ڲһд */ +/* ж */ + +#define CMD0H_DISK_MAX_LUN 0x5D /* ʽ: ƴ-ȡUSB洢߼Ԫ */ +/* ж */ + +/* ********************************************************************************************************************* */ +/* ¶ֻΪ˼CH375INCLUDEļеƸʽ */ + +#ifndef _NO_CH375_COMPATIBLE_ +#define CMD_GET_IC_VER CMD01_GET_IC_VER +#define CMD_SET_BAUDRATE CMD21_SET_BAUDRATE +#define CMD_ENTER_SLEEP CMD00_ENTER_SLEEP +#define CMD_RESET_ALL CMD00_RESET_ALL +#define CMD_CHECK_EXIST CMD11_CHECK_EXIST +#define CMD_CHK_SUSPEND CMD20_CHK_SUSPEND +#define CMD_SET_SDO_INT CMD20_SET_SDO_INT +#define CMD_GET_FILE_SIZE CMD14_GET_FILE_SIZE +#define CMD_SET_FILE_SIZE CMD50_SET_FILE_SIZE +#define CMD_SET_USB_MODE CMD11_SET_USB_MODE +#define CMD_GET_STATUS CMD01_GET_STATUS +#define CMD_UNLOCK_USB CMD00_UNLOCK_USB +#define CMD_RD_USB_DATA0 CMD01_RD_USB_DATA0 +#define CMD_RD_USB_DATA CMD01_RD_USB_DATA +#define CMD_WR_USB_DATA7 CMD10_WR_USB_DATA7 +#define CMD_WR_HOST_DATA CMD10_WR_HOST_DATA +#define CMD_WR_REQ_DATA CMD01_WR_REQ_DATA +#define CMD_WR_OFS_DATA CMD20_WR_OFS_DATA +#define CMD_SET_FILE_NAME CMD10_SET_FILE_NAME +#define CMD_DISK_CONNECT CMD0H_DISK_CONNECT +#define CMD_DISK_MOUNT CMD0H_DISK_MOUNT +#define CMD_FILE_OPEN CMD0H_FILE_OPEN +#define CMD_FILE_ENUM_GO CMD0H_FILE_ENUM_GO +#define CMD_FILE_CREATE CMD0H_FILE_CREATE +#define CMD_FILE_ERASE CMD0H_FILE_ERASE +#define CMD_FILE_CLOSE CMD1H_FILE_CLOSE +#define CMD_DIR_INFO_READ CMD1H_DIR_INFO_READ +#define CMD_DIR_INFO_SAVE CMD0H_DIR_INFO_SAVE +#define CMD_BYTE_LOCATE CMD4H_BYTE_LOCATE +#define CMD_BYTE_READ CMD2H_BYTE_READ +#define CMD_BYTE_RD_GO CMD0H_BYTE_RD_GO +#define CMD_BYTE_WRITE CMD2H_BYTE_WRITE +#define CMD_BYTE_WR_GO CMD0H_BYTE_WR_GO +#define CMD_DISK_CAPACITY CMD0H_DISK_CAPACITY +#define CMD_DISK_QUERY CMD0H_DISK_QUERY +#define CMD_DIR_CREATE CMD0H_DIR_CREATE +#define CMD_SEC_LOCATE CMD4H_SEC_LOCATE +#define CMD_SEC_READ CMD1H_SEC_READ +#define CMD_SEC_WRITE CMD1H_SEC_WRITE +#define CMD_DISK_BOC_CMD CMD0H_DISK_BOC_CMD +#define CMD_DISK_READ CMD5H_DISK_READ +#define CMD_DISK_RD_GO CMD0H_DISK_RD_GO +#define CMD_DISK_WRITE CMD5H_DISK_WRITE +#define CMD_DISK_WR_GO CMD0H_DISK_WR_GO +#define CMD_SET_USB_SPEED CMD10_SET_USB_SPEED +#define CMD_GET_DEV_RATE CMD11_GET_DEV_RATE +#define CMD_GET_TOGGLE CMD11_GET_TOGGLE +#define CMD_READ_VAR8 CMD11_READ_VAR8 +#define CMD_SET_RETRY CMD20_SET_RETRY +#define CMD_WRITE_VAR8 CMD20_WRITE_VAR8 +#define CMD_READ_VAR32 CMD14_READ_VAR32 +#define CMD_WRITE_VAR32 CMD50_WRITE_VAR32 +#define CMD_DELAY_100US CMD01_DELAY_100US +#define CMD_SET_USB_ID CMD40_SET_USB_ID +#define CMD_SET_USB_ADDR CMD10_SET_USB_ADDR +#define CMD_TEST_CONNECT CMD01_TEST_CONNECT +#define CMD_ABORT_NAK CMD00_ABORT_NAK +#define CMD_SET_ENDP2 CMD10_SET_ENDP2 +#define CMD_SET_ENDP3 CMD10_SET_ENDP3 +#define CMD_SET_ENDP4 CMD10_SET_ENDP4 +#define CMD_SET_ENDP5 CMD10_SET_ENDP5 +#define CMD_SET_ENDP6 CMD10_SET_ENDP6 +#define CMD_SET_ENDP7 CMD10_SET_ENDP7 +#define CMD_DIRTY_BUFFER CMD00_DIRTY_BUFFER +#define CMD_WR_USB_DATA3 CMD10_WR_USB_DATA3 +#define CMD_WR_USB_DATA5 CMD10_WR_USB_DATA5 +#define CMD_CLR_STALL CMD1H_CLR_STALL +#define CMD_SET_ADDRESS CMD1H_SET_ADDRESS +#define CMD_GET_DESCR CMD1H_GET_DESCR +#define CMD_SET_CONFIG CMD1H_SET_CONFIG +#define CMD_AUTO_SETUP CMD0H_AUTO_SETUP +#define CMD_ISSUE_TKN_X CMD2H_ISSUE_TKN_X +#define CMD_ISSUE_TOKEN CMD1H_ISSUE_TOKEN +#define CMD_DISK_INIT CMD0H_DISK_INIT +#define CMD_DISK_RESET CMD0H_DISK_RESET +#define CMD_DISK_SIZE CMD0H_DISK_SIZE +#define CMD_DISK_INQUIRY CMD0H_DISK_INQUIRY +#define CMD_DISK_READY CMD0H_DISK_READY +#define CMD_DISK_R_SENSE CMD0H_DISK_R_SENSE +#define CMD_RD_DISK_SEC CMD0H_RD_DISK_SEC +#define CMD_WR_DISK_SEC CMD0H_WR_DISK_SEC +#define CMD_DISK_MAX_LUN CMD0H_DISK_MAX_LUN +#endif + +/* ********************************************************************************************************************* */ +/* ڷʽ, ״̬˿(˿)λ */ +#ifndef PARA_STATE_INTB +#define PARA_STATE_INTB 0x80 /* ڷʽ״̬˿ڵλ7: жϱ־,Ч */ +#define PARA_STATE_BUSY 0x10 /* ڷʽ״̬˿ڵλ4: æ־,Ч */ +#endif + +/* ********************************************************************************************************************* */ +/* ڷʽ, ǰͬ */ +#ifndef SER_CMD_TIMEOUT +#define SER_CMD_TIMEOUT 32 /* ʱʱ, λΪmS, ֮ͬ估֮ͬļӦþ, ʱĴʽΪ */ +#define SER_SYNC_CODE1 0x57 /* ĵ1ͬ */ +#define SER_SYNC_CODE2 0xAB /* ĵ2ͬ */ +#endif + +/* ********************************************************************************************************************* */ +/* ״̬ */ + +#ifndef CMD_RET_SUCCESS +#define CMD_RET_SUCCESS 0x51 /* ɹ */ +#define CMD_RET_ABORT 0x5F /* ʧ */ +#endif + +/* ********************************************************************************************************************* */ +/* USBж״̬ */ + +#ifndef USB_INT_EP0_SETUP + +/* ״̬Ϊ¼ж, ͨCMD20_CHK_SUSPENDUSB߹, ô봦USB߹˯߻ѵж״̬ */ +#define USB_INT_USB_SUSPEND 0x05 /* USB߹¼ */ +#define USB_INT_WAKE_UP 0x06 /* ˯б¼ */ + +/* ״̬0XHUSB豸ʽ */ +/* ù̼ģʽֻҪ: USB_INT_EP1_OUT, USB_INT_EP1_IN, USB_INT_EP2_OUT, USB_INT_EP2_IN */ +/* λ7-λ4Ϊ0000 */ +/* λ3-λ2ָʾǰ, 00=OUT, 10=IN, 11=SETUP */ +/* λ1-λ0ָʾǰ˵, 00=˵0, 01=˵1, 10=˵2, 11=USB߸λ */ +#define USB_INT_EP0_SETUP 0x0C /* USB˵0SETUP */ +#define USB_INT_EP0_OUT 0x00 /* USB˵0OUT */ +#define USB_INT_EP0_IN 0x08 /* USB˵0IN */ +#define USB_INT_EP1_OUT 0x01 /* USB˵1OUT */ +#define USB_INT_EP1_IN 0x09 /* USB˵1IN */ +#define USB_INT_EP2_OUT 0x02 /* USB˵2OUT */ +#define USB_INT_EP2_IN 0x0A /* USB˵2IN */ +/* USB_INT_BUS_RESET 0x0000XX11B */ /* USB߸λ */ +#define USB_INT_BUS_RESET1 0x03 /* USB߸λ */ +#define USB_INT_BUS_RESET2 0x07 /* USB߸λ */ +#define USB_INT_BUS_RESET3 0x0B /* USB߸λ */ +#define USB_INT_BUS_RESET4 0x0F /* USB߸λ */ + +#endif + +/* ״̬2XH-3XHUSBʽͨѶʧܴ */ +/* λ7-λ6Ϊ00 */ +/* λ5Ϊ1 */ +/* λ4ָʾǰյݰǷͬ */ +/* λ3-λ0ָʾͨѶʧʱUSB豸Ӧ: 0010=ACK, 1010=NAK, 1110=STALL, 0011=DATA0, 1011=DATA1, XX00=ʱ */ +/* USB_INT_RET_ACK 0x001X0010B */ /* :IN񷵻ACK */ +/* USB_INT_RET_NAK 0x001X1010B */ /* :NAK */ +/* USB_INT_RET_STALL 0x001X1110B */ /* :STALL */ +/* USB_INT_RET_DATA0 0x001X0011B */ /* :OUT/SETUP񷵻DATA0 */ +/* USB_INT_RET_DATA1 0x001X1011B */ /* :OUT/SETUP񷵻DATA1 */ +/* USB_INT_RET_TOUT 0x001XXX00B */ /* :سʱ */ +/* USB_INT_RET_TOGX 0x0010X011B */ /* :IN񷵻ݲͬ */ +/* USB_INT_RET_PID 0x001XXXXXB */ /* :δ */ + +/* ״̬1XHUSBʽIJ״̬ */ +#ifndef USB_INT_SUCCESS +#define USB_INT_SUCCESS 0x14 /* USBߴɹ */ +#define USB_INT_CONNECT 0x15 /* ⵽USB豸¼, ӻ߶Ͽ */ +#define USB_INT_DISCONNECT 0x16 /* ⵽USB豸Ͽ¼ */ +#define USB_INT_BUF_OVER 0x17 /* USB̫໺ */ +#define USB_INT_USB_READY 0x18 /* USB豸Ѿʼ(ѾUSBַ) */ +#define USB_INT_DISK_READ 0x1D /* USB洢ݶ */ +#define USB_INT_DISK_WRITE 0x1E /* USB洢д */ +#define USB_INT_DISK_ERR 0x1F /* USB洢ʧ */ +#endif + +/* ״̬ļģʽµļϵͳ */ +#ifndef ERR_DISK_DISCON +#define ERR_DISK_DISCON 0x82 /* δ,ܴѾϿ */ +#define ERR_LARGE_SECTOR 0x84 /* ̵̫,ֻ֧ÿ512ֽ */ +#define ERR_TYPE_ERROR 0x92 /* ̷Ͳ֧,ֻ֧FAT12/FAT16/BigDOS/FAT32,Ҫɴ̹· */ +#define ERR_BPB_ERROR 0xA1 /* δʽ,߲,ҪWINDOWSĬϲ¸ʽ */ +#define ERR_DISK_FULL 0xB1 /* ļ̫,ʣռ̫ٻѾû,Ҫ */ +#define ERR_FDT_OVER 0xB2 /* Ŀ¼(ļ)ļ̫,ûпеĿ¼,FAT12/FAT16Ŀ¼µļӦ512,Ҫ */ +#define ERR_FILE_CLOSE 0xB4 /* ļѾر,Ҫʹ,Ӧ´ļ */ +#define ERR_OPEN_DIR 0x41 /* ָ·Ŀ¼(ļ) */ +#define ERR_MISS_FILE 0x42 /* ָ·ļûҵ,ļƴ */ +#define ERR_FOUND_NAME 0x43 /* ƥļ,ҪĿ¼(ļ)ʵʽȴļ */ +/* ļϵͳļϵͳӳ */ +#define ERR_MISS_DIR 0xB3 /* ָ·ijĿ¼(ļ)ûҵ,Ŀ¼ƴ */ +#define ERR_LONG_BUF_OVER 0x48 /* ļ */ +#define ERR_LONG_NAME_ERR 0x49 /* ļûжӦijļ߳ļ */ +#define ERR_NAME_EXIST 0x4A /* ͬĶļѾ,һļ */ +#endif + +/* ********************************************************************************************************************* */ +/* ״̬ļģʽµĴ̼ļ״̬, VAR_DISK_STATUS */ +#ifndef DEF_DISK_UNKNOWN +#define DEF_DISK_UNKNOWN 0x00 /* δʼ,δ֪״̬ */ +#define DEF_DISK_DISCONN 0x01 /* ûӻѾϿ */ +#define DEF_DISK_CONNECT 0x02 /* Ѿ,δʼ޷ʶô */ +#define DEF_DISK_MOUNTED 0x03 /* Ѿʼɹ,δļϵͳļϵͳ֧ */ +#define DEF_DISK_READY 0x10 /* Ѿ̵ļϵͳܹ֧ */ +#define DEF_DISK_OPEN_ROOT 0x12 /* Ѿ򿪸Ŀ¼,ʹúر,עFAT12/FAT16Ŀ¼ǹ̶ */ +#define DEF_DISK_OPEN_DIR 0x13 /* ѾĿ¼(ļ) */ +#define DEF_DISK_OPEN_FILE 0x14 /* Ѿļ */ +#endif + +/* ********************************************************************************************************************* */ +/* ļϵͳö */ + +#ifndef DEF_SECTOR_SIZE +#define DEF_SECTOR_SIZE 512 /* U̻SDĬϵĴС */ +#endif + +#ifndef DEF_WILDCARD_CHAR +#define DEF_WILDCARD_CHAR 0x2A /* ·ͨ '*' */ +#define DEF_SEPAR_CHAR1 0x5C /* ·ķָ '\' */ +#define DEF_SEPAR_CHAR2 0x2F /* ·ķָ '/' */ +#define DEF_FILE_YEAR 2004 /* Ĭļ: 2004 */ +#define DEF_FILE_MONTH 1 /* Ĭļ: 1 */ +#define DEF_FILE_DATE 1 /* Ĭļ: 1 */ +#endif + +#ifndef ATTR_DIRECTORY + +/* FATļĿ¼Ϣ */ +typedef struct _FAT_DIR_INFO { + UINT8 DIR_Name[11]; /* 00H,ļ,11ֽ,㴦ո */ + UINT8 DIR_Attr; /* 0BH,ļ,ο˵ */ + UINT8 DIR_NTRes; /* 0CH */ + UINT8 DIR_CrtTimeTenth; /* 0DH,ļʱ,0.1뵥λ */ + UINT16 DIR_CrtTime; /* 0EH,ļʱ */ + UINT16 DIR_CrtDate; /* 10H,ļ */ + UINT16 DIR_LstAccDate; /* 12H,һδȡ */ + UINT16 DIR_FstClusHI; /* 14H */ + UINT16 DIR_WrtTime; /* 16H,ļ޸ʱ,οǰĺMAKE_FILE_TIME */ + UINT16 DIR_WrtDate; /* 18H,ļ޸,οǰĺMAKE_FILE_DATE */ + UINT16 DIR_FstClusLO; /* 1AH */ + UINT32 DIR_FileSize; /* 1CH,ļ */ +} FAT_DIR_INFO, *P_FAT_DIR_INFO; /* 20H */ + +/* ļ */ +#define ATTR_READ_ONLY 0x01 /* ļΪֻ */ +#define ATTR_HIDDEN 0x02 /* ļΪ */ +#define ATTR_SYSTEM 0x04 /* ļΪϵͳ */ +#define ATTR_VOLUME_ID 0x08 /* */ +#define ATTR_DIRECTORY 0x10 /* Ŀ¼(ļ) */ +#define ATTR_ARCHIVE 0x20 /* ļΪ浵 */ +#define ATTR_LONG_NAME ( ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID ) /* ļ */ +#define ATTR_LONG_NAME_MASK ( ATTR_LONG_NAME | ATTR_DIRECTORY | ATTR_ARCHIVE ) +/* ļ UINT8 */ +/* bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 */ +/* ֻ ϵ Ŀ δ */ +/* ͳ ¼ */ +/* ļʱ UINT16 */ +/* Time = (Hour<<11) + (Minute<<5) + (Second>>1) */ +#define MAKE_FILE_TIME( h, m, s ) ( (h<<11) + (m<<5) + (s>>1) ) /* ָʱļʱ */ +/* ļ UINT16 */ +/* Date = ((Year-1980)<<9) + (Month<<5) + Day */ +#define MAKE_FILE_DATE( y, m, d ) ( ((y-1980)<<9) + (m<<5) + d ) /* ָյļ */ + +#define LONE_NAME_MAX_CHAR (255*2) /* ļַ/ֽ */ +#define LONG_NAME_PER_DIR (13*2) /* ļÿļĿ¼Ϣṹеַ/ֽ */ + +#endif + +/* ********************************************************************************************************************* */ +/* SCSIṹ */ + +#ifndef SPC_CMD_INQUIRY + +/* SCSI */ +#define SPC_CMD_INQUIRY 0x12 +#define SPC_CMD_READ_CAPACITY 0x25 +#define SPC_CMD_READ10 0x28 +#define SPC_CMD_WRITE10 0x2A +#define SPC_CMD_TEST_READY 0x00 +#define SPC_CMD_REQUEST_SENSE 0x03 +#define SPC_CMD_MODESENSE6 0x1A +#define SPC_CMD_MODESENSE10 0x5A +#define SPC_CMD_START_STOP 0x1B + +/* BulkOnlyЭ */ +typedef struct _BULK_ONLY_CBW { + UINT32 CBW_Sig; + UINT32 CBW_Tag; + UINT8 CBW_DataLen0; /* 08H,: ݴ䳤,Чֵ048,ЧֵΪ033 */ + UINT8 CBW_DataLen1; + UINT16 CBW_DataLen2; + UINT8 CBW_Flag; /* 0CH,: ䷽ȱ־,λ7Ϊ1,λΪ0ݻû */ + UINT8 CBW_LUN; + UINT8 CBW_CB_Len; /* 0EH,: ij,Чֵ116 */ + UINT8 CBW_CB_Buf[16]; /* 0FH,: ,ûΪ16ֽ */ +} BULK_ONLY_CBW, *P_BULK_ONLY_CBW; /* BulkOnlyЭ, CBWṹ */ + +/* INQUIRYķ */ +typedef struct _INQUIRY_DATA { + UINT8 DeviceType; /* 00H, 豸 */ + UINT8 RemovableMedia; /* 01H, λ7Ϊ1˵ƶ洢 */ + UINT8 Versions; /* 02H, Э汾 */ + UINT8 DataFormatAndEtc; /* 03H, ָݸʽ */ + UINT8 AdditionalLength; /* 04H, ݵij */ + UINT8 Reserved1; + UINT8 Reserved2; + UINT8 MiscFlag; /* 07H, һЩƱ־ */ + UINT8 VendorIdStr[8]; /* 08H, Ϣ */ + UINT8 ProductIdStr[16]; /* 10H, ƷϢ */ + UINT8 ProductRevStr[4]; /* 20H, Ʒ汾 */ +} INQUIRY_DATA, *P_INQUIRY_DATA; /* 24H */ + +/* REQUEST SENSEķ */ +typedef struct _SENSE_DATA { + UINT8 ErrorCode; /* 00H, 뼰Чλ */ + UINT8 SegmentNumber; + UINT8 SenseKeyAndEtc; /* 02H, */ + UINT8 Information0; + UINT8 Information1; + UINT8 Information2; + UINT8 Information3; + UINT8 AdditSenseLen; /* 07H, ݵij */ + UINT8 CmdSpecInfo[4]; + UINT8 AdditSenseCode; /* 0CH, Ӽ */ + UINT8 AddSenCodeQual; /* 0DH, ϸĸӼ */ + UINT8 FieldReplaUnit; + UINT8 SenseKeySpec[3]; +} SENSE_DATA, *P_SENSE_DATA; /* 12H */ + +#endif + +/* ********************************************************************************************************************* */ +/* ļģʽµṹ */ + +#ifndef MAX_FILE_NAME_LEN + +#define MAX_FILE_NAME_LEN (13+1) /* ļ󳤶,󳤶1Ŀ¼+8ļ+1С+3+=14 */ + +/* ݺ */ +typedef union _CH376_CMD_DATA { + struct { + UINT8 mBuffer[ MAX_FILE_NAME_LEN ]; + } Default; + + INQUIRY_DATA DiskMountInq; /* : INQUIRYķ */ + /* CMD0H_DISK_MOUNT: ʼ̲ԴǷ,״ִʱ */ + + FAT_DIR_INFO OpenDirInfo; /* : öٵļĿ¼Ϣ */ + /* CMD0H_FILE_OPEN: öļĿ¼(ļ) */ + + FAT_DIR_INFO EnumDirInfo; /* : öٵļĿ¼Ϣ */ + /* CMD0H_FILE_ENUM_GO: öļĿ¼(ļ) */ + + struct { + UINT8 mUpdateFileSz; /* : Ƿļ, 0ֹ³ */ + } FileCLose; /* CMD1H_FILE_CLOSE: رյǰѾ򿪵ļ */ + + struct { + UINT8 mDirInfoIndex; /* : ָҪȡĿ¼Ϣṹڵ, 0FFHΪǰѾ򿪵ļ */ + } DirInfoRead; /* CMD1H_DIR_INFO_READ: ȡļĿ¼Ϣ */ + + union { + UINT32 mByteOffset; /* : ƫֽ,ֽΪλƫ(ܳ32λ,ֽǰ) */ + UINT32 mSectorLba; /* : ǰļָӦľ,0FFFFFFFFHѵļβ(ܳ32λ,ֽǰ) */ + } ByteLocate; /* CMD4H_BYTE_LOCATE: ֽΪλƶǰļָ */ + + struct { + UINT16 mByteCount; /* : ȡֽ(ܳ16λ,ֽǰ) */ + } ByteRead; /* CMD2H_BYTE_READ: ֽΪλӵǰλöȡݿ */ + + struct { + UINT16 mByteCount; /* : дֽ(ܳ16λ,ֽǰ) */ + } ByteWrite; /* CMD2H_BYTE_WRITE: ֽΪλǰλдݿ */ + + union { + UINT32 mSectorOffset; /* : ƫ,Ϊλƫ(ܳ32λ,ֽǰ) */ + UINT32 mSectorLba; /* : ǰļָӦľ,0FFFFFFFFHѵļβ(ܳ32λ,ֽǰ) */ + } SectorLocate; /* CMD4H_SEC_LOCATE: Ϊλƶǰļָ */ + + struct { + UINT8 mSectorCount; /* : ȡ */ + /* : ȡ */ + UINT8 mReserved1; + UINT8 mReserved2; + UINT8 mReserved3; + UINT32 mStartSector; /* : ȡʼ(ܳ32λ,ֽǰ) */ + } SectorRead; /* CMD1H_SEC_READ: Ϊλӵǰλöȡݿ */ + + struct { + UINT8 mSectorCount; /* : д */ + /* : д */ + UINT8 mReserved1; + UINT8 mReserved2; + UINT8 mReserved3; + UINT32 mStartSector; /* : дʼ(ܳ32λ,ֽǰ) */ + } SectorWrite; /* CMD1H_SEC_WRITE: Ϊλڵǰλдݿ */ + + struct { + UINT32 mDiskSizeSec; /* : ̵(ܳ32λ,ֽǰ) */ + } DiskCapacity; /* CMD0H_DISK_CAPACITY: ѯ */ + + struct { + UINT32 mTotalSector; /* : ǰ߼̵(ܳ32λ,ֽǰ) */ + UINT32 mFreeSector; /* : ǰ߼̵ʣ(ܳ32λ,ֽǰ) */ + UINT8 mDiskFat; /* : ǰ߼̵FAT,1-FAT12,2-FAT16,3-FAT32 */ + } DiskQuery; /* CMD_DiskQuery, ѯϢ */ + + BULK_ONLY_CBW DiskBocCbw; /* : CBWṹ */ + /* CMD0H_DISK_BOC_CMD: USB洢ִBulkOnlyЭ */ + + struct { + UINT8 mMaxLogicUnit; /* : USB洢߼Ԫ */ + } DiskMaxLun; /* CMD0H_DISK_MAX_LUN: ƴ-ȡUSB洢߼Ԫ */ + + INQUIRY_DATA DiskInitInq; /* : INQUIRYķ */ + /* CMD0H_DISK_INIT: ʼUSB洢 */ + + INQUIRY_DATA DiskInqData; /* : INQUIRYķ */ + /* CMD0H_DISK_INQUIRY: ѯUSB洢 */ + + SENSE_DATA ReqSenseData; /* : REQUEST SENSEķ */ + /* CMD0H_DISK_R_SENSE: USB洢 */ + + struct { + UINT32 mDiskSizeSec; /* : ̵(ܳ32λ,ֽǰ) */ + } DiskSize; /* CMD0H_DISK_SIZE: ȡUSB洢 */ + + struct { + UINT32 mStartSector; /* : LBAַ(ܳ32λ,ֽǰ) */ + UINT8 mSectorCount; /* : ȡ */ + } DiskRead; /* CMD5H_DISK_READ: USB洢ݿ(Ϊλ) */ + + struct { + UINT32 mStartSector; /* : LBAַ(ܳ32λ,ֽǰ) */ + UINT8 mSectorCount; /* : д */ + } DiskWrite; /* CMD5H_DISK_WRITE: USB洢дݿ(Ϊλ) */ +} CH376_CMD_DATA, *P_CH376_CMD_DATA; + +#endif + +/* ********************************************************************************************************************* */ +/* ļģʽµļϵͳĵַ */ + +#ifndef VAR_FILE_SIZE + +/* 8λ/ֽڱ */ +#define VAR_SYS_BASE_INFO 0x20 /* ǰϵͳĻϢ */ +/* λ6ָʾUSB洢豸SubClass-Code, λ6Ϊ0˵Ϊ6, λ6Ϊ1˵Ƿ6ֵ */ +/* λ5ָʾUSB豸ʽµUSB״̬USBʽµUSB豸״̬ */ +/* USB豸ʽ, λ5Ϊ1USB, λ5λ0δ */ +/* USBʽ, λ5Ϊ1USB˿ڴUSB豸, λ5λ0USB˿ûUSB豸 */ +/* λ4ָʾUSB豸ʽµĻ״̬, λ4Ϊ1˵USB״̬, λ6Ϊ1˵Ѿͷ */ +/* λ, ,޸ */ +#define VAR_RETRY_TIMES 0x25 /* USBԴ */ +/* λ7Ϊ0յNAKʱ, λ7Ϊ1λ6Ϊ0յNAKʱ(CMD_ABORT_NAK), λ7Ϊ1λ6Ϊ1յNAKʱ3 */ +/* λ5~λ0ΪʱԴ */ +#define VAR_FILE_BIT_FLAG 0x26 /* ļģʽµλ־ */ +/* λ1λ0, ߼̵FATļϵͳ־, 00-FAT12, 01-FAT16, 10-FAT32, 11-Ƿ */ +/* λ2, ǰеFATǷ޸ı־, 0-δ޸, 1-޸ */ +/* λ3, ļҪ޸ı־, ǰļ׷, 0-δ׷޸, 1-׷Ҫ޸ */ +/* λ, ,޸ */ +#define VAR_DISK_STATUS 0x2B /* ļģʽµĴ̼ļ״̬ */ +#define VAR_SD_BIT_FLAG 0x30 /* ļģʽSDλ־ */ +/* λ0, SD汾, 0-ֻ֧SDһ,1-֧SDڶ */ +/* λ1, Զʶ, 0-SD, 1-MMC */ +/* λ2, Զʶ, 0-׼SD, 1-SD(HC-SD) */ +/* λ4, ACMD41ʱ */ +/* λ5, CMD1ʱ */ +/* λ6, CMD58ʱ */ +/* λ, ,޸ */ +#define VAR_UDISK_TOGGLE 0x31 /* USB洢豸BULK-IN/BULK-OUT˵ͬ־ */ +/* λ7, Bulk-In˵ͬ־ */ +/* λ6, Bulk-In˵ͬ־ */ +/* λ5~λ0, Ϊ0 */ +#define VAR_UDISK_LUN 0x34 /* USB洢豸߼Ԫ */ +/* λ7~λ4, USB洢豸ĵǰ߼Ԫ,CH376ʼUSB洢豸,ĬǷ0#߼Ԫ */ +/* λ3~λ0, USB洢豸߼Ԫ,1߼Ԫ */ +#define VAR_SEC_PER_CLUS 0x38 /* ߼̵ÿ */ +#define VAR_FILE_DIR_INDEX 0x3B /* ǰļĿ¼Ϣڵ */ +#define VAR_CLUS_SEC_OFS 0x3C /* ǰļָڴڵƫ,Ϊ0xFFָļĩβ,ؽ */ + +/* 32λ/4ֽڱ */ +#define VAR_DISK_ROOT 0x44 /* FAT16ΪĿ¼ռ,FAT32ΪĿ¼ʼغ(ܳ32λ,ֽǰ) */ +#define VAR_DSK_TOTAL_CLUS 0x48 /* ߼̵ܴ(ܳ32λ,ֽǰ) */ +#define VAR_DSK_START_LBA 0x4C /* ߼̵ʼLBA(ܳ32λ,ֽǰ) */ +#define VAR_DSK_DAT_START 0x50 /* ߼̵ʼLBA(ܳ32λ,ֽǰ) */ +#define VAR_LBA_BUFFER 0x54 /* ǰݻݶӦLBA(ܳ32λ,ֽǰ) */ +#define VAR_LBA_CURRENT 0x58 /* ǰдĴʼLBAַ(ܳ32λ,ֽǰ) */ +#define VAR_FAT_DIR_LBA 0x5C /* ǰļĿ¼ϢڵLBAַ(ܳ32λ,ֽǰ) */ +#define VAR_START_CLUSTER 0x60 /* ǰļĿ¼(ļ)ʼغ(ܳ32λ,ֽǰ) */ +#define VAR_CURRENT_CLUST 0x64 /* ǰļĵǰغ(ܳ32λ,ֽǰ) */ +#define VAR_FILE_SIZE 0x68 /* ǰļij(ܳ32λ,ֽǰ) */ +#define VAR_CURRENT_OFFSET 0x6C /* ǰļָ,ǰдλõֽƫ(ܳ32λ,ֽǰ) */ + +#endif + +/* ********************************************************************************************************************* */ +/* USB */ + +/* USBİʶPID, ʽõ */ +#ifndef DEF_USB_PID_SETUP +#define DEF_USB_PID_NULL 0x00 /* PID, δ */ +#define DEF_USB_PID_SOF 0x05 +#define DEF_USB_PID_SETUP 0x0D +#define DEF_USB_PID_IN 0x09 +#define DEF_USB_PID_OUT 0x01 +#define DEF_USB_PID_ACK 0x02 +#define DEF_USB_PID_NAK 0x0A +#define DEF_USB_PID_STALL 0x0E +#define DEF_USB_PID_DATA0 0x03 +#define DEF_USB_PID_DATA1 0x0B +#define DEF_USB_PID_PRE 0x0C +#endif + +/* USB, ù̼ģʽõ */ +#ifndef DEF_USB_REQ_TYPE +#define DEF_USB_REQ_READ 0x80 /* ƶ */ +#define DEF_USB_REQ_WRITE 0x00 /* д */ +#define DEF_USB_REQ_TYPE 0x60 /* */ +#define DEF_USB_REQ_STAND 0x00 /* ׼ */ +#define DEF_USB_REQ_CLASS 0x20 /* 豸 */ +#define DEF_USB_REQ_VENDOR 0x40 /* */ +#define DEF_USB_REQ_RESERVE 0x60 /* */ +#endif + +/* USB׼豸, RequestTypeλ6λ5=00(Standard), ù̼ģʽõ */ +#ifndef DEF_USB_GET_DESCR +#define DEF_USB_CLR_FEATURE 0x01 +#define DEF_USB_SET_FEATURE 0x03 +#define DEF_USB_GET_STATUS 0x00 +#define DEF_USB_SET_ADDRESS 0x05 +#define DEF_USB_GET_DESCR 0x06 +#define DEF_USB_SET_DESCR 0x07 +#define DEF_USB_GET_CONFIG 0x08 +#define DEF_USB_SET_CONFIG 0x09 +#define DEF_USB_GET_INTERF 0x0A +#define DEF_USB_SET_INTERF 0x0B +#define DEF_USB_SYNC_FRAME 0x0C +#endif + +/* *************************************************************************** */ + +#ifdef __cplusplus +} +#endif + +#endif +/************************************ End *************************************/ diff --git a/User/CH376_Driver/FILE_SYS.H b/User/CH376_Driver/FILE_SYS.H new file mode 100644 index 0000000..79e0f62 --- /dev/null +++ b/User/CH376_Driver/FILE_SYS.H @@ -0,0 +1,170 @@ +/****************************** (C) COPYRIGHT 2011 YQDZ ************************** +* : FILE_SYS.H +* : ȫ +* FAEֳӦùʦ QQ:1027413631 +* 7*24Сʱֵ֧绰:15366066738 +* http://shop57138657.taobao.com/ +* : V1.0 +* : 2011/08/29 +* : CH376оƬ ļϵͳ V1.0 +* ṩļϵͳӳ,ṩ. +* ʹõӳע͵,ӶԼƬijROMռ +* RAMռ. +* ӳͨеıݲ,϶,Ϊ˽ +* ԼRAM,ҲԲοCH375ӳijͨͬһȫֱ/Ͻṹ +* CH376_CMD_DATA. +*********************************************************************************/ +/* name ָļ, ԰Ŀ¼, ·ָ, ܳȲ1+8+1+3+1ֽ */ +/* PathName ָȫ·Ķļ, Ŀ¼༶Ŀ¼·ָļ/Ŀ¼ */ +/* LongName ָļ, UNICODEС˳, 0ֽڽ, ʹóļӳȶȫֻGlobalBuf, ȲС64ֽ, ӳ */ + +/* NO_DEFAULT_CH376_INT ڽֹĬϵWait376Interruptӳ,ֹ,Ӧóжһͬӳ */ +/* DEF_INT_TIMEOUT ĬϵWait376Interruptӳеĵȴжϵijʱʱ/ѭֵ, 0򲻼鳬ʱһֱȴ */ +/* EN_DIR_CREATE ṩ½༶Ŀ¼ӳ,ĬDzṩ */ +/* EN_DISK_QUERY ṩѯʣռѯӳ,Ĭṩ */ +/* EN_SECTOR_ACCESS ṩΪλдļӳ,ĬDzṩ */ +/* EN_LONG_NAME ṩֳ֧ļӳ,ĬDzṩ */ + +#ifndef __FILE_SYS_H__ +#define __FILE_SYS_H__ + +#define ERR_USB_UNKNOWN 0xFA /* δ֪,Ӧ÷,Ӳ߳ */ + +#define STRUCT_OFFSET( s, m ) ( (u8)( & ((s *)0) -> m ) ) /* ȡṹԱƫƵַĺ */ +#ifdef EN_LONG_NAME +#ifndef LONG_NAME_BUF_LEN +#define LONG_NAME_BUF_LEN ( LONG_NAME_PER_DIR * 20 ) /* жijļ,СֵΪLONG_NAME_PER_DIR*1 */ +#endif +#endif + + +#define CH376_EN GPIO_SetBits(GPIOB,GPIO_Pin_12); +#define CH376_DIS GPIO_ResetBits(GPIOB,GPIO_Pin_12);GPIO_SetBits(GPIOD,GPIO_Pin_12); + +#define CH376_INT GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) +void CH376_PORT_INIT( void ); /* CH376ͨѶӿڳʼ */ +void xEndCH376Cmd( void ); /* SPI */ +void xWriteCH376Cmd( u8 mCmd ); /* CH376д */ +void xWriteCH376Data( u8 mData ); /* CH376д */ +u8 xReadCH376Data( void ); /* CH376 */ +u8 Query376Interrupt( void ); /* ѯCH376ж(INT#Ϊ͵ƽ) */ +u8 mInitCH376Host( void ); /* ʼCH376 */ + +u8 SPIx_ReadWriteByte(u8 TxData);//SPI߶дһֽ + +u8 CH376ReadBlock( u8* buf ); /* ӵǰ˵Ľջȡݿ,س */ + +u8 CH376WriteReqBlock( u8 * buf ); /* ڲָдݿ,س */ + +void CH376WriteHostBlock( u8 * buf, u8 len ); /* USB˵ķͻдݿ */ + +void CH376WriteOfsBlock( u8 * buf, u8 ofs, u8 len ); /* ڲָƫƵַдݿ */ + +void CH376SetFileName( u8 * name ); /* ýҪļļ */ + +u32 CH376Read32bitDat( void ); /* CH376оƬȡ32λݲ */ + +u8 CH376ReadVar8( u8 var ); /* CH376оƬڲ8λ */ + +void CH376WriteVar8( u8 var, u8 dat ); /* дCH376оƬڲ8λ */ + +u32 CH376ReadVar32( u8 var ); /* CH376оƬڲ32λ */ + +void CH376WriteVar32( u8 var, u32 dat ); /* дCH376оƬڲ32λ */ + +void CH376EndDirInfo( void ); /* ڵCH376DirInfoReadȡFAT_DIR_INFOṹ֮Ӧ֪ͨCH376 */ + +u32 CH376GetFileSize( void ); /* ȡǰļ */ + +u8 CH376GetDiskStatus( void ); /* ȡ̺ļϵͳĹ״̬ */ + +u8 CH376GetIntStatus( void ); /* ȡж״̬ȡж */ + +#ifndef NO_DEFAULT_CH376_INT +u8 Wait376Interrupt( void ); /* ȴCH376ж(INT#͵ƽ)ж״̬, ʱ򷵻ERR_USB_UNKNOWN */ +#endif + +u8 CH376SendCmdWaitInt( u8 mCmd ); /* ,ȴж */ + +u8 CH376SendCmdDatWaitInt( u8 mCmd, u8 mDat ); /* һֽݺ,ȴж */ + +u8 CH376DiskReqSense( void ); /* USB洢 */ + +u8 CH376DiskConnect( void ); /* UǷ,֧SD */ + +u8 CH376DiskMount( void ); /* ʼ̲ԴǷ */ + +u8 CH376FileOpen( u8 * name ); /* ڸĿ¼ߵǰĿ¼´ļĿ¼(ļ) */ + +u8 CH376FileCreate( u8 * name ); /* ڸĿ¼ߵǰĿ¼½ļ,ļѾôɾ */ + +u8 CH376DirCreate( u8 * name ); /* ڸĿ¼½Ŀ¼(ļ),Ŀ¼ѾôֱӴ */ + +u8 CH376SeparatePath( u8 * path ); /* ·зһļĿ¼(ļ),һļĿ¼ֽƫ */ + +u8 CH376FileOpenDir( u8 * PathName, u8 StopName ); /* 򿪶༶Ŀ¼µļĿ¼ϼĿ¼,ֶ֧༶Ŀ¼·,֧·ָ,·Ȳ255ַ */ +/* StopName ָһļĿ¼ */ + +u8 CH376FileOpenPath( u8 * PathName ); /* 򿪶༶Ŀ¼µļĿ¼(ļ),ֶ֧༶Ŀ¼·,֧·ָ,·Ȳ255ַ */ + +u8 CH376FileCreatePath( u8 * PathName ); /* ½༶Ŀ¼µļ,ֶ֧༶Ŀ¼·,֧·ָ,·Ȳ255ַ */ + +#ifdef EN_DIR_CREATE +u8 CH376DirCreatePath( u8 * PathName ); /* ½༶Ŀ¼µĿ¼(ļ),ֶ֧༶Ŀ¼·,֧·ָ,·Ȳ255ַ */ +#endif + +u8 CH376FileErase( u8 * PathName ); /* ɾļ,Ѿֱɾ,ļȴɾ,ֶ֧༶Ŀ¼· */ + +u8 CH376FileClose( u8 UpdateSz ); /* رյǰѾ򿪵ļĿ¼(ļ) */ + +u8 CH376DirInfoRead( void ); /* ȡǰļĿ¼Ϣ */ + +u8 CH376DirInfoSave( void ); /* ļĿ¼Ϣ */ + +u8 CH376ByteLocate( u32 offset ); /* ֽΪλƶǰļָ */ + +u8 CH376ByteRead( u8 * buf, UINT16 ReqCount, PUINT16 RealCount ); /* ֽΪλӵǰλöȡݿ */ + +u8 CH376ByteWrite( u8 * buf, UINT16 ReqCount, PUINT16 RealCount ); /* ֽΪλǰλдݿ */ + +u8 CH376DiskCapacity( u32 * DiskCap ); /* ѯ, */ + +u8 CH376DiskQuery( u32 * DiskFre ); /* ѯʣռϢ, */ + +u8 CH376SecLocate( u32 offset ); /* Ϊλƶǰļָ */ + +#ifdef EN_SECTOR_ACCESS + +u8 CH376DiskReadSec( u8 * buf, u32 iLbaStart, u8 iSectorCount ); /* U̶ȡݿ鵽,֧SD */ + +u8 CH376DiskWriteSec( u8 * buf, u32 iLbaStart, u8 iSectorCount ); /* еĶݿдU,֧SD */ + +u8 CH376SecRead( u8 * buf, u8 ReqCount, u8 * RealCount ); /* Ϊλӵǰλöȡݿ,֧SD */ + +u8 CH376SecWrite( u8 * buf, u8 ReqCount, u8 * RealCount ); /* Ϊλڵǰλдݿ,֧SD */ + +#endif + +#ifdef EN_LONG_NAME + +u8 CH376LongNameWrite( u8 * buf, UINT16 ReqCount ); /* ļרõֽдӳ */ + +u8 CH376CheckNameSum( u8 * DirName ); /* 㳤ļĶļ,ΪСָĹ̶11ֽڸʽ */ + +u8 CH376LocateInUpDir( u8 * PathName ); /* ϼĿ¼(ļ)ƶļָ뵽ǰļĿ¼Ϣڵ */ +/* ,˳㽫ǰļĿ¼ϢڵǰһLBAַдCH376ڲVAR_FAT_DIR_LBA(Ϊ˷ռļʱǰ,Ҫƶһ) */ +/* ʹȫֻGlobalBufǰ12ֽ */ + +u8 CH376GetLongName( u8 * PathName, u8 * LongName ); /* ɶļĿ¼(ļ)Ӧijļ */ +/* Ҫļ·PathName,ҪṩճļLongName(UNICODEС˱,˫0) */ +/* ʹȫֻGlobalBufǰ34ֽ,sizeof(GlobalBuf)>=sizeof(FAT_DIR_INFO)+2 */ + +u8 CH376CreateLongName( u8 * PathName, u8 * LongName ); /* ½гļļ,رļ󷵻,LongName·RAM */ +/* Ҫļ·PathName(ȲοFAT淶ɳļв),ҪUNICODEС˱˫0ijļLongName */ +/* ʹȫֻGlobalBufǰ64ֽ,sizeof(GlobalBuf)>=sizeof(FAT_DIR_INFO)*2 */ + +#endif + +#endif + + diff --git a/User/CH376_Driver/FILE_SYS.c b/User/CH376_Driver/FILE_SYS.c new file mode 100644 index 0000000..fcaec81 --- /dev/null +++ b/User/CH376_Driver/FILE_SYS.c @@ -0,0 +1,1899 @@ +/******************************************************** +* : CH376оƬ ļϵͳ V1.2 +* ṩļϵͳӳ,ṩ. +* ʹõӳע͵,ӶԼƬijROMռ +* RAMռ. +* ӳͨеıݲ,϶,Ϊ˽ +* ԼRAM,ҲԲοCH375ӳijͨͬһȫֱ/Ͻṹ +* CH376_CMD_DATA. +*********************************************************************************/ +/* name ָļ, ԰Ŀ¼, ·ָ, ܳȲ1+8+1+3+1ֽ */ +/* PathName ָȫ·Ķļ, Ŀ¼༶Ŀ¼·ָļ/Ŀ¼ */ +/* LongName ָļ, UNICODEС˳, 0ֽڽ, ʹóļӳȶȫֻGlobalBuf, ȲС64ֽ, ӳ */ + +/* NO_DEFAULT_CH376_INT ڽֹĬϵWait376Interruptӳ,ֹ,Ӧóжһͬӳ */ +/* DEF_INT_TIMEOUT ĬϵWait376Interruptӳеĵȴжϵijʱʱ/ѭֵ, 0򲻼鳬ʱһֱȴ */ +/* EN_DIR_CREATE ṩ½༶Ŀ¼ӳ,ĬDzṩ */ +/* EN_DISK_QUERY ṩѯʣռѯӳ,ĬDzṩ */ +/* EN_SECTOR_ACCESS ṩΪλдļӳ,ĬDzṩ */ +/* EN_LONG_NAME ṩֳ֧ļӳ,ĬDzṩ */ +/* DEF_IC_V43_U ȥֵ֧Ͱ汾ij,֧V4.3ϰ汾CH376оƬ,Ĭֵ֧Ͱ汾 */ + +#include "config.h" //ȫ +/******************************************************************************* +* : CH376ReadBlock +* : ӵǰ˵Ľջȡݿ,. +* : u8 * buf: +* ָⲿջ. +* : س. +*******************************************************************************/ +//void delay_1us(void) +//{ +// unsigned char i; +// for(i=0;i<20;i++) +// { +// __nop(); +// __nop(); +// __nop(); +// __nop(); +// __nop(); +// __nop(); +// __nop(); +// __nop(); +// __nop(); +// __nop(); +// } +// +// +//} +//void delay_us(unsigned int Counter) +//{ +// while(Counter--) +// { +// delay_1us(); +// } +//} + +void SPI2_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + SPI_InitTypeDef SPI_InitStructure; + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB ,ENABLE); + + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + //GPIO_InitStructure.GPIO_OType = GPIO_i; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2); + GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2); + GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2); + + /*!< Configure SPI1 pins: SCK MOSI*/ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 |GPIO_Pin_14| GPIO_Pin_15; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + SPI_I2S_DeInit(SPI2); + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//??? + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//8????? + SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//?????SCK?1 + SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//??????2??????? + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS???? + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;//??? + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//???? + SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC??? + SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//???? + SPI_Init(SPI2, &SPI_InitStructure); + SPI_Cmd(SPI2, ENABLE); +} +u8 SPI2_ReadWriteByte(u8 TxData) +{ + while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); + SPI_I2S_SendData(SPI2, TxData); + while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); + return SPI_I2S_ReceiveData(SPI2); +} + +/******************************************************************************* +SPI8λ. * : u8 d:Ҫ͵. +*******************************************************************************/ +void Spi376OutByte( u8 d ) +{ + SPI2_ReadWriteByte(d); +} + +/******************************************************************************* +* : SPI8λ. u8 d:յ. +*******************************************************************************/ +u8 Spi376InByte( void ) +{ +/* ӲSPIӿ,ӦȲѯSPI״̬ĴԵȴSPIֽڴ,ȻSPIݼĴ */ + while((SPI2->SR&1<<0)==0); //RXEN=0 ջΪ + return SPI2->DR; //յ +} + +/******************************************************************************* +* : CH376д . +* : u8 mCmd:Ҫ͵. +*******************************************************************************/ +void xWriteCH376Cmd( u8 mCmd ) +{ + CH376_EN; /* ֹ֮ǰδͨxEndCH376CmdֹSPIƬѡ */ + delay_us(3); +/* ˫I/OģSPIӿ,ôȷѾSPI_SCS,SPI_SCK,SPI_SDIΪ +* ,SPI_SDOΪ뷽 */ + CH376_DIS; /* SPIƬѡЧ */ + Spi376OutByte( mCmd ); /* */ + delay_us(3); /* ʱ1.5uSȷдڴ1.5uS,һе״̬ѯ */ +} + +/******************************************************************************* +* : CH376д . +* : u8 mData: +* Ҫ͵. +*******************************************************************************/ +void xWriteCH376Data( u8 mData ) +{ + Spi376OutByte( mData ); + delay_us(1); /* ȷдڴ0.6uS */ +} + +/******************************************************************************* +* : xReadCH376Data +* : CH376. +*******************************************************************************/ +u8 xReadCH376Data( void ) +{ + u8 i; + delay_us(1); + i = SPI2_ReadWriteByte( 0xFF ); + return( i ); +} + +/******************************************************************************* +* : ѯCH376ж(INT#͵ƽ). +* : FALSE:ж. TRUE:ж. +*******************************************************************************/ +u8 Query376Interrupt( void ) +{ + u8 i; + i = CH376_INT; /* CH376жֱӲѯж */ + return( i ); +} + +/******************************************************************************* +* : ʼCH376. +* : FALSE:ж. TRUE:ж. +*******************************************************************************/ +u8 mInitCH376Host( void ) +{ + u8 res; + //delay_us(200); + + SPI2_Init(); /* ӿӲʼ */ + xWriteCH376Cmd( CMD11_CHECK_EXIST ); /* ԵƬCH376֮ͨѶӿ */ + xWriteCH376Data( 0x55 ); + res = xReadCH376Data( ); + CH376_DIS; + if ( res != 0xAA ) return( ERR_USB_UNKNOWN ); /* ͨѶӿڲ,ԭ:ӿ쳣,豸Ӱ(ƬѡΨһ),ڲ,һֱڸλ,񲻹 */ + xWriteCH376Cmd( CMD11_SET_USB_MODE ); /* 豸USBģʽ */ + xWriteCH376Data( 0x06 ); //06H=õʽԶSOF 03CD + delay_us( 20 ); + res = xReadCH376Data( ); + CH376_EN; + + if ( res == CMD_RET_SUCCESS ) //RES=51 ɹ + { + return( USB_INT_SUCCESS ); //USBߴɹ + } + else + { + return( ERR_USB_UNKNOWN );/* ģʽ */ + } +} + +u8 CH376ReadBlock( u8 * buf ) +{ + u8 s, l; + + + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + s = l = xReadCH376Data( ); /* ݳ */ + if ( l ) + { + do + { + *buf = xReadCH376Data( ); + buf ++; + } while ( -- l ); + } + CH376_EN; + return( s ); +} + +/******************************************************************************* +* : CH376WriteReqBlock +* : ڲָдݿ,س. +* : u8 * buf: +* ָͻ. +* : u8 sݳ. +*******************************************************************************/ +u8 CH376WriteReqBlock( u8 * buf ) +{ + u8 s, l; + + xWriteCH376Cmd( CMD01_WR_REQ_DATA ); /* ڲָдݿ */ + s = l = xReadCH376Data( ); /* ݳ */ + if ( l ) + { + do + { + xWriteCH376Data( *buf ); + buf ++; + } while ( -- l ); + } + CH376_EN; + return( s ); +} + +/******************************************************************************* +* : CH376WriteHostBlock +* : USB˵ķͻдݿ. +* : u8 * buf +* ָݻ. +* u8 len: +* ݳ. +* : . +*******************************************************************************/ +void CH376WriteHostBlock( u8 * buf, u8 len ) +{ + xWriteCH376Cmd( CMD10_WR_HOST_DATA ); + xWriteCH376Data( len ); /* ݳ */ + if ( len ) + { + do + { + xWriteCH376Data( *buf ); + buf ++; + } while ( -- len ); + } + CH376_EN; +} + +/******************************************************************************* +* : CH376WriteOfsBlock +* : ڲָƫƵַдݿ. +* : u8 * buf +* ָݻ. +* u8 ofs: +* ƫƵַ. +* u8 len: +* ݳ. +* : . +*******************************************************************************/ +void CH376WriteOfsBlock( u8 * buf, u8 ofs, u8 len ) +{ + xWriteCH376Cmd( CMD20_WR_OFS_DATA ); + xWriteCH376Data( ofs ); /* ƫƵַ */ + xWriteCH376Data( len ); /* ݳ */ + if ( len ) + { + do + { + xWriteCH376Data( *buf ); + buf ++; + } while ( -- len ); + } + CH376_EN; +} + +/******************************************************************************* +* : CH376SetFileName +* : ýҪļļ . +* : u8 * name +* ָļ. +* : . +*******************************************************************************/ +void CH376SetFileName( u8 * name ) +{ + u8 c; + +#ifndef DEF_IC_V43_U /* Ĭֵ֧Ͱ汾 */ + u8 s; + + xWriteCH376Cmd( CMD01_GET_IC_VER ); /* ȡоƬ汾 */ + if ( xReadCH376Data( ) < 0x43 ) + { + if ( CH376ReadVar8( VAR_DISK_STATUS ) < DEF_DISK_READY ) + { + xWriteCH376Cmd( CMD10_SET_FILE_NAME ); + xWriteCH376Data( 0 ); + s = CH376SendCmdWaitInt( CMD0H_FILE_OPEN ); + if ( s == USB_INT_SUCCESS ) + { + s = CH376ReadVar8( 0xCF ); + if ( s ) + { + CH376WriteVar32( 0x4C, CH376ReadVar32( 0x4C ) + ( (UINT16)s << 8 ) ); + CH376WriteVar32( 0x50, CH376ReadVar32( 0x50 ) + ( (UINT16)s << 8 ) ); + CH376WriteVar32( 0x70, 0 ); + } + } + } + } +#endif + xWriteCH376Cmd( CMD10_SET_FILE_NAME ); + c = *name; + xWriteCH376Data( c ); + while ( c ) + { + name ++; + c = *name; + if ( c == DEF_SEPAR_CHAR1 || c == DEF_SEPAR_CHAR2 ) + { + c = 0; /* ǿнļֹ */ + } + xWriteCH376Data( c ); + } + CH376_EN; +} + +/******************************************************************************* +* : CH376Read32bitDat +* : CH376оƬȡ32λݲ. +* : . +* : 32λ. +*******************************************************************************/ +u32 CH376Read32bitDat( void ) +{ + u8 c0, c1, c2, c3; + + c0 = xReadCH376Data( ); + c1 = xReadCH376Data( ); + c2 = xReadCH376Data( ); + c3 = xReadCH376Data( ); + CH376_EN; + return( c0 | (UINT16)c1 << 8 | (u32)c2 << 16 | (u32)c3 << 24 ); +} + +/******************************************************************************* +* : CH376ReadVar8 +* : CH376оƬڲ8λ. +* : . +* : 8λ. +*******************************************************************************/ +u8 CH376ReadVar8( u8 var ) +{ + u8 c0; + + xWriteCH376Cmd( CMD11_READ_VAR8 ); /* ȡָ8λļϵͳ */ + xWriteCH376Data( var ); + c0 = xReadCH376Data( ); + CH376_EN; + return( c0 ); +} + +/******************************************************************************* +* : CH376WriteVar8 +* : дCH376оƬڲ8λ. +* : u8 var +* ַ. +* u8 dat: + . +* : . +*******************************************************************************/ +void CH376WriteVar8( u8 var, u8 dat ) +{ + xWriteCH376Cmd( CMD20_WRITE_VAR8 ); /* ָ8λļϵͳ */ + xWriteCH376Data( var ); + xWriteCH376Data( dat ); + CH376_EN; +} + +/******************************************************************************* +* : CH376ReadVar8 +* : CH376оƬڲ32λ. +* : u8 var +* ַ. +* : 32λ. +*******************************************************************************/ +u32 CH376ReadVar32( u8 var ) +{ + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( var ); + return( CH376Read32bitDat( ) ); /* CH376оƬȡ32λݲ */ +} + +/******************************************************************************* +* : CH376WriteVar32 +* : дCH376оƬڲ32λ. +* : u8 var +* ַ. +* u32 dat: +* . +* : . +*******************************************************************************/ +void CH376WriteVar32( u8 var, u32 dat ) +{ + xWriteCH376Cmd( CMD50_WRITE_VAR32 ); + xWriteCH376Data( var ); + xWriteCH376Data( (u8)dat ); + xWriteCH376Data( (u8)( (UINT16)dat >> 8 ) ); + xWriteCH376Data( (u8)( dat >> 16 ) ); + xWriteCH376Data( (u8)( dat >> 24 ) ); + CH376_EN; +} + +/******************************************************************************* +* : CH376EndDirInfo +* : ڵCH376DirInfoReadȡFAT_DIR_INFOṹ֮Ӧ֪ͨCH376. +* : . +* : . +*******************************************************************************/ +void CH376EndDirInfo( void ) +{ + CH376WriteVar8( 0x0D, 0x00 ); +} + +/******************************************************************************* +* : CH376GetFileSize +* : ȡǰļ. +* : . +* : ļ. +*******************************************************************************/ +u32 CH376GetFileSize( void ) +{ + return( CH376ReadVar32( VAR_FILE_SIZE ) ); +} + +/******************************************************************************* +* : CH376GetDiskStatus +* : ȡ̺ļϵͳĹ״̬. +* : . +* : ״̬. +*******************************************************************************/ +u8 CH376GetDiskStatus( void ) +{ + return( CH376ReadVar8( VAR_DISK_STATUS ) ); +} + +/******************************************************************************* +* : CH376GetIntStatus +* : ȡж״̬ȡж. +* : . +* : u8 s: +* ж״̬. +*******************************************************************************/ +u8 CH376GetIntStatus( void ) +{ + u8 s; + + xWriteCH376Cmd( CMD01_GET_STATUS ); + s = xReadCH376Data( ); + CH376_EN; + return( s ); +} + +/******************************************************************************* +* : Wait376Interrupt +* : ȴCH376ж(INT#͵ƽ)ж״̬, ʱ򷵻 +* ERR_USB_UNKNOWN. +* : . +* : ж״̬. +*******************************************************************************/ +#ifndef NO_DEFAULT_CH376_INT +u8 Wait376Interrupt( void ) +{ +#ifdef DEF_INT_TIMEOUT /* Ƿ˳ʱʱ */ +#if DEF_INT_TIMEOUT < 1 /* ûж */ + while ( Query376Interrupt( ) == FALSE ); /* һֱж */ + return( CH376GetIntStatus( ) ); /* ⵽ж */ +#else /* ˳ʱʱ */ + u32 i; + + for ( i = 0; i < DEF_INT_TIMEOUT; i ++ ) /* ֹʱ */ + { + if ( Query376Interrupt( ) ) + { + return( CH376GetIntStatus( ) ); /* ⵽ж */ + } + /* ڵȴCH376жϵĹ,ЩҪʱ */ + } + return( ERR_USB_UNKNOWN ); /* Ӧ÷ */ +#endif +#else + u32 i; + + for ( i = 0; i < 5000000; i ++ ) /* ֹʱ,Ĭϵijʱʱ,뵥ƬƵй */ + { + if ( Query376Interrupt( ) == 0 ) + { + return( CH376GetIntStatus( ) ); /* ⵽ж */ + } + /* ڵȴCH376жϵĹ,ЩҪʱ */ + } + return( ERR_USB_UNKNOWN ); /* Ӧ÷ */ +#endif +} +#endif + +/******************************************************************************* +* : CH376SendCmdWaitInt +* : ,ȴж. +* : u8 mCmd: +* . +* : ж״̬. +*******************************************************************************/ +u8 CH376SendCmdWaitInt( u8 mCmd ) +{ + xWriteCH376Cmd( mCmd ); + CH376_EN; + return( Wait376Interrupt( ) ); +} + +/******************************************************************************* +* : CH376SendCmdDatWaitInt +* : һֽݺ,ȴж. +* : . +* : ж״̬. +*******************************************************************************/ +u8 CH376SendCmdDatWaitInt( u8 mCmd, u8 mDat ) +{ + xWriteCH376Cmd( mCmd ); + xWriteCH376Data( mDat ); + CH376_EN; + return( Wait376Interrupt( ) ); +} + +/******************************************************************************* +* : CH376DiskReqSense +* : USB洢. +* : . +* : u8 s: +* ״̬. +*******************************************************************************/ +u8 CH376DiskReqSense( void ) +{ + u8 s; + + delay_us( 5 ); + s = CH376SendCmdWaitInt( CMD0H_DISK_R_SENSE ); + delay_us( 5 ); + return( s ); +} + +/******************************************************************************* +* : CH376DiskConnect +* : UǷ,֧SD. +* : . +* : UǷ״̬. +*******************************************************************************/ +u8 CH376DiskConnect( void ) +{ + if ( Query376Interrupt( ) ) + { + CH376GetIntStatus( ); /* ⵽ж */ + } + return( CH376SendCmdWaitInt( CMD0H_DISK_CONNECT ) ); /* Ƿ */ +} + +/******************************************************************************* +* : CH376DiskMount +* : ʼ̲ԴǷ. +* : . +* : ж״̬. +*******************************************************************************/ +u8 CH376DiskMount( void ) +{ + return( CH376SendCmdWaitInt( CMD0H_DISK_MOUNT ) ); /* ʼ̲ԴǷ */ +} + +/******************************************************************************* +* : CH376FileOpen +* : ڸĿ¼ߵǰĿ¼´ļĿ¼(ļ). +* : . +* : ж״̬. +*******************************************************************************/ +u8 CH376FileOpen( u8 * name ) +{ + CH376SetFileName( name ); /* ýҪļļ */ +#ifndef DEF_IC_V43_U + if ( name[0] == DEF_SEPAR_CHAR1 || name[0] == DEF_SEPAR_CHAR2 ) + { + CH376WriteVar32( VAR_CURRENT_CLUST, 0 ); + } +#endif + return( CH376SendCmdWaitInt( CMD0H_FILE_OPEN ) ); +} + +/******************************************************************************* +* : CH376FileCreate +* : ڸĿ¼ߵǰĿ¼½ļ,ļѾôɾ. +* : . +* : ж״̬. +*******************************************************************************/ +u8 CH376FileCreate( u8 * name ) +{ + if ( name ) + { + CH376SetFileName( name ); /* ýҪļļ */ + } + return( CH376SendCmdWaitInt( CMD0H_FILE_CREATE ) ); +} + +/******************************************************************************* +* : CH376DirCreate +* : ڸĿ¼½Ŀ¼(ļ),Ŀ¼ѾôֱӴ. +* : . +* : ж״̬. +*******************************************************************************/ +u8 CH376DirCreate( u8 * name ) +{ + CH376SetFileName( name ); /* ýҪļļ */ +#ifndef DEF_IC_V43_U + if ( name[0] == DEF_SEPAR_CHAR1 || name[0] == DEF_SEPAR_CHAR2 ) + { + CH376WriteVar32( VAR_CURRENT_CLUST, 0 ); + } +#endif + return( CH376SendCmdWaitInt( CMD0H_DIR_CREATE ) ); +} + +/******************************************************************************* +* : CH376SeparatePath +* : ·зһļĿ¼(ļ) +* : u8 * path: +* ָ·. +* : һļĿ¼ֽƫ. +*******************************************************************************/ +u8 CH376SeparatePath( u8 * path ) +{ + u8 * pName; + + for ( pName = path; *pName != 0; ++ pName ); /* ļַλ */ + while ( *pName != DEF_SEPAR_CHAR1 && *pName != DEF_SEPAR_CHAR2 && pName != path ) + { + pName --; /* һ·ָ */ + } + if ( pName != path ) + { + pName ++; /* ҵ·ָ,޸ָĿļһļ,ǰĶ༶Ŀ¼·ָ */ + } + return( pName - path ); +} + +/******************************************************************************* +* : CH376FileOpenDir +* : 򿪶༶Ŀ¼µļĿ¼ϼĿ¼,ֶ֧༶Ŀ¼·, +* ֧·ָ,·Ȳ255ַ +* : u8 * path: +* ָ·. +* u8 StopName: +* ָһļĿ¼ +* : һļĿ¼ֽƫ. +*******************************************************************************/ +u8 CH376FileOpenDir( u8 * PathName, u8 StopName ) +{ + u8 i, s; + + s = 0; + i = 1; /* пܵĸĿ¼ */ + while ( 1 ) + { + while ( PathName[i] != DEF_SEPAR_CHAR1 && PathName[i] != DEF_SEPAR_CHAR2 && PathName[i] != 0 ) + { + ++ i; /* һ·ָ· */ + } + + if ( PathName[i] ) + { + i ++; /* ҵ·ָ,޸ָĿļһļ */ + } + else + { + i = 0; /* · */ + } + + s = CH376FileOpen( &PathName[s] ); /* ļĿ¼ */ + + if ( i && i != StopName ) /* ·δ */ + { + if ( s != ERR_OPEN_DIR ) /* Ϊ𼶴,δ·,,dzɹĿ¼,ô˵ */ + { + if ( s == USB_INT_SUCCESS ) + { + return( ERR_FOUND_NAME ); /* м·Ŀ¼,ļ */ + } + else if ( s == ERR_MISS_FILE ) + { + return( ERR_MISS_DIR ); /* м·ijĿ¼ûҵ,Ŀ¼ƴ */ + } + else + { + return( s ); /* */ + } + } + s = i; /* һĿ¼ʼ */ + } + else + { + return( s ); /* ·,USB_INT_SUCCESSΪɹļ,ERR_OPEN_DIRΪɹĿ¼(ļ),Ϊ */ + } + } +} + +/******************************************************************************* +* : CH376FileOpenPath +* : 򿪶༶Ŀ¼µļĿ¼(ļ),ֶ֧༶Ŀ¼·, +* ֧·ָ,·Ȳ255ַ +* : u8 * path: +* ָ·. +* : һļĿ¼ֽƫ. +*******************************************************************************/ +u8 CH376FileOpenPath( u8 * PathName ) +{ + return( CH376FileOpenDir( PathName, 0xFF ) ); +} + +/******************************************************************************* +* : CH376FileCreatePath +* : ½༶Ŀ¼µĿ¼(ļ),ֶ֧༶Ŀ¼·,֧· +* ָ,·Ȳ255ַ. +* : u8 * path: +* ָ·. +* : ж״̬. +*******************************************************************************/ +u8 CH376FileCreatePath( u8 * PathName ) +{ + u8 s; + u8 Name; + + Name = CH376SeparatePath( PathName ); /* ·зһļ,һļƫ */ + if ( Name ) /* Ƕ༶Ŀ¼ */ + { + s = CH376FileOpenDir( PathName, Name ); /* 򿪶༶Ŀ¼µһĿ¼,½ļϼĿ¼ */ + if ( s != ERR_OPEN_DIR ) /* ΪǴϼĿ¼,,dzɹĿ¼,ô˵ */ + { + if ( s == USB_INT_SUCCESS ) + { + return( ERR_FOUND_NAME ); /* м·Ŀ¼,ļ */ + } + else if ( s == ERR_MISS_FILE ) + { + return( ERR_MISS_DIR ); /* м·ijĿ¼ûҵ,Ŀ¼ƴ */ + } + else + { + return( s ); /* */ + } + } + } + return( CH376FileCreate( &PathName[Name] ) ); /* ڸĿ¼ߵǰĿ¼½ļ */ +} + +/******************************************************************************* +* : CH376FileCreatePath +* : ½༶Ŀ¼µļ,ֶ֧༶Ŀ¼·,֧·ָ,· +* Ȳ255ַ +* : u8 * path: ָ·. +* : ״̬. +*******************************************************************************/ +#ifdef EN_DIR_CREATE +u8 CH376DirCreatePath( u8 * PathName ) +{ + u8 s; + u8 Name; + u8 ClustBuf[4]; + + Name = CH376SeparatePath( PathName ); /* ·зһĿ¼,һļƫ */ + if ( Name ) /* Ƕ༶Ŀ¼ */ + { + s = CH376FileOpenDir( PathName, Name ); /* 򿪶༶Ŀ¼µһĿ¼,½Ŀ¼ϼĿ¼ */ + if ( s != ERR_OPEN_DIR ) /* ΪǴϼĿ¼,,dzɹĿ¼,ô˵ */ + { + if ( s == USB_INT_SUCCESS ) + { + return( ERR_FOUND_NAME ); /* м·Ŀ¼,ļ */ + } + else if ( s == ERR_MISS_FILE ) + { + return( ERR_MISS_DIR ); /* м·ijĿ¼ûҵ,Ŀ¼ƴ */ + } + else + { + return( s ); /* */ + } + } + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( VAR_START_CLUSTER ); /* ϼĿ¼ʼغ */ + + for ( s = 0; s != 4; s ++ ) + { + ClustBuf[ s ] = xReadCH376Data( ); + } + + CH376_EN; + + s = CH376DirCreate( &PathName[Name] ); /* ڵǰĿ¼½Ŀ¼ */ + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + + s = CH376ByteLocate( sizeof(FAT_DIR_INFO) + STRUCT_OFFSET( FAT_DIR_INFO, DIR_FstClusHI ) ); /* ƶļָ */ + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + + s = CH376ByteWrite( &ClustBuf[2], 2, NULL ); /* дϼĿ¼ʼغŵĸ16λ */ + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + + s = CH376ByteLocate( sizeof(FAT_DIR_INFO) + STRUCT_OFFSET( FAT_DIR_INFO, DIR_FstClusLO ) ); /* ƶļָ */ + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + + s = CH376ByteWrite( ClustBuf, 2, NULL ); /* дϼĿ¼ʼغŵĵ16λ */ + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + + s = CH376ByteLocate( 0 ); /* ƶļָ,ָĿ¼ͷλ */ + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + } + else /* Ƕ༶Ŀ¼ */ + { + if ( PathName[0] == DEF_SEPAR_CHAR1 || PathName[0] == DEF_SEPAR_CHAR2 ) + { + return( CH376DirCreate( PathName ) ); /* ڸĿ¼½Ŀ¼ */ + } + else + { + return( ERR_MISS_DIR ); /* ṩ·ʵڵǰĿ¼½Ŀ¼ */ + } + } +} +#endif + +/******************************************************************************* +* : CH376FileErase +* : ɾļ,Ѿֱɾ,ļȴɾ, +* ֶ֧༶Ŀ¼·. +* : u8 * path: +* ָ·. +* : ж״̬. +*******************************************************************************/ +u8 CH376FileErase( u8 * PathName ) +{ + u8 s; + + if ( PathName ) /* ļδ */ + { + for ( s = 1; PathName[s] != DEF_SEPAR_CHAR1 && PathName[s] != DEF_SEPAR_CHAR2 && PathName[s] != 0; ++ s ); /* һ·ָ· */ + if ( PathName[s] ) /* ·ָ,Ƕ༶Ŀ¼µļĿ¼ */ + { + s = CH376FileOpenPath( PathName ); /* 򿪶༶Ŀ¼µļĿ¼ */ + if ( s != USB_INT_SUCCESS && s != ERR_OPEN_DIR ) + { + return( s ); /* */ + } + } + else + { + CH376SetFileName( PathName ); /* û·ָ,ǸĿ¼ߵǰĿ¼µļĿ¼,ýҪļļ */ + } + } + return( CH376SendCmdWaitInt( CMD0H_FILE_ERASE ) ); +} + +/******************************************************************************* +* : CH376FileClose +* : رյǰѾ򿪵ļĿ¼(ļ) +* : u8 * UpdateSz: +* Ƿļ. +* : ж״̬. +*******************************************************************************/ +u8 CH376FileClose( u8 UpdateSz ) +{ + return( CH376SendCmdDatWaitInt( CMD1H_FILE_CLOSE, UpdateSz ) ); +} + +/******************************************************************************* +* : CH376DirInfoRead +* : ȡǰļĿ¼Ϣ +* : . +* : ж״̬. +*******************************************************************************/ +u8 CH376DirInfoRead( void ) +{ + return( CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, 0xFF ) ); +} + +/******************************************************************************* +* : CH376DirInfoSave +* : ļĿ¼Ϣ +* : . +* : ж״̬. +*******************************************************************************/ +u8 CH376DirInfoSave( void ) +{ + return( CH376SendCmdWaitInt( CMD0H_DIR_INFO_SAVE ) ); +} + +/******************************************************************************* +* : CH376ByteLocate +* : ֽΪλƶǰļָ +* : u32 offset: +* ָƫƵַ. +* : ж״̬. +*******************************************************************************/ +u8 CH376ByteLocate( u32 offset ) +{ + xWriteCH376Cmd( CMD4H_BYTE_LOCATE ); + xWriteCH376Data( (u8)offset ); + xWriteCH376Data( (u8)((UINT16)offset>>8) ); + xWriteCH376Data( (u8)(offset>>16) ); + xWriteCH376Data( (u8)(offset>>24) ); + CH376_EN; + return( Wait376Interrupt( ) ); +} + +/******************************************************************************* +* : CH376ByteRead +* : ֽΪλӵǰλöȡݿ +* : u8 * buf: +* ָݻ. +* UINT16 ReqCount +* ȡֽ. +* PUINT16 RealCount: +* ʵʶȡֽ. +* : ж״̬. +*******************************************************************************/ +u8 CH376ByteRead( u8 * buf, UINT16 ReqCount, PUINT16 RealCount ) +{ + u8 s; + + xWriteCH376Cmd( CMD2H_BYTE_READ ); + xWriteCH376Data( (u8)ReqCount ); + xWriteCH376Data( (u8)(ReqCount>>8) ); + CH376_EN; +// if ( RealCount ) +// { +// *RealCount = 0; +// } + + while ( 1 ) + { + s = Wait376Interrupt( ); + if ( s == USB_INT_DISK_READ ) /* ݶ */ + { + s = CH376ReadBlock( buf ); /* ӵǰ˵Ľջȡݿ,س */ + xWriteCH376Cmd( CMD0H_BYTE_RD_GO ); /* */ + CH376_EN; + buf += s; + if ( RealCount ) + { + *RealCount += s; + } + } + else + { + return( s ); /* */ + } + } +} + +/******************************************************************************* +* : CH376ByteWrite +* : ֽΪλǰλдݿ. +* : u8 * buf: +* ָⲿ. +* UINT16 ReqCount +* дֽ. +* PUINT16 RealCount: +* ʵдֽ. +* : ж״̬. +*******************************************************************************/ +u8 CH376ByteWrite( u8 * buf, UINT16 ReqCount, PUINT16 RealCount ) +{ + u8 s; + + xWriteCH376Cmd( CMD2H_BYTE_WRITE ); + xWriteCH376Data( (u8)ReqCount ); + xWriteCH376Data( (u8)(ReqCount>>8) ); + CH376_EN; + if ( RealCount ) + { + *RealCount = 0; + } + + while ( 1 ) + { + s = Wait376Interrupt( ); + if ( s == USB_INT_DISK_WRITE ) + { + s = CH376WriteReqBlock( buf ); /* ڲָдݿ,س */ + xWriteCH376Cmd( CMD0H_BYTE_WR_GO ); + CH376_EN; + buf += s; + if ( RealCount ) *RealCount += s; + } + else + { + return( s ); /* */ + } + } +} + +/******************************************************************************* +* : CH376DiskCapacity +* : ѯ,. +* : u32 * DiskCap: +* . +* : ж״̬. +*******************************************************************************/ +u8 CH376DiskCapacity( u32 * DiskCap ) +{ + u8 s; + + s = CH376SendCmdWaitInt( CMD0H_DISK_CAPACITY ); + if ( s == USB_INT_SUCCESS ) + { /* οCH376INC.HļCH376_CMD_DATAṹDiskCapacity */ + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + xReadCH376Data( ); /* sizeof(CH376_CMD_DATA.DiskCapacity) */ + *DiskCap = CH376Read32bitDat( ); /* CH376_CMD_DATA.DiskCapacity.mDiskSizeSec,CH376оƬȡ32λݲ */ + } + else + { + *DiskCap = 0; + } + return( s ); +} + +/******************************************************************************* +* : CH376DiskQuery +* : ѯʣռϢ,. +* : u32 * DiskFre: +* ǰ߼̵ʣ. +* : ж״̬. +*******************************************************************************/ +u8 CH376DiskQuery( u32 * DiskFre ) +{ + u8 s; + u8 c0, c1, c2, c3; + +#ifndef DEF_IC_V43_U + xWriteCH376Cmd( CMD01_GET_IC_VER ); /* ȡоƬ̼汾 */ + if ( xReadCH376Data( ) < 0x43 ) + { + if ( CH376ReadVar8( VAR_DISK_STATUS ) >= DEF_DISK_READY ) /* ȡļģʽµĴ̼ļ״̬ǷѾܹ֧ */ + { + CH376WriteVar8( VAR_DISK_STATUS, DEF_DISK_MOUNTED ); + } + } +#endif + + s = CH376SendCmdWaitInt( CMD0H_DISK_QUERY ); + if ( s == USB_INT_SUCCESS ) + { /* οCH376INC.HļCH376_CMD_DATAṹDiskQuery */ + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + xReadCH376Data( ); /* sizeof(CH376_CMD_DATA.DiskQuery) */ + xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mTotalSector */ + xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + c0 = xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mFreeSector */ + c1 = xReadCH376Data( ); + c2 = xReadCH376Data( ); + c3 = xReadCH376Data( ); + *DiskFre = c0 | (UINT16)c1 << 8 | (u32)c2 << 16 | (u32)c3 << 24; + xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mDiskFat */ + CH376_EN; + } + else + { + *DiskFre = 0; + } + + return( s ); +} + +/******************************************************************************* +* : CH376SecLocate +* : Ϊλƶǰļָ. +* : u32 offset: +* Ҫƶ. +* : ж״̬. +*******************************************************************************/ +u8 CH376SecLocate( u32 offset ) +{ + xWriteCH376Cmd( CMD4H_SEC_LOCATE ); + xWriteCH376Data( (u8)offset ); + xWriteCH376Data( (u8)((UINT16)offset>>8) ); + xWriteCH376Data( (u8)(offset>>16) ); + xWriteCH376Data( 0 ); /* ļߴ */ + CH376_EN; + return( Wait376Interrupt( ) ); +} + +/******************************************************************************* +* : CH376DiskReadSec +* : U̶ȡݿ鵽,֧SD. +* : u8 * buf: +* ָⲿݻ. +* u32 iLbaStart +* iLbaStart ׼ȡʼ. +* u8 iSectorCount: +* iSectorCount ׼ȡ +* : ж״̬. +*******************************************************************************/ +#ifdef EN_SECTOR_ACCESS +u8 CH376DiskReadSec( u8 * buf, u32 iLbaStart, u8 iSectorCount ) +{ + u8 s, err; + UINT16 mBlockCount; + + for ( err = 0; err != 3; ++ err ) /* */ + { + xWriteCH376Cmd( CMD5H_DISK_READ ); /* USB洢 */ + xWriteCH376Data( (u8)iLbaStart ); /* LBA8λ */ + xWriteCH376Data( (u8)( (UINT16)iLbaStart >> 8 ) ); + xWriteCH376Data( (u8)( iLbaStart >> 16 ) ); + xWriteCH376Data( (u8)( iLbaStart >> 24 ) ); /* LBA8λ */ + xWriteCH376Data( iSectorCount ); /* */ + CH376_EN; + for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) /* ݿ */ + { + s = Wait376Interrupt( ); /* ȴжϲȡ״̬ */ + if ( s == USB_INT_DISK_READ ) /* USB洢ݿ,ݶ */ + { + s = CH376ReadBlock( buf ); /* ӵǰ˵Ľջȡݿ,س */ + xWriteCH376Cmd( CMD0H_DISK_RD_GO ); /* ִUSB洢Ķ */ + CH376_EN; + buf += s; + } + else + { + break; /* ش״̬ */ + } + } + + if ( mBlockCount == 0 ) + { + s = Wait376Interrupt( ); /* ȴжϲȡ״̬ */ + if ( s == USB_INT_SUCCESS ) + { + return( USB_INT_SUCCESS ); /* ɹ */ + } + } + + if ( s == USB_INT_DISCONNECT ) + { + return( s ); /* U̱Ƴ */ + } + + CH376DiskReqSense( ); /* USB洢 */ + } + + return( s ); /* ʧ */ +} + +/******************************************************************************* +* : CH376DiskWriteSec +* : еĶݿдU,֧SD. +* : u8 * buf: +* ָⲿݻ. +* u32 iLbaStart +* дʼ. +* u8 iSectorCount: +* д. +* : ж״̬. +*******************************************************************************/ +u8 CH376DiskWriteSec( u8 * buf, u32 iLbaStart, u8 iSectorCount ) +{ + u8 s, err; + UINT16 mBlockCount; + + for ( err = 0; err != 3; ++ err ) /* */ + { + xWriteCH376Cmd( CMD5H_DISK_WRITE ); /* USB洢д */ + xWriteCH376Data( (u8)iLbaStart ); /* LBA8λ */ + xWriteCH376Data( (u8)( (UINT16)iLbaStart >> 8 ) ); + xWriteCH376Data( (u8)( iLbaStart >> 16 ) ); + xWriteCH376Data( (u8)( iLbaStart >> 24 ) ); /* LBA8λ */ + xWriteCH376Data( iSectorCount ); /* */ + CH376_EN; + for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) /* ݿ */ + { + s = Wait376Interrupt( ); /* ȴжϲȡ״̬ */ + if ( s == USB_INT_DISK_WRITE ) /* USB洢дݿ,д */ + { + CH376WriteHostBlock( buf, CH376_DAT_BLOCK_LEN ); /* USB˵ķͻдݿ */ + xWriteCH376Cmd( CMD0H_DISK_WR_GO ); /* ִUSB洢д */ + CH376_EN; + buf += CH376_DAT_BLOCK_LEN; + } + else + { + break; /* ش״̬ */ + } + } + + if ( mBlockCount == 0 ) + { + s = Wait376Interrupt( ); /* ȴжϲȡ״̬ */ + if ( s == USB_INT_SUCCESS ) return( USB_INT_SUCCESS ); /* ɹ */ + } + + if ( s == USB_INT_DISCONNECT ) + { + return( s ); /* U̱Ƴ */ + } + + CH376DiskReqSense( ); /* USB洢 */ + } + return( s ); /* ʧ */ +} + +/******************************************************************************* +* : CH376SecRead +* : Ϊλӵǰλöȡݿ,֧SD. +* : u8 * buf: +* ָⲿݻ. +* u8 ReqCount +* . +* u8 * RealCount: +* ʵʶ. +* : ж״̬. +*******************************************************************************/ +u8 CH376SecRead( u8 * buf, u8 ReqCount, u8 * RealCount ) +{ + u8 s; + u8 cnt; + u32 StaSec; + +#ifndef DEF_IC_V43_U + u32 fsz, fofs; +#endif + if ( RealCount ) + { + *RealCount = 0; + } + + do + { +#ifndef DEF_IC_V43_U + xWriteCH376Cmd( CMD01_GET_IC_VER ); + cnt = xReadCH376Data( ); + + if ( cnt == 0x41 ) + { + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( VAR_FILE_SIZE ); + xReadCH376Data( ); + fsz = xReadCH376Data( ); + fsz |= (UINT16)(xReadCH376Data( )) << 8; + cnt = xReadCH376Data( ); + fsz |= (u32)cnt << 16; + + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( VAR_CURRENT_OFFSET ); + xReadCH376Data( ); + fofs = xReadCH376Data( ); + fofs |= (UINT16)(xReadCH376Data( )) << 8; + fofs |= (u32)(xReadCH376Data( )) << 16; + + if ( fsz >= fofs + 510 ) + { + CH376WriteVar8( VAR_FILE_SIZE + 3, 0xFF ); + } + else + { + cnt = 0xFF; + } + } + else + { + cnt = 0xFF; + } +#endif + xWriteCH376Cmd( CMD1H_SEC_READ ); + xWriteCH376Data( ReqCount ); + CH376_EN; + s = Wait376Interrupt( ); +#ifndef DEF_IC_V43_U + if ( cnt != 0xFF ) + { + CH376WriteVar8( VAR_FILE_SIZE + 3, cnt ); + } +#endif + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + xReadCH376Data( ); /* sizeof(CH376_CMD_DATA.SectorRead) */ + cnt = xReadCH376Data( ); /* CH376_CMD_DATA.SectorRead.mSectorCount */ + xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + StaSec = CH376Read32bitDat( ); /* CH376_CMD_DATA.SectorRead.mStartSector,CH376оƬȡ32λݲ */ + + if ( cnt == 0 ) + { + break; + } + + s = CH376DiskReadSec( buf, StaSec, cnt ); /* U̶ȡݿ鵽 */ + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + + buf += cnt * DEF_SECTOR_SIZE; + if ( RealCount ) + { + *RealCount += cnt; + } + ReqCount -= cnt; + + } while ( ReqCount ); + + return( s ); +} + +/******************************************************************************* +* : CH376SecWrite +* : Ϊλڵǰλдݿ,֧SD. +* : u8 * buf: +* ָⲿݻ. +* u8 ReqCount +* д. +* u8 * RealCount: +* ʵд. +* : ж״̬. +*******************************************************************************/ +u8 CH376SecWrite( u8 * buf, u8 ReqCount, u8 * RealCount ) +{ + u8 s; + u8 cnt; + u32 StaSec; + + if ( RealCount ) + { + *RealCount = 0; + } + + do + { + xWriteCH376Cmd( CMD1H_SEC_WRITE ); + xWriteCH376Data( ReqCount ); + CH376_EN; + s = Wait376Interrupt( ); + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + xReadCH376Data( ); /* sizeof(CH376_CMD_DATA.SectorWrite) */ + cnt = xReadCH376Data( ); /* CH376_CMD_DATA.SectorWrite.mSectorCount */ + xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + StaSec = CH376Read32bitDat( ); /* CH376_CMD_DATA.SectorWrite.mStartSector,CH376оƬȡ32λݲ */ + if ( cnt == 0 ) + { + break; + } + s = CH376DiskWriteSec( buf, StaSec, cnt ); /* еĶݿдU */ + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + + buf += cnt * DEF_SECTOR_SIZE; + if ( RealCount ) + { + *RealCount += cnt; + } + + ReqCount -= cnt; + + } while ( ReqCount ); + return( s ); +} + +#endif + +/******************************************************************************* +* : CH376LongNameWrite +* : ļרõֽдӳ. +* : u8 * buf: +* ָⲿݻ. +* UINT16 ReqCount +* дֽ. +* : ж״̬. +*******************************************************************************/ +#ifdef EN_LONG_NAME +u8 CH376LongNameWrite( u8 * buf, UINT16 ReqCount ) +{ + u8 s; +#ifndef DEF_IC_V43_U + u8 c; + + c = CH376ReadVar8( VAR_DISK_STATUS ); + if ( c == DEF_DISK_OPEN_ROOT ) + { + CH376WriteVar8( VAR_DISK_STATUS, DEF_DISK_OPEN_DIR ); + } +#endif + xWriteCH376Cmd( CMD2H_BYTE_WRITE ); + xWriteCH376Data( (u8)ReqCount ); + xWriteCH376Data( (u8)(ReqCount>>8) ); + CH376_EN; + while ( 1 ) + { + s = Wait376Interrupt( ); + if ( s == USB_INT_DISK_WRITE ) + { + if ( buf ) + { + buf += CH376WriteReqBlock( buf ); /* ڲָдݿ,س */ + } + else + { + xWriteCH376Cmd( CMD01_WR_REQ_DATA ); /* ڲָдݿ */ + s = xReadCH376Data( ); /* */ + while ( s -- ) + { + xWriteCH376Data( 0 ); /* 0 */ + } + } + + xWriteCH376Cmd( CMD0H_BYTE_WR_GO ); + CH376_EN; + } + else + { +#ifndef DEF_IC_V43_U + if ( c == DEF_DISK_OPEN_ROOT ) + { + CH376WriteVar8( VAR_DISK_STATUS, c ); + } +#endif + return( s ); /* */ + } + } +} + +/******************************************************************************* +* : CH376CheckNameSum +* : 㳤ļĶļ,ΪСָĹ̶11 +* ڸʽ. +* : u8 * DirName: +* ָⲿļ. +* : ж״̬. +*******************************************************************************/ +u8 CH376CheckNameSum( u8 * DirName ) +{ + u8 NameLen; + u8 CheckSum; + + CheckSum = 0; + for ( NameLen = 0; NameLen != 11; NameLen ++ ) + { + CheckSum = ( CheckSum & 1 ? 0x80 : 0x00 ) + ( CheckSum >> 1 ) + *DirName++; + } + return( CheckSum ); +} + +/******************************************************************************* +* : CH376LocateInUpDir +* : ϼĿ¼(ļ)ƶļָ뵽ǰļĿ¼Ϣڵ. +* ,˳㽫ǰļĿ¼ϢڵǰһLBAַд +* CH376ڲVAR_FAT_DIR_LBA(Ϊ˷ռļʱǰ +* ,Ҫƶһ. +* ʹȫֻGlobalBufǰ12ֽ. +* : u8 * PathName: +* ָ·. +* : ж״̬. +*******************************************************************************/ +u8 CH376LocateInUpDir( u8 * PathName ) +{ + u8 s; + + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( VAR_FAT_DIR_LBA ); /* ǰļĿ¼ϢڵLBAַ */ + for ( s = 4; s != 8; s ++ ) + { + GlobalBuf[ s ] = xReadCH376Data( ); /* ʱȫֻ,ԼRAM */ + } + + CH376_EN; + + s = CH376SeparatePath( PathName ); /* ·зһļĿ¼,һļĿ¼ƫ */ + if ( s ) + { + s = CH376FileOpenDir( PathName, s ); /* Ƕ༶Ŀ¼,򿪶༶Ŀ¼µһĿ¼,ļϼĿ¼ */ + } + else + { + s = CH376FileOpen( "/" ); /* Ŀ¼µļ,򿪸Ŀ¼ */ + } + + if ( s != ERR_OPEN_DIR ) + { + return( s ); + } + *(u32 *)( &GlobalBuf[0] ) = 0; /* Ŀ¼ƫ,ȫֻ,ԼRAM */ + + while ( 1 ) /* ƶļָ,ֱ뵱ǰļĿ¼ϢڵLBAַƥ */ + { + s = CH376SecLocate( *(u32 *)(&GlobalBuf[0]) ); /* ΪλϼĿ¼ƶļָ */ + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + CH376ReadBlock( &GlobalBuf[8] ); /* ڴ滺ȡCH376_CMD_DATA.SectorLocate.mSectorLbaݿ,سsizeof(CH376_CMD_DATA.SectorLocate) */ + if ( *(u32 *)(&GlobalBuf[8]) == *(u32 *)(&GlobalBuf[4]) ) + { + return( USB_INT_SUCCESS ); /* ѵǰļĿ¼Ϣ */ + } + xWriteCH376Cmd( CMD50_WRITE_VAR32 ); + xWriteCH376Data( VAR_FAT_DIR_LBA ); /* õǰһ,ΪµļĿ¼ϢLBAַ */ + for ( s = 8; s != 12; s ++ ) + { + xWriteCH376Data( GlobalBuf[ s ] ); + } + CH376_EN; + ++ *(u32 *)(&GlobalBuf[0]); + } +} + +/******************************************************************************* +* : CH376CheckNameSum +* : ɶļĿ¼(ļ)Ӧijļ. +* Ҫļ·PathName,Ҫṩճļ +* LongName(UNICODEС˱,˫0), +* ʹȫֻGlobalBufǰ34ֽ, +* sizeof(GlobalBuf) >= sizeof(FAT_DIR_INFO)+2 +* : u8 * PathName: +* ļ·. +* u8 * LongName: +* ָļջ. +* : ж״̬. +*******************************************************************************/ +u8 CH376GetLongName( u8 * PathName, u8 * LongName ) +{ + u8 s; + UINT16 NameCount; /* ļֽڼ */ + + s = CH376FileOpenPath( PathName ); /* 򿪶༶Ŀ¼µļĿ¼ */ + if ( s != USB_INT_SUCCESS && s != ERR_OPEN_DIR ) + { + return( s ); + } + + s = CH376DirInfoRead( ); /* ȡǰļĿ¼ϢFAT_DIR_INFO,ݵڴ */ + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + + CH376ReadBlock( GlobalBuf ); /* ڴ滺ȡFAT_DIR_INFOݿ,سsizeof(FAT_DIR_INFO) */ + CH376EndDirInfo( ); /* ȡFAT_DIR_INFOṹ */ + GlobalBuf[32] = CH376CheckNameSum( GlobalBuf ); /* 㳤ļĶļ,ȫֻ,ԼRAM */ + GlobalBuf[33] = CH376ReadVar8( VAR_FILE_DIR_INDEX ); /* ǰļĿ¼Ϣڵ,ȫֻ,ԼRAM */ + NameCount = 0; + while ( 1 ) + { + if ( GlobalBuf[33] == 0 ) /* ǰļĿ¼Ϣ,תǰһ */ + { + s = CH376LocateInUpDir( PathName ); /* ϼĿ¼ƶļָ뵽ǰļĿ¼Ϣڵ */ + if ( s != USB_INT_SUCCESS ) + { + break; + } + + if ( CH376ReadVar32( VAR_CURRENT_OFFSET ) == 0 ) /* ǰѾĿ¼Ŀʼ,޷ȡļ */ + { + s = ERR_LONG_NAME_ERR; + break; + } + GlobalBuf[33] = DEF_SECTOR_SIZE / sizeof( FAT_DIR_INFO ); /* ָǰһһļĿ¼Ϣ */ + } + + GlobalBuf[33] --; /* ӺǰļĿ¼Ϣ */ + s = CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, GlobalBuf[33] ); /* ȡָĿ¼ϢFAT_DIR_INFO,ݵڴ */ + if ( s != USB_INT_SUCCESS ) + { + break; + } + + CH376ReadBlock( GlobalBuf ); /* ڴ滺ȡFAT_DIR_INFOݿ,سsizeof(FAT_DIR_INFO) */ + CH376EndDirInfo( ); /* ȡFAT_DIR_INFOṹ */ + if ( ( GlobalBuf[11] & ATTR_LONG_NAME_MASK ) != ATTR_LONG_NAME || GlobalBuf[13] != GlobalBuf[32] ) /* ʹУʹ */ + { + s = ERR_LONG_NAME_ERR; + break; /* ûֱӷΪǴ˸Ŀ¼ôҪرպܷ */ + } + + for ( s = 1; s < sizeof( FAT_DIR_INFO ); s += 2 ) /* ռļ,ļַڴUNICODEС˷ʽ */ + { + if ( s == 1 + 5 * 2 ) + { + s = 14; /* ӳļĵһ1-5ַڶ6-11ַ */ + } + else if ( s == 14 + 6 * 2 ) + { + s = 28; /* ӳļĵڶ6-11ַ12-13ַ */ + } + + LongName[ NameCount++ ] = GlobalBuf[ s ]; + LongName[ NameCount++ ] = GlobalBuf[ s + 1 ]; + if ( GlobalBuf[ s ] == 0 && GlobalBuf[ s + 1 ] == 0 ) + { + break; /* ļ */ + } + + if ( NameCount >= LONG_NAME_BUF_LEN ) /* ļ */ + { + s = ERR_LONG_BUF_OVER; + goto CH376GetLongNameE; + } + } + + if ( GlobalBuf[0] & 0x40 ) /* ļĿ¼Ϣ */ + { + if ( s >= sizeof( FAT_DIR_INFO ) ) *(PUINT16)( &LongName[ NameCount ] ) = 0x0000; /* δռļĽ,ǿƽ */ + s = USB_INT_SUCCESS; /* ɹɳļռ */ + break; + } + } + +CH376GetLongNameE: + CH376FileClose( FALSE ); /* ڸĿ¼Ҫر */ + return( s ); +} + +/******************************************************************************* +* : CH376CreateLongName +* : ½гļļ,رļ󷵻,LongName· +* RAM. +* Ҫļ·PathName(ȲοFAT淶ɳ +* в),ҪUNICODEС˱˫0ijļ +* LongName. +* ʹȫֻGlobalBufǰ64ֽ, +* sizeof(GlobalBuf)>=sizeof(FAT_DIR_INFO)*2 +* : u8 * PathName: +* ļ·. +* u8 * LongName: +* ָļ. +* : ж״̬. +*******************************************************************************/ +u8 CH376CreateLongName( u8 * PathName, u8 * LongName ) +{ + u8 s, i; + u8 DirBlockCnt; /* ļռļĿ¼ṹĸ */ + UINT16 count; /* ʱ,ڼ,ֽڶļʽʵʶȡֽ */ + UINT16 NameCount; /* ļֽڼ */ + u32 NewFileLoc; /* ǰļĿ¼ϢϼĿ¼еʼλ,ƫƵַ */ + + for ( count = 0; count < LONG_NAME_BUF_LEN; count += 2 ) + { + if ( *(PUINT16)(&LongName[count]) == 0 ) + { + break; /* λ */ + } + } + + if ( count == 0 || count >= LONG_NAME_BUF_LEN || count > LONE_NAME_MAX_CHAR ) + { + return( ERR_LONG_NAME_ERR ); /* ļЧ */ + } + + DirBlockCnt = count / LONG_NAME_PER_DIR; /* ļռļĿ¼ṹĸ */ + i = count - DirBlockCnt * LONG_NAME_PER_DIR; + + if ( i ) /* ͷ */ + { + if ( ++ DirBlockCnt * LONG_NAME_PER_DIR > LONG_NAME_BUF_LEN ) + { + return( ERR_LONG_BUF_OVER ); /* */ + } + count += 2; /* 0ij */ + i += 2; + + if ( i < LONG_NAME_PER_DIR ) /* ĩļĿ¼ṹ */ + { + while ( i++ < LONG_NAME_PER_DIR ) + { + LongName[count++] = 0xFF; /* ʣΪ0xFF */ + } + } + } + + s = CH376FileOpenPath( PathName ); /* 򿪶༶Ŀ¼µļ */ + if ( s == USB_INT_SUCCESS ) /* ļ򷵻ش */ + { + s = ERR_NAME_EXIST; + goto CH376CreateLongNameE; + } + + if ( s != ERR_MISS_FILE ) + { + return( s ); + } + + s = CH376FileCreatePath( PathName ); /* ½༶Ŀ¼µļ */ + if ( s != USB_INT_SUCCESS ) + { + return( s ); + } + + i = CH376ReadVar8( VAR_FILE_DIR_INDEX ); /* ʱڱ浱ǰļĿ¼Ϣڵ */ + s = CH376LocateInUpDir( PathName ); /* ϼĿ¼ƶļָ뵽ǰļĿ¼Ϣڵ */ + if ( s != USB_INT_SUCCESS ) + { + goto CH376CreateLongNameE; /* ûֱӷΪǴ˸Ŀ¼ôҪرպܷ */ + } + + NewFileLoc = CH376ReadVar32( VAR_CURRENT_OFFSET ) + i * sizeof(FAT_DIR_INFO); /* 㵱ǰļĿ¼ϢϼĿ¼еʼλ,ƫƵַ */ + s = CH376ByteLocate( NewFileLoc ); /* ϼĿ¼ƶļָ뵽ǰļĿ¼Ϣλ */ + if ( s != USB_INT_SUCCESS ) + { + goto CH376CreateLongNameE; + } + + s = CH376ByteRead( &GlobalBuf[ sizeof(FAT_DIR_INFO) ], sizeof(FAT_DIR_INFO), NULL );/* ֽΪλȡ,õǰļĿ¼ϢFAT_DIR_INFO */ + if ( s != USB_INT_SUCCESS ) + { + goto CH376CreateLongNameE; + } + + for ( i = DirBlockCnt; i != 0; -- i ) /* еļĿ¼ṹڴųļ */ + { + s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count ); /* ֽΪλȡ,һļĿ¼ϢFAT_DIR_INFO */ + if ( s != USB_INT_SUCCESS ) + { + goto CH376CreateLongNameE; + } + + if ( count == 0 ) + { + break; /* ޷,ϼĿ¼ */ + } + + if ( GlobalBuf[0] && GlobalBuf[0] != 0xE5 ) /* ʹõļĿ¼ṹ,ڳļӴ,Կռ䲻,ǰλòת */ + { + s = CH376ByteLocate( NewFileLoc ); /* ϼĿ¼ƶļָ뵽ǰļĿ¼Ϣλ */ + if ( s != USB_INT_SUCCESS ) + { + goto CH376CreateLongNameE; + } + + GlobalBuf[ 0 ] = 0xE5; /* ļɾ־ */ + for ( s = 1; s != sizeof(FAT_DIR_INFO); s ++ ) + { + GlobalBuf[ s ] = GlobalBuf[ sizeof(FAT_DIR_INFO) + s ]; + } + + s = CH376LongNameWrite( GlobalBuf, sizeof(FAT_DIR_INFO) ); /* дһļĿ¼ṹ,ɾ֮ǰ½ļ,ʵԺὫ֮תƵĿ¼ĩλ */ + if ( s != USB_INT_SUCCESS ) + { + goto CH376CreateLongNameE; + } + + do /* еļĿ¼ṹ */s + { + s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count ); /* ֽΪλȡ,һļĿ¼ϢFAT_DIR_INFO */ + if ( s != USB_INT_SUCCESS ) + { + goto CH376CreateLongNameE; + } + } while ( count && GlobalBuf[0] ); /* ȻʹõļĿ¼ṹ,ֱϼĿ¼δʹùļĿ¼ṹ */ + + NewFileLoc = CH376ReadVar32( VAR_CURRENT_OFFSET ); /* ϼĿ¼ĵǰļָΪǰļĿ¼ϢϼĿ¼еʼλ */ + i = DirBlockCnt + 1; /* ҪĿеļĿ¼ṹĸ,ļһͳļ */ + + if ( count == 0 ) + { + break; /* ޷,ϼĿ¼ */ + } + + NewFileLoc -= sizeof(FAT_DIR_INFO); /* صղĿеļĿ¼ṹʼλ */ + } + } + + if ( i ) /* еļĿ¼ṹԴųļ,ԭϼĿ¼,ϼĿ¼ij */ + { + s = CH376ReadVar8( VAR_SEC_PER_CLUS ); /* ÿ */ + if ( s == 128 ) /* FAT12/FAT16ĸĿ¼,ǹ̶,޷ļĿ¼ṹ */ + { + s = ERR_FDT_OVER; /* FAT12/FAT16Ŀ¼µļӦ512,Ҫ */ + goto CH376CreateLongNameE; + } + + count = s * DEF_SECTOR_SIZE; /* ÿֽ */ + if ( count < i * sizeof(FAT_DIR_INFO) ) + { + count <<= 1; /* һزһ,ֻᷢÿΪ512ֽڵ */ + } + + s = CH376LongNameWrite( NULL, count ); /* ֽΪλǰλдȫ0ݿ,ӵļĿ¼ */ + if ( s != USB_INT_SUCCESS ) + { + goto CH376CreateLongNameE; + } + } + + s = CH376ByteLocate( NewFileLoc ); /* ϼĿ¼ƶļָ뵽ǰļĿ¼Ϣλ */ + if ( s != USB_INT_SUCCESS ) + { + goto CH376CreateLongNameE; + } + + GlobalBuf[11] = ATTR_LONG_NAME; + GlobalBuf[12] = 0x00; + GlobalBuf[13] = CH376CheckNameSum( &GlobalBuf[ sizeof(FAT_DIR_INFO) ] ); /* 㳤ļĶļ */ + GlobalBuf[26] = 0x00; + GlobalBuf[27] = 0x00; + + for ( s = 0; DirBlockCnt != 0; ) /* ļռõļĿ¼ṹ */ + { + GlobalBuf[0] = s ? DirBlockCnt : DirBlockCnt | 0x40; /* ״Ҫóļڱ־ */ + DirBlockCnt --; + NameCount = DirBlockCnt * LONG_NAME_PER_DIR; + + for ( s = 1; s < sizeof( FAT_DIR_INFO ); s += 2 ) /* ļ,ļַڴUNICODEС˷ʽ */ + { + if ( s == 1 + 5 * 2 ) + { + s = 14; /* ӳļĵһ1-5ַڶ6-11ַ */ + } + else if ( s == 14 + 6 * 2 ) + { + s = 28; /* ӳļĵڶ6-11ַ12-13ַ */ + } + GlobalBuf[ s ] = LongName[ NameCount++ ]; + GlobalBuf[ s + 1 ] = LongName[ NameCount++ ]; + } + s = CH376LongNameWrite( GlobalBuf, sizeof(FAT_DIR_INFO) ); /* ֽΪλдһļĿ¼ṹ,ļ */ + if ( s != USB_INT_SUCCESS ) + { + goto CH376CreateLongNameE; + } + } + + s = CH376LongNameWrite( &GlobalBuf[ sizeof(FAT_DIR_INFO) ], sizeof(FAT_DIR_INFO) ); /* ֽΪλдһļĿ¼ṹ,ת֮ǰ½ļĿ¼Ϣ */ + +CH376CreateLongNameE: + CH376FileClose( FALSE ); /* ڸĿ¼Ҫر */ + return( s ); +} +#endif +/************************************ End *************************************/ diff --git a/User/DS1307/DS1307.c b/User/DS1307/DS1307.c new file mode 100644 index 0000000..8bd32a5 --- /dev/null +++ b/User/DS1307/DS1307.c @@ -0,0 +1,242 @@ + +#include "config.h" //ȫ + +//=========================================================================== +//Subroutine: iic_init +//IICʼ +//=========================================================================== + +//void delay_us(unsigned int Counter) +//{ +// uint32_t count; +// while (Counter--) +// { +// count = 42; // Ƶͱֵ +// while (count--) +// { +// __asm__ volatile("nop"); // ȷŻ +// } +// } +//} +void DS1307_Init() +{ + u8 i = 0; + GPIO_InitTypeDef GPIO_InitStructure; + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); + + GPIO_InitStructure.GPIO_Pin = iic_scl|iic_sda; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(iic_gpio, &GPIO_InitStructure); + GPIO_SetBits(iic_gpio,iic_scl|iic_sda); + TXHData.CTIMEReadTimer.Init = 0; //ʼ־ + TXHData.CTIMEReadTimer.Flag = 0; //ʱ־ + TXHData.CTIMEReadTimer.ON_OFF = 1; // + TXHData.CTIMEReadTimer.Cycle = 1; //Ϊѭģʽʱ + TXHData.CTIMEReadTimer.TimerCountMax = 500;//0.5 + DS1307_Read(); + if(TXHData.CTIME.Sec > 0x59) + { + //TXHData.PREXDATA_WaitUpNummber = 0; + TXHData.CTIME.Year = 0x24;// + TXHData.CTIME.Month = 0x08;// + TXHData.CTIME.Day = 0x30;// + //TXHData.CTIME.Week = 0x02;// + TXHData.CTIME.Hour = 0x14;//ʱ + TXHData.CTIME.Min = 0x20;// + TXHData.CTIME.Sec = 0x00;// + DS1307_Write(); + } +} +//=========================================================================== +//Subroutine: iic_start +//IICݴź +//SCLΪߵƽʱSDA½ +//=========================================================================== + void iic_start(void) +{ + iic_sdaout(); //SDA + GPIO_SetBits(iic_gpio,iic_sda); //SDAΪߵƽ + GPIO_SetBits(iic_gpio,iic_scl); //SCLΪߵƽ + delay_us(4); + GPIO_ResetBits(iic_gpio,iic_sda); //SDA½ +} +//=========================================================================== +//Subroutine: iic_stop +//IICݴֹͣź +//SCLΪߵƽʱSDA +//=========================================================================== +void iic_stop(void) +{ + iic_sdaout(); //SDA + GPIO_ResetBits(iic_gpio,iic_sda); //SDAΪ͵ƽ + delay_us(4); + GPIO_SetBits(iic_gpio,iic_scl); //SCLߵƽ + GPIO_SetBits(iic_gpio,iic_sda); //SDAأI2Cݴͽź +} +//=========================================================================== +//Subroutine: iic_wait4ack +//IICȴӦ +//ֵ1Ӧʧ +// 0Ӧɹ +//=========================================================================== + +u8 iic_wait4ack(void) +{ + u8 times=0; + iic_sdain(); //SDAΪ + GPIO_SetBits(iic_gpio,iic_sda);//sda͸ߵƽ + delay_us(1); + GPIO_SetBits(iic_gpio,iic_scl); //ʱӸߵƽ + delay_us(1); + while(GPIO_ReadInputDataBit(iic_gpio, iic_sda)) //ݣֱӻӦ + { + if(++times>IICWAITTIMEOUT) + { + iic_stop(); //Ӧֹͣ + return 1; + } + } + GPIO_ResetBits(iic_gpio,iic_scl);//ʱ͵ƽ½ + return 0; +} +//=========================================================================== +//Subroutine: iic_act Ӧ +//ʾ +//=========================================================================== + +void iic_ack(void) +{ + GPIO_ResetBits(iic_gpio,iic_scl); //ʱӵ͵ƽ + iic_sdaout(); + GPIO_ResetBits(iic_gpio,iic_sda); //ݵ͵ƽ,ʾӦ + delay_us(2); + GPIO_SetBits(iic_gpio,iic_scl); //ʱ + delay_us(2); + GPIO_ResetBits(iic_gpio,iic_scl); //ʱ½ +} + +//=========================================================================== +//Subroutine: iic_noact ӦӦ +//ʾٽ +//=========================================================================== +void iic_noack(void) +{ + GPIO_ResetBits(iic_gpio,iic_scl); //ʱӵ͵ƽ + iic_sdaout(); + GPIO_SetBits(iic_gpio,iic_sda); //ݸߵƽ,ʾӦ + delay_us(2); + GPIO_SetBits(iic_gpio,iic_scl); //ʱ + delay_us(2); + GPIO_ResetBits(iic_gpio,iic_scl); //ʱ½ +} + +//=========================================================================== +//Subroutine: iic_sendbyte +//IICһֽ +//=========================================================================== +void iic_sendbyte(u8 txd) +{ + u8 t; + iic_sdaout(); //SDAΪΪҪ + GPIO_ResetBits(iic_gpio,iic_scl); //ʱӵ͵ƽֻSCLΪͲſɸı + for(t=0;t<8;t++)//ѭ8ֽ + { + if ((txd&0x80)>>7) GPIO_SetBits(iic_gpio,iic_sda); //7-tλ + else GPIO_ResetBits(iic_gpio,iic_sda); + txd<<=1; + delay_us(2); + GPIO_SetBits(iic_gpio,iic_scl); //SCL + delay_us(2); + GPIO_ResetBits(iic_gpio,iic_scl); //SCLָ͵ƽ׼޸SDA + delay_us(2); + } +} + + +//=========================================================================== +//Subroutine: iic_readbyte +//1ֽڣack=1ʱ֮ACKack=0ߺnACK +//=========================================================================== +u8 iic_readbyte(u8 ack) +{ + unsigned char i,receive=0; + iic_sdain();//׼ݣSDAΪ + for(i=0;i<8;i++ ) //ѭ8λ + { + GPIO_ResetBits(iic_gpio,iic_scl); //SCLΪ͵ƽ + delay_us(2); + GPIO_SetBits(iic_gpio,iic_scl); //SCLأʼȡ + receive<<=1; + if(GPIO_ReadInputDataBit(iic_gpio, iic_sda)) //ȡ + receive|=0x01; //Ϊ1receiveλӦΪ1 + delay_us(1); + } + if (ack) //ҪӦ + iic_ack();//Ӧ + else + iic_noack(); //Ӧ + return receive; +} + +//=========================================================================== +//ַָһ +//ֵ : +//=========================================================================== +void DS1307_Read(void)//93us +{ + u8 temp[7],i; + + iic_start(); // + iic_sendbyte(0XD0); //ַ0XD0 + iic_wait4ack(); //ȴӦ + iic_sendbyte(0); //ֵַ + iic_wait4ack(); //ȴӦ + iic_start(); //һ + iic_sendbyte(0XD1); //͵ַ0XD1ģʽ + iic_wait4ack(); //ȴӦ + for (i = 0;i < 7;i ++) + { + if (i < 6) + temp[i] = iic_readbyte(1); + else + temp[i] = iic_readbyte(0); + } + iic_stop(); //һֹͣ + TXHData.CTIME.Year = temp[6];// + TXHData.CTIME.Month = temp[5];// + TXHData.CTIME.Day = temp[4];// + + TXHData.CTIME.Hour = temp[2];//ʱ + TXHData.CTIME.Min = temp[1];// + TXHData.CTIME.Sec = temp[0];// +} +//=========================================================================== +//ַָдһ +//ֵ : +//=========================================================================== +void DS1307_Write(void) +{ + u8 i = 0,temp[7]; + + temp[0]= TXHData.CTIME.Sec; + temp[1]= TXHData.CTIME.Min; + temp[2]= TXHData.CTIME.Hour; + temp[3]= 0x01; + temp[4]= TXHData.CTIME.Day; + temp[5]= TXHData.CTIME.Month; + temp[6]= TXHData.CTIME.Year; + iic_start(); + iic_sendbyte(0XD0); //ַ0XD0 + iic_wait4ack(); //ȴӦ + iic_sendbyte(0x00); //ֵַ + iic_wait4ack(); //ȴӦ + for(i = 0;i < 7;i ++) + { + iic_sendbyte(temp[i]); //ֽ + iic_wait4ack(); //ȴӦ + } + iic_stop(); //һֹͣ +} diff --git a/User/DS1307/DS1307.h b/User/DS1307/DS1307.h new file mode 100644 index 0000000..1569c2a --- /dev/null +++ b/User/DS1307/DS1307.h @@ -0,0 +1,32 @@ +#ifndef __DS1307_H +#define __DS1307_H + +//============================================================================== +//macro: iic_sdain iic_sdaout +//sdaΪ +// CRL 4λΪ 1000 λ7 sda +// CRL 4λΪ 0011 λ7 sda Ƶ50M +//ΪԱ֤ΪAF +//============================================================================== +#define iic_sdain() GPIOF->MODER &= 0XFFFFF3FF;// +#define iic_sdaout() GPIOF->MODER |= 0X00000400;// +#define IICWAITTIMEOUT 250 +#define iic_gpio GPIOF +#define iic_scl GPIO_Pin_4 +#define iic_sda GPIO_Pin_5 + +//void delay_us(unsigned int Counter); +void DS1307_Init(void); +void iic_start(void); +void iic_stop(void); +u8 iic_wait4ack(void); +void iic_ack(void); +void iic_noack(void); +void iic_sendbyte(u8); +u8 iic_readbyte(unsigned char ack); +void DS1307_Read(void); +void DS1307_Write(void); + + + +#endif diff --git a/User/Delay/delay.c b/User/Delay/delay.c new file mode 100644 index 0000000..43d2c07 --- /dev/null +++ b/User/Delay/delay.c @@ -0,0 +1,39 @@ +#include "config.h" //ȫ + +void delay_init(void) +{ + SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//ʱ +} +//ʱ뼶 +void delay_ms(uint32_t nms) +{ + uint32_t tmp; + while(nms--) + { + SysTick->LOAD = 168000000/8/1000; //ֵʱ1ms + SysTick->VAL = 0; //յǰֵ + SysTick->CTRL |= 0x1; //ʼ + while ((SysTick->CTRL & 0x00010000)==0); + + SysTick->VAL = 0; //յǰֵ + SysTick->CTRL &= 0; //رռ + } +} + +//ʱ΢뼶 +void delay_us(uint32_t nus) +{ + uint32_t tmp; + while(nus--) + { + SysTick->LOAD = 168000000/8/1000000; //ֵʱ1us + SysTick->VAL = 0; //յǰֵ + SysTick->CTRL |= 0x1; //ʼ + while ((SysTick->CTRL & 0x00010000)==0); + SysTick->VAL = 0; //յǰֵ + SysTick->CTRL &= 0; //رռ + } + +} + + \ No newline at end of file diff --git a/User/Delay/delay.h b/User/Delay/delay.h new file mode 100644 index 0000000..a569fc3 --- /dev/null +++ b/User/Delay/delay.h @@ -0,0 +1,10 @@ +#ifndef _DELAY_H_ +#define _DELAY_H_ +#include "stm32f4xx.h" +void delay_init(void) ; +void delay_ms(uint32_t nms); +void delay_us(uint32_t nus); + + +#endif + \ No newline at end of file diff --git a/User/FRam/FRam.c b/User/FRam/FRam.c new file mode 100644 index 0000000..7d93364 --- /dev/null +++ b/User/FRam/FRam.c @@ -0,0 +1,436 @@ +/*C***************************************************************************** +* NAME: fRamDrive.c +*------------------------------------------------------------------------------- +*******************************************************************************/ +/*_____ I N C L U D E S ______________________________________________________*/ + +//#define FRAM_INIT + + +#include "config.h" //ȫ + +volatile s_uniGlobal_Typedef s_uniGlobal; + + +//ʼ==================================================================== +// + +const u8 initFRam_Flag = 0x38; +const PrintInfo_Type InitPrintInfo={ + " Ho So Giao Dich ",//׼¼ + "TEN CUA HANG: ",//ַ + "DIA CHI: ",//˰ + "MA SO THUE: ",// + " ", + " ", + "SO VOL: ",// + "SO TIEN: ",// + "SO LIT: ",// + "DONGIA: ",// + " ", + "NGAY: ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "CAM ON & HEN GAP LAI QUY KHACH !", + }; +const MD_Port_Data_Type InitMD_Port_Data = { + //BaudRate StopBits Parity_Even POSType GunNumber MBCountTime Display_Type + { 9600, 1, 0, 0, 0, 10, 0 ,MD_RS485,{0,0,0,0,0,0,0,0,0,0}}, + {//Num Addr State Standby[35] + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + {0, 0, 0, }, + } +}; +/*typedef struct +{ + char CMD_SOCKA[50]; + char IMEI[20]; + char APN[40]; + char WiFIName[40]; + char WiFIPassWord[20]; +}WirelessData_Type;*/ + +//Tast URL http://test.joyfueling.com:8012/ +// http://3.92.208.210:7011/ +const POSData_Type InitPOSData={ +// +//{"AT+SOCKA=TCP,3.92.208.210,7011\r\n"},POS_Connect_Typ_Station}; +{"joyfuel.joyfueling.com,7011","","","KFB-2.4G","KFB123456"},POS_Connect_Typ_Station}; +const u8 InitMD_Port_Num_Top = 0; +const ROM_UpData_Type InitROM_UpData = {{0x06},900};//450K +const u32 InitPREXDATA_WaitUpNummber = 0; +const u32 InitPREXDATA_TTC = 0; +const PREXDATA_Type initPrintLastRecord= {0,0,0,0,0,0,0,0,0}; +const POSNetSetState_TypeDef InitPOSNetSetState; +const MD_Multiplex_Port_Data_Type InitMD_Multiplex_Port_Data;//˿5·ÿPREXDATA_NowFrameLen +const WhiteList_Type InitWhiteList; +const PREXDATA_Upload_Type InitPREXDATA_Upload; +//============================================================================== +const framDataIndex FDITab[] = +{ ///FRAM1(ݲԲƵ) +/// pInitData; upData pData firstAdr; len; Group Tpye; //(ע,Уݰβ) + {(u8*)&initFRam_Flag, (u8*)(&buf_FRam_Flag), (u8*)(&TXHData.FRam_Flag), FRam_Flag_FADR, FRam_Flag_LEN, FRam_Flag_Group, CF_FRam_Flag}, + {(u8*)&InitROM_UpData, (u8*)(&buf_ROM_UpData), (u8*)(&TXHData.ROM_UpData), ROM_UpData_FADR, ROM_UpData_LEN, ROM_UpData_Group, CF_ROM_UpData}, + {(u8*)&InitMD_Port_Data, (u8*)(&buf_MD_Port_Data), (u8*)(&TXHData.MD_Port_Data), MD_Port_Data_FADR, MD_Port_Data_LEN, MD_Port_Data_Group, CF_MD_Port_Data}, + {(u8*)&InitPOSData, (u8*)(&buf_POSData), (u8*)(&TXHData.POSData), POSData_FADR, POSData_LEN, POSData_Group, CF_POSData}, + {(u8*)&InitMD_Port_Num_Top, (u8*)(&buf_MD_Port_Num_Top), (u8*)(&TXHData.MD_Port_Num_Top), MD_Port_Num_Top_FADR, MD_Port_Num_Top_LEN, MD_Port_Num_Top_Group, CF_MD_Port_Num_Top}, + {(u8*)&InitPREXDATA_WaitUpNummber,(u8*)(&buf_PREXDATA_WaitUpNummber), (u8*)(&TXHData.PREXDATA_WaitUpNummber),PREXDATA_WaitUpNummber_FADR, PREXDATA_WaitUpNummber_LEN, PREXDATA_WaitUpNummber_Group, CF_PREXDATA_WaitUpNummber}, + {(u8*)&InitPREXDATA_TTC, (u8*)(&buf_PREXDATA_TTC), (u8*)(&TXHData.PREXDATA_TTC), PREXDATA_TTC_FADR, PREXDATA_TTC_LEN, PREXDATA_TTC_Group, CF_PREXDATA_TTC}, + {(u8*)&InitPrintInfo, (u8*)(&buf_PrintInfo), (u8*)(&TXHData.PrintInfo), PrintInfo_FADR, PrintInfo_LEN, PrintInfo_Group, CF_PrintInfo}, + {(u8*)&initPrintLastRecord, (u8*)(&buf_PrintLastRecord), (u8*)(&TXHData.PrintLastRecord), PrintLastRecord_FADR, PrintLastRecord_LEN, PrintLastRecord_Group, CF_PrintLastRecord}, + {(u8*)&InitPOSNetSetState, (u8*)(&buf_POSNetSetState), (u8*)(&TXHData.POSNetSetState), POSNetSetState_FADR, POSNetSetState_LEN, POSNetSetState_Group, CF_POSNetSetState}, + {(u8*)&InitMD_Multiplex_Port_Data,(u8*)(&buf_MD_Multiplex_Port_Data), (u8*)(&TXHData.MD_Multiplex_Port_Data),MD_Multiplex_Port_Data_FADR, MD_Multiplex_Port_Data_LEN, MD_Multiplex_Port_Data_Group, CF_MD_Multiplex_Port_Data}, + {(u8*)&InitWhiteList, (u8*)(&buf_WhiteList), (u8*)(&TXHData.WhiteList), WhiteList_FADR, WhiteList_LEN, WhiteList_Group, CF_WhiteList}, + {(u8*)&InitPREXDATA_Upload, (u8*)(&buf_PREXDATA_Upload), (u8*)(&TXHData.PREXDATA_Upload), PREXDATA_Upload_FADR, PREXDATA_Upload_LEN, PREXDATA_Upload_Group, CF_PREXDATA_Upload}, +}; +////============================================================================== + +//F***************************************************************************** +//* NAME: FRamDataCheck +//* PURPOSE: У麯 +//* PARAMS: pDataҪַlenݳ +//* return: +//****************************************************************************** +u8 FRamDataCheck(volatile u8* pData, u16 len) +{ + u8 result; + result = *pData; + while(len--) + { + result += *pData++; + }; + + return result; +} +/**************************************************** +FM_IO_Configuration + FM洢õIOʼ + +ֵ +****************************************************/ +void FM_IO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA ,ENABLE); + + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); + + /*!< Configure SPI1 pins: SCK MOSI*/ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + /*!< Configure SPI1: MISO */ + //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //modi + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; + GPIO_Init(GPIOA, &GPIO_InitStructure); + +} + +/**************************************************** +FM_SPI_Configuration + FM洢õSPIʼ + +ֵ +****************************************************/ +void FM_SPI_Configuration(void) +{ + /* SPI1 configuration */ + SPI_InitTypeDef SPI_InitStructure; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); + + SPI_I2S_DeInit(SPI1); + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//??? + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//8????? + SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//?????SCK?1 + SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//??????2??????? + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS???? + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;//??? + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//???? + SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC??? + SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//???? + SPI_Init(SPI1, &SPI_InitStructure); + SPI_Cmd(SPI1, ENABLE); + +} + +/**************************************************** +FM_SPI2_SendByte + FM洢õSPIͺ + dt Ҫ͵ +ֵ +****************************************************/ +u8 FM_SPI1_SendByte(u8 dt) +{ + while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); + SPI_I2S_SendData(SPI1, dt); + while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); + return SPI_I2S_ReceiveData(SPI1); +} + +/**************************************************** +FM_ReadData + ȡַָ + *pBuffȡ + addr ȡĵַ + Len ݳ +ֵ +****************************************************/ +void FM_ReadData(u8 *pBuff,u32 addr,u16 Len) +{ + u16 i = 0; + CLI(); + FM_CS_EN; + FM_SPI1_SendByte(0x03); + FM_SPI1_SendByte((u8)(addr>>16)); + FM_SPI1_SendByte((u8)(addr>>8)); + FM_SPI1_SendByte((u8)addr); + for(i = 0;i < Len;i ++) + { + *pBuff = FM_SPI1_SendByte(0x00); + pBuff ++; + } + FM_CS_DIS; + SEI(); +} + +/**************************************************** +FM_WriteData + дȡַָ + *pBuffݻ + addr дĵַ + Len ݳ +ֵ +****************************************************/ +void FM_WriteData(u8 *pBuff,u32 addr,u16 Len) +{ + u16 i = 0; + CLI(); + FM_CS_EN; + FM_SPI1_SendByte(0x06); + FM_CS_DIS; + FM_CS_EN; + FM_SPI1_SendByte(0x02); + FM_SPI1_SendByte((u8)(addr>>16)); + FM_SPI1_SendByte((u8)(addr>>8)); + FM_SPI1_SendByte((u8)addr); + for(i = 0;i < Len;i ++) + { + FM_SPI1_SendByte(*pBuff); + pBuff ++; + } + FM_CS_DIS; + SEI(); +} +/**************************************************** +FM_Init + FM洢ֳʼ + +ֵ +****************************************************/ +u16 iiii = 0;//㲻ȫֱ(ܴעһ) +void FM_Init(void) +{ + u16 i = 0,j = 0; + u8* pBuff; + u8 Temp_Buff[1300]; + u8 Temp = 0; + u32 Fristflag = 0,delay = 0; + FM_IO_Configuration(); //FMIOʼ + FM_SPI_Configuration(); //FMSPIʼ + //for(delay = 0;delay<0xfffff;delay++);//ʱȴȶ + delay_ms(10); + pBuff = (u8*)&Fristflag; + { + FM_CS_EN; + FM_SPI1_SendByte(0x06); //дʹ + FM_CS_DIS; + FM_CS_EN; + FM_SPI1_SendByte(0x01); //λ + FM_SPI1_SendByte(0x00); + FM_CS_DIS; + } + if((FDITab[FramItemEnd - 1].firstAdr + FDITab[FramItemEnd - 1].len * FDITab[FramItemEnd - 1].Group) > 0x20000) + { + __breakpoint(0); // halt program execution here + while(1); + } +#ifdef FRAM_INIT //ʼ + for(iiii = 0;iiii< FramItemEnd;iiii ++) //дĬϴ洢 + { + for(i = 0;i < FDITab[iiii].Group;i ++) + { + for(j = 0;j < FDITab[iiii].len-checkLen_1;j ++) + Temp_Buff[j]=*(FDITab[iiii].upData+j) = *(FDITab[iiii].pInitData+j); + + Temp = FRamDataCheck(Temp_Buff,FDITab[iiii].len - checkLen_1); + FM_WriteData(uniGlobal.Global,FDITab[iiii].firstAdr+FDITab[iiii].len*i, FDITab[iiii].len-checkLen_1); + FM_WriteData(&Temp, FDITab[iiii].firstAdr+FDITab[iiii].len+FDITab[iiii].len*i-checkLen_1,checkLen_1); + } + } +#endif + if(SWF8 == SWF_ON) + { + FM_Data_Init(); + } + + for(iiii = 0;iiii< FramItemEnd;iiii ++) //ȡ洢 + { + for(i = 0;i < FDITab[iiii].Group;i ++) + { + if(FMItemRead(iiii,i) == 0) + { + + } + } + } + + TXHData.SystemErr = TXHData.PREXDATA_WaitUpNummber; +} +void PCBEncryption(void) +{ + STM32CPU.v.id[0] = *(u32*)0x1fff7a10; + STM32CPU.v.id[1] = *(u32*)(0x1fff7a10 + 4); + STM32CPU.v.id[2] = *(u32*)(0x1fff7a10 + 8); + TXHData.Encryption[0] = CRC_Check(&STM32CPU.v.byte[0],6); + TXHData.Encryption[1] = CRC_Check(&STM32CPU.v.byte[1],6); + TXHData.Encryption[2] = CRC_Check(&STM32CPU.v.byte[2],8); + TXHData.Encryption[3] = CRC_Check(&STM32CPU.v.byte[3],8); + FM_WriteData((u8*)TXHData.Encryption,Encryption_FADR,sizeof(TXHData.Encryption)); +} +void PCBEncryption_Check(void) +{ + STM32CPU.v.id[0] = *(u32*)0x1fff7a10; + STM32CPU.v.id[1] = *(u32*)(0x1fff7a10 + 4); + STM32CPU.v.id[2] = *(u32*)(0x1fff7a10 + 8); + FM_ReadData((u8*)TXHData.Encryption,Encryption_FADR,sizeof(TXHData.Encryption)); + if(TXHData.Encryption[0] != CRC_Check(&STM32CPU.v.byte[0],6)) TXHData.ErrState.Flag.e_errPCBCheck = 1; + if(TXHData.Encryption[1] != CRC_Check(&STM32CPU.v.byte[1],6)) TXHData.ErrState.Flag.e_errPCBCheck = 1; + if(TXHData.Encryption[2] != CRC_Check(&STM32CPU.v.byte[2],8)) TXHData.ErrState.Flag.e_errPCBCheck = 1; + if(TXHData.Encryption[3] != CRC_Check(&STM32CPU.v.byte[3],8)) TXHData.ErrState.Flag.e_errPCBCheck = 1; +} +void FM_Data_Init(void) +{ + u16 i = 0,j = 0; + u8 Temp_Buff[1300]; + u8 Temp = 0; + u8 BackTemp = 0; + FMItemRead(CF_ROM_UpData,0); + BackTemp = TXHData.ROM_UpData.ROM_UpData_State.State;//IAPʼʱùˣظʼ + for(iiii = 0;iiii< FramItemEnd;iiii ++) //дĬϴ洢 + { + for(i = 0;i < FDITab[iiii].Group;i ++) + { + for(j = 0;j < FDITab[iiii].len-checkLen_1;j ++) + Temp_Buff[j]=*(FDITab[iiii].upData+j) = *(FDITab[iiii].pInitData+j); + + Temp = FRamDataCheck(Temp_Buff,FDITab[iiii].len - checkLen_1); + FM_WriteData(uniGlobal.Global,FDITab[iiii].firstAdr+FDITab[iiii].len*i, FDITab[iiii].len-checkLen_1); + FM_WriteData(&Temp, FDITab[iiii].firstAdr+FDITab[iiii].len+FDITab[iiii].len*i-checkLen_1,checkLen_1); + } + } + TXHData.ROM_UpData.ROM_UpData_State.State = BackTemp; + FMItemWrite(CF_ROM_UpData,0); +} +u8 FMItemWrite(FramItem Type, u16 Group) +{ + u16 i = 0,j = 0,k = 0; + u8 Temp_Buff[1300]; + u8 Temp = 0; + if(Group >= FDITab[Type].Group) + return 0; + if(TXHData.PowerDown.State == 0 && FMItemRead(CF_FRam_Flag,0) == 1) + { + for(i = 0;i < FDITab[Type].len;i ++) + { + *(FDITab[Type].upData + i) = *(FDITab[Type].pData + i + (FDITab[Type].len-1)*Group); + Temp_Buff[i] = *(FDITab[Type].upData + i); + } + for(j = 0;j < 6;j ++) + { + FM_WriteData(uniGlobal.Global,FDITab[Type].firstAdr+FDITab[Type].len*Group,FDITab[Type].len-1); + Temp = FRamDataCheck(Temp_Buff,FDITab[Type].len - checkLen_1); + FM_WriteData(&Temp,FDITab[Type].firstAdr+FDITab[Type].len+FDITab[Type].len*Group-1,checkLen_1); + + if(FMItemRead(Type,Group) == 1) + { + return 1; + } + delay_ms(100); + } + } +// pGun.ErrState[0].Flag.e_errFramParameter = 1; //洢󹫹ֻжһ +// pGun.ErrState[1].Flag.e_errFramParameter = 1; //洢󹫹ֻжһ + return 0; +} + +u8 FMItemRead(FramItem Type, u16 Group) +{ + volatile u16 ii = 0,j = 0; + u8 Temp_Buff[1300]; + u8 Temp = 0; + + if(Group >= FDITab[Type].Group) + return 0; + for(j = 0;j < 6;j ++) + { + /****************************/ + FM_ReadData(uniGlobal.Global,FDITab[CF_FRam_Flag].firstAdr,1); + *(Temp_Buff) = *(FDITab[CF_FRam_Flag].upData); + + if(*(Temp_Buff) == 0x38) + { + FM_ReadData(uniGlobal.Global,FDITab[Type].firstAdr+FDITab[Type].len*Group,FDITab[Type].len); + for(ii = 0;ii < FDITab[Type].len;ii ++) + *(Temp_Buff+ii) = *(FDITab[Type].upData+ii); + Temp = FRamDataCheck(Temp_Buff,FDITab[Type].len - checkLen_1); + if(Temp == Temp_Buff[FDITab[Type].len - checkLen_1]) + { + for(ii = 0;ii < FDITab[Type].len - checkLen_1;ii ++) + { + *(FDITab[Type].pData+ii+(FDITab[Type].len-1)*Group) = *(FDITab[Type].upData+ii); + } + return 1; + } + } + delay_ms(100); + } +// pGun.ErrState[0].Flag.e_errFramParameter = 1; //洢󹫹ֻжһ +// pGun.ErrState[1].Flag.e_errFramParameter = 1; //洢󹫹ֻжһ + + return 0; +} + diff --git a/User/FRam/FRam.h b/User/FRam/FRam.h new file mode 100644 index 0000000..5ffac70 --- /dev/null +++ b/User/FRam/FRam.h @@ -0,0 +1,191 @@ +#ifndef _FRam_H_ +#define _FRam_H_ +/****************************************************************************** +* NAME: fRam.h +*******************************************************************************/ +/*_____ M A C R O S __________________________________________________________*/ + + +//˿ +#define FM_CS_EN GPIO_ResetBits(GPIOA, GPIO_Pin_3);GPIO_SetBits(GPIOA, GPIO_Pin_4); +#define FM_CS_DIS GPIO_SetBits(GPIOA, GPIO_Pin_3); +//FM +#define FM_WREN 0X06 //дʹ +#define FM_READ 0X03 // +#define FM_WRITE 0X02 //д + +#define CLI() __set_PRIMASK(1) +#define SEI() __set_PRIMASK(0) + +/*_____ M A C R O S __________________________________________________________*/ +//CONFIG() +#define FRAM_SPACE_SIZE (0X800) ///󱣴 +#define FristStart_Addr 100 +//****************************************************************************** +// 洢 + +#define uniGlobal s_uniGlobal.u + +#define checkLen_1 1 ///У,1byte +//****************************************************************************** +// FRAM_DATA_MAP +//֤ +///ȫֻеֵ +///ṹ嶨 +#define Encryption_FADR (80) + +//洢ñ +///ȫֻеֵ +#define buf_FRam_Flag uniGlobal.FRam_Flag +///ṹ嶨 +#define FRam_Flag_FADR (FristStart_Addr) +#define FRam_Flag_LEN (sizeof(buf_FRam_Flag) + checkLen_1) +#define FRam_Flag_Group 1 // + +///ȫֻеֵ +#define buf_ROM_UpData uniGlobal.ROM_UpData +///ṹ嶨 +#define ROM_UpData_FADR (FRam_Flag_FADR + FRam_Flag_LEN * FRam_Flag_Group) +#define ROM_UpData_LEN (sizeof(buf_ROM_UpData) + checkLen_1) +#define ROM_UpData_Group 1 // + +//Ա +///ȫֻеֵ +#define buf_MD_Port_Data uniGlobal.MD_Port_Data +///ṹ嶨 +#define MD_Port_Data_FADR (ROM_UpData_FADR + ROM_UpData_LEN * ROM_UpData_Group) +#define MD_Port_Data_LEN (sizeof(buf_MD_Port_Data) + checkLen_1) +#define MD_Port_Data_Group 4 // + +//Ա +///ȫֻеֵ +#define buf_POSData uniGlobal.POSData +///ṹ嶨 +#define POSData_FADR (MD_Port_Data_FADR + MD_Port_Data_LEN * MD_Port_Data_Group) +#define POSData_LEN (sizeof(buf_POSData) + checkLen_1) +#define POSData_Group 1 // + +//Ա +///ȫֻеֵ +#define buf_MD_Port_Num_Top uniGlobal.MD_Port_Num_Top +///ṹ嶨 +#define MD_Port_Num_Top_FADR (POSData_FADR + POSData_LEN * POSData_Group) +#define MD_Port_Num_Top_LEN (sizeof(buf_MD_Port_Num_Top) + checkLen_1) +#define MD_Port_Num_Top_Group 1 // + +///ȫֻеֵ +#define buf_PREXDATA_WaitUpNummber uniGlobal.PREXDATA_WaitUpNummber +///ṹ嶨 +#define PREXDATA_WaitUpNummber_FADR (MD_Port_Num_Top_FADR + MD_Port_Num_Top_LEN * MD_Port_Num_Top_Group) +#define PREXDATA_WaitUpNummber_LEN (sizeof(buf_PREXDATA_WaitUpNummber) + checkLen_1) +#define PREXDATA_WaitUpNummber_Group 1 // + +///ȫֻеֵ +#define buf_PREXDATA_TTC uniGlobal.PREXDATA_TTC +///ṹ嶨 +#define PREXDATA_TTC_FADR (PREXDATA_WaitUpNummber_FADR + PREXDATA_WaitUpNummber_LEN * PREXDATA_WaitUpNummber_Group) +#define PREXDATA_TTC_LEN (sizeof(buf_PREXDATA_TTC) + checkLen_1) +#define PREXDATA_TTC_Group 1 // + +///ȫֻеֵ +#define buf_PrintInfo uniGlobal.PrintInfo +///ṹ嶨 +#define PrintInfo_FADR (PREXDATA_TTC_FADR + PREXDATA_TTC_LEN * PREXDATA_TTC_Group) +#define PrintInfo_LEN (sizeof(buf_PrintInfo) + checkLen_1) +#define PrintInfo_Group 1 // + +///ȫֻеֵ +#define buf_PrintLastRecord uniGlobal.PrintLastRecord +///ṹ嶨 +#define PrintLastRecord_FADR (PrintInfo_FADR + PrintInfo_LEN * PrintInfo_Group) +#define PrintLastRecord_LEN (sizeof(buf_PrintLastRecord) + checkLen_1) +#define PrintLastRecord_Group 64 // + +///ȫֻеֵ +#define buf_POSNetSetState uniGlobal.POSNetSetState +///ṹ嶨 +#define POSNetSetState_FADR (PrintLastRecord_FADR + PrintLastRecord_LEN * PrintLastRecord_Group) +#define POSNetSetState_LEN (sizeof(buf_POSNetSetState) + checkLen_1) +#define POSNetSetState_Group 1 // + +///ȫֻеֵ +#define buf_MD_Multiplex_Port_Data uniGlobal.MD_Multiplex_Port_Data +///ṹ嶨 +#define MD_Multiplex_Port_Data_FADR (POSNetSetState_FADR + POSNetSetState_LEN * POSNetSetState_Group) +#define MD_Multiplex_Port_Data_LEN (sizeof(buf_MD_Multiplex_Port_Data) + checkLen_1) +#define MD_Multiplex_Port_Data_Group 1 // + +///ȫֻеֵ +#define buf_WhiteList uniGlobal.WhiteList +///ṹ嶨 +#define WhiteList_FADR (MD_Multiplex_Port_Data_FADR + MD_Multiplex_Port_Data_LEN * MD_Multiplex_Port_Data_Group) +#define WhiteList_LEN (sizeof(buf_WhiteList) + checkLen_1) +#define WhiteList_Group 1 // + +///ȫֻеֵ +#define buf_PREXDATA_Upload uniGlobal.PREXDATA_Upload +///ṹ嶨 +#define PREXDATA_Upload_FADR (WhiteList_FADR + WhiteList_LEN * WhiteList_Group) +#define PREXDATA_Upload_LEN (sizeof(buf_PREXDATA_Upload) + checkLen_1) +#define PREXDATA_Upload_Group 1 // + +typedef struct +{ + union + { + u8 Global[1000]; //ȫ + u8 FRam_Flag; + MD_Port_Data_Type MD_Port_Data; + POSData_Type POSData; + u8 MD_Port_Num_Top; + ROM_UpData_Type ROM_UpData; + u32 PREXDATA_WaitUpNummber; + u32 PREXDATA_TTC; + PrintInfo_Type PrintInfo; + PREXDATA_Type PrintLastRecord;//Խϴӡÿǹһ + POSNetSetState_TypeDef POSNetSetState; + MD_Multiplex_Port_Data_Type MD_Multiplex_Port_Data;//˿5·ÿ + WhiteList_Type WhiteList; + PREXDATA_Upload_Type PREXDATA_Upload; + }u; + u8 CheckAdd; +}s_uniGlobal_Typedef; //洢д湲 + +typedef enum +{ + CF_FRam_Flag, + CF_ROM_UpData, + CF_MD_Port_Data, + CF_POSData, + CF_MD_Port_Num_Top, + CF_PREXDATA_WaitUpNummber, + CF_PREXDATA_TTC, + CF_PrintInfo, + CF_PrintLastRecord, + CF_POSNetSetState, + CF_MD_Multiplex_Port_Data, + CF_WhiteList, + CF_PREXDATA_Upload, + + FramItemEnd, +}FramItem; + +//******************************************************************************** +typedef struct +{ + u8* pInitData;//ʼָ + u8* upData; //ݻָ + u8* pData; //pGunָ + u32 firstAdr; //һַ + u16 len; // + u16 Group; + u8 Tpye; // +}framDataIndex; + +void FM_Init(void); +u8 FMItemWrite(FramItem Type, u16 Group); +u8 FMItemRead(FramItem Type, u16 Group); +void FM_Data_Init(void); +void PCBEncryption(void); +void PCBEncryption_Check(void); +#endif diff --git a/User/FRam/FRam.h~RF1bdf050.TMP b/User/FRam/FRam.h~RF1bdf050.TMP new file mode 100644 index 0000000..f32332d --- /dev/null +++ b/User/FRam/FRam.h~RF1bdf050.TMP @@ -0,0 +1,445 @@ +#ifndef _FRam_H_ +#define _FRam_H_ +/****************************************************************************** +* NAME: fRam.h +*******************************************************************************/ +/*_____ M A C R O S __________________________________________________________*/ + + +//˿ +#define FM_CS_EN GPIO_ResetBits(GPIOC, GPIO_Pin_6); +#define FM_CS_DIS GPIO_SetBits(GPIOC, GPIO_Pin_6); +#define FM_WP_EN GPIO_ResetBits(GPIOC, GPIO_Pin_7); +#define FM_WP_DIS GPIO_SetBits(GPIOC, GPIO_Pin_7); +//FM +#define FM_WREN 0X06 //дʹ +#define FM_READ 0X03 // +#define FM_WRITE 0X02 //д + +#define CLI() __set_PRIMASK(1) +#define SEI() __set_PRIMASK(0) + +/*_____ M A C R O S __________________________________________________________*/ +//CONFIG() +#define FRAM_SPACE_SIZE (0X800) ///󱣴 +#define FristStart_Addr 0 +//****************************************************************************** +// 洢 + +#define uniGlobal s_uniGlobal.u + +//****************************************************************************** +// FRAM_DATA_MAP +//****************************************************************************** +#define checkLen_1 0 ///У,1byte +//============================================================================== +// +///ȫֻеֵ +#define buf_Price uniGlobal.Price +///ṹ嶨 +#define Price_FADR 100 +#define Price_SADR FRAM_SPACE_SIZE/2+100 +#define Price_LEN (sizeof(buf_Price) + checkLen_1) +#define Price_arrayNb gunNumber +//============================================================================== +// +///ȫֻеֵ +#define buf_M_SquadTop uniGlobal.M_SquadTop +///ṹ嶨 +#define M_SquadTop_FADR (Price_FADR + Price_LEN) +#define M_SquadTop_SADR (Price_SADR + Price_LEN) +#define M_SquadTop_LEN (sizeof(buf_M_SquadTop) + checkLen_1) +#define M_SquadTop_arrayNb gunNumber +//============================================================================== +// +///ȫֻеֵ +#define buf_V_SquadTop uniGlobal.V_SquadTop +///ṹ嶨 +#define V_SquadTop_FADR (M_SquadTop_FADR + M_SquadTop_LEN) +#define V_SquadTop_SADR (M_SquadTop_SADR + M_SquadTop_LEN) +#define V_SquadTop_LEN (sizeof(buf_V_SquadTop) + checkLen_1) +#define V_SquadTop_arrayNb gunNumber +//============================================================================== +// +///ȫֻеֵ +#define buf_S_SquadTop uniGlobal.S_SquadTop +///ṹ嶨 +#define S_SquadTop_FADR (V_SquadTop_FADR + V_SquadTop_LEN) +#define S_SquadTop_SADR (V_SquadTop_SADR + V_SquadTop_LEN) +#define S_SquadTop_LEN (sizeof(buf_S_SquadTop) + checkLen_1) +#define S_SquadTop_arrayNb gunNumber +// +///ȫֻеֵ +#define buf_MassTop uniGlobal.MassTop +///ṹ嶨 +#define MassTop_FADR (S_SquadTop_FADR + S_SquadTop_LEN) +#define MassTop_SADR (S_SquadTop_SADR + S_SquadTop_LEN) +#define MassTop_LEN (sizeof(buf_MassTop) + checkLen_1) +#define MassTop_arrayNb gunNumber +// +///ȫֻеֵ +#define buf_VolumeTop uniGlobal.VolumeTop +///ṹ嶨 +#define VolumeTop_FADR (MassTop_FADR + MassTop_LEN) +#define VolumeTop_SADR (MassTop_SADR + MassTop_LEN) +#define VolumeTop_LEN (sizeof(buf_VolumeTop) + checkLen_1) +#define VolumeTop_arrayNb gunNumber +// +///ȫֻеֵ +#define buf_SaleTop uniGlobal.SaleTop +///ṹ嶨 +#define SaleTop_FADR (VolumeTop_FADR + VolumeTop_LEN) +#define SaleTop_SADR (VolumeTop_SADR + VolumeTop_LEN) +#define SaleTop_LEN (sizeof(buf_SaleTop) + checkLen_1) +#define SaleTop_arrayNb gunNumber +//ж +///ȫֻеֵ +#define buf_StockTop uniGlobal.StockTop +///ṹ嶨 +#define StockTop_FADR (SaleTop_FADR + SaleTop_LEN) +#define StockTop_SADR (SaleTop_SADR + SaleTop_LEN) +#define StockTop_LEN (sizeof(buf_StockTop) + checkLen_1) +#define StockTop_arrayNb gunNumber +//С +///ȫֻеֵ +#define buf_Decimal uniGlobal.Decimal +///ṹ嶨 +#define Decimal_FADR (StockTop_FADR + StockTop_LEN) +#define Decimal_SADR (StockTop_SADR + StockTop_LEN) +#define Decimal_LEN (sizeof(buf_Decimal) + checkLen_1) +#define Decimal_arrayNb gunNumber +//ϵͳʱ +///ȫֻеֵ +#define buf_SystemTime uniGlobal.SystemTime +///ṹ嶨 +#define SystemTime_FADR (Decimal_FADR + Decimal_LEN) +#define SystemTime_SADR (Decimal_SADR + Decimal_LEN) +#define SystemTime_LEN (sizeof(buf_SystemTime) + checkLen_1) +#define SystemTime_arrayNb gunNumber +//ģʽ +///ȫֻеֵ +#define buf_GasWorkMode uniGlobal.GasWorkMode +///ṹ嶨 +#define GasWorkMode_FADR (SystemTime_FADR + SystemTime_LEN) +#define GasWorkMode_SADR (SystemTime_SADR + SystemTime_LEN) +#define GasWorkMode_LEN (sizeof(buf_GasWorkMode) + checkLen_1) +#define GasWorkMode_arrayNb gunNumber +//嵱 +///ȫֻеֵ +#define buf_PulseEqu uniGlobal.PulseEqu +///ṹ嶨 +#define PulseEqu_FADR (GasWorkMode_FADR + GasWorkMode_LEN) +#define PulseEqu_SADR (GasWorkMode_SADR + GasWorkMode_LEN) +#define PulseEqu_LEN (sizeof(buf_PulseEqu) + checkLen_1) +#define PulseEqu_arrayNb gunNumber +//ܶ +///ȫֻеֵ +#define buf_Density uniGlobal.Density +///ṹ嶨 +#define Density_FADR (PulseEqu_FADR + PulseEqu_LEN) +#define Density_SADR (PulseEqu_SADR + PulseEqu_LEN) +#define Density_LEN (sizeof(buf_Density) + checkLen_1) +#define Density_arrayNb gunNumber +//Сʾ +///ȫֻеֵ +#define buf_MinDisp uniGlobal.MinDisp +///ṹ嶨 +#define MinDisp_FADR (Density_FADR + Density_LEN) +#define MinDisp_SADR (Density_SADR + Density_LEN) +#define MinDisp_LEN (sizeof(buf_MinDisp) + checkLen_1) +#define MinDisp_arrayNb gunNumber +//ǰط +///ȫֻеֵ +#define buf_ValueTurnOff uniGlobal.ValueTurnOff +///ṹ嶨 +#define ValueTurnOff_FADR (MinDisp_FADR + MinDisp_LEN) +#define ValueTurnOff_SADR (MinDisp_SADR + MinDisp_LEN) +#define ValueTurnOff_LEN (sizeof(buf_ValueTurnOff) + checkLen_1) +#define ValueTurnOff_arrayNb gunNumber +// +///ȫֻеֵ +#define buf_ValueOverShoot uniGlobal.ValueOverShoot +///ṹ嶨 +#define ValueOverShoot_FADR (ValueTurnOff_FADR + ValueTurnOff_LEN) +#define ValueOverShoot_SADR (ValueTurnOff_SADR + ValueTurnOff_LEN) +#define ValueOverShoot_LEN (sizeof(buf_ValueOverShoot) + checkLen_1) +#define ValueOverShoot_arrayNb gunNumber +//ʱ +///ȫֻеֵ +#define buf_TimeCount uniGlobal.TimeCount +///ṹ嶨 +#define TimeCount_FADR (ValueOverShoot_FADR + ValueOverShoot_LEN) +#define TimeCount_SADR (ValueOverShoot_SADR + ValueOverShoot_LEN) +#define TimeCount_LEN (sizeof(buf_TimeCount) + checkLen_1) +#define TimeCount_arrayNb gunNumber +//μ +///ȫֻеֵ +#define buf_FuelRecord0 uniGlobal.FuelRecord0 +///ṹ嶨 +#define FuelRecord0_FADR (TimeCount_FADR + TimeCount_LEN) +#define FuelRecord0_SADR (TimeCount_SADR + TimeCount_LEN) +#define FuelRecord0_LEN (sizeof(buf_FuelRecord0) + checkLen_1) +#define FuelRecord0_arrayNb gunNumber +//ǰμ +///ȫֻеֵ +#define buf_FuelRecord1 uniGlobal.FuelRecord1 +///ṹ嶨 +#define FuelRecord1_FADR (FuelRecord0_FADR + FuelRecord0_LEN) +#define FuelRecord1_SADR (FuelRecord0_SADR + FuelRecord0_LEN) +#define FuelRecord1_LEN (sizeof(buf_FuelRecord1) + checkLen_1) +#define FuelRecord1_arrayNb gunNumber +//Ƽʹ +///ȫֻеֵ +#define buf_TriesLimit uniGlobal.TriesLimit +///ṹ嶨 +#define TriesLimit_FADR (FuelRecord1_FADR + FuelRecord1_LEN) +#define TriesLimit_SADR (FuelRecord1_SADR + FuelRecord1_LEN) +#define TriesLimit_LEN (sizeof(buf_TriesLimit) + checkLen_1) +#define TriesLimit_arrayNb gunNumber +//Ƶַ +///ȫֻеֵ +#define buf_GasAddr uniGlobal.GasAddr +///ṹ嶨 +#define GasAddr_FADR (TriesLimit_FADR + TriesLimit_LEN) +#define GasAddr_SADR (TriesLimit_SADR + TriesLimit_LEN) +#define GasAddr_LEN (sizeof(buf_GasAddr) + checkLen_1) +#define GasAddr_arrayNb gunNumber +//Ƶַ +///ȫֻеֵ +#define buf_GasAddr uniGlobal.GasAddr +///ṹ嶨 +#define GasAddr_FADR (TriesLimit_FADR + TriesLimit_LEN) +#define GasAddr_SADR (TriesLimit_SADR + TriesLimit_LEN) +#define GasAddr_LEN (sizeof(buf_GasAddr) + checkLen_1) +#define GasAddr_arrayNb gunNumber +//ϵ +///ȫֻеֵ +#define buf_GasScaleCoefficients uniGlobal.GasScaleCoefficients +///ṹ嶨 +#define GasScaleCoefficients_FADR (GasAddr_FADR + GasAddr_LEN) +#define GasScaleCoefficients_SADR (GasAddr_SADR + GasAddr_LEN) +#define GasScaleCoefficients_LEN (sizeof(buf_GasScaleCoefficients) + checkLen_1) +#define GasScaleCoefficients_arrayNb gunNumber +//ܶ +///ȫֻеֵ +#define buf_GasDensity uniGlobal.GasDensity +///ṹ嶨 +#define GasDensity_FADR (GasScaleCoefficients_FADR + GasScaleCoefficients_LEN) +#define GasDensity_SADR (GasScaleCoefficients_SADR + GasScaleCoefficients_LEN) +#define GasDensity_LEN (sizeof(buf_GasDensity) + checkLen_1) +#define GasDensity_arrayNb gunNumber +///ȫֻеֵ +#define buf_GasPourTo1 uniGlobal.GasPourTo1 +///ṹ嶨 +#define GasPourTo1_FADR (GasDensity_FADR + GasDensity_LEN) +#define GasPourTo1_SADR (GasDensity_SADR + GasDensity_LEN) +#define GasPourTo1_LEN (sizeof(buf_GasPourTo1) + checkLen_1) +#define GasPourTo1_arrayNb gunNumber +//ел +///ȫֻеֵ +#define buf_GasPour1To2 uniGlobal.GasPour1To2 +///ṹ嶨 +#define GasPour1To2_FADR (GasPourTo1_FADR + GasPourTo1_LEN) +#define GasPour1To2_SADR (GasPourTo1_SADR + GasPourTo1_LEN) +#define GasPour1To2_LEN (sizeof(buf_GasPour1To2) + checkLen_1) +#define GasPour1To2_arrayNb gunNumber +// +///ȫֻеֵ +#define buf_GasFlowMax uniGlobal.GasFlowMax +///ṹ嶨 +#define GasFlowMax_FADR (GasPour1To2_FADR + GasPour1To2_LEN) +#define GasFlowMax_SADR (GasPour1To2_SADR + GasPour1To2_LEN) +#define GasFlowMax_LEN (sizeof(buf_GasFlowMax) + checkLen_1) +#define GasFlowMax_arrayNb gunNumber +//С +///ȫֻеֵ +#define buf_GasFlowMin uniGlobal.GasFlowMin +///ṹ嶨 +#define GasFlowMin_FADR (GasFlowMax_FADR + GasFlowMax_LEN) +#define GasFlowMin_SADR (GasFlowMax_SADR + GasFlowMax_LEN) +#define GasFlowMin_LEN (sizeof(buf_GasFlowMin) + checkLen_1) +#define GasFlowMin_arrayNb gunNumber +//ѹֵ +///ȫֻеֵ +#define buf_PressureMax uniGlobal.PressureMax +///ṹ嶨 +#define PressureMax_FADR (GasFlowMin_FADR + GasFlowMin_LEN) +#define PressureMax_SADR (GasFlowMin_SADR + GasFlowMin_LEN) +#define PressureMax_LEN (sizeof(buf_PressureMax) + checkLen_1) +#define PressureMax_arrayNb gunNumber +//Сѹֵ +///ȫֻеֵ +#define buf_PressureMin uniGlobal.PressureMin +///ṹ嶨 +#define PressureMin_FADR (PressureMax_FADR + PressureMax_LEN) +#define PressureMin_SADR (PressureMax_SADR + PressureMax_LEN) +#define PressureMin_LEN (sizeof(buf_PressureMin) + checkLen_1) +#define PressureMin_arrayNb gunNumber + +// +///ȫֻеֵ +#define buf_Medium uniGlobal.Medium +///ṹ嶨 +#define Medium_FADR (PressureMin_FADR + PressureMin_LEN) +#define Medium_SADR (PressureMin_SADR + PressureMin_LEN) +#define Medium_LEN (sizeof(buf_Medium) + checkLen_1) +#define Medium_arrayNb gunNumber +//ʾ +///ȫֻеֵ +#define buf_DispSet uniGlobal.DispSet +///ṹ嶨 +#define DispSet_FADR (Medium_FADR + Medium_LEN) +#define DispSet_SADR (Medium_SADR + Medium_LEN) +#define DispSet_LEN (sizeof(buf_DispSet) + checkLen_1) +#define DispSet_arrayNb gunNumber + +// +///ȫֻеֵ +#define buf_Compensation uniGlobal.Compensation +///ṹ嶨 +#define Compensation_FADR (DispSet_FADR + DispSet_LEN) +#define Compensation_SADR (DispSet_SADR + DispSet_LEN) +#define Compensation_LEN (sizeof(buf_Compensation) + checkLen_1) +#define Compensation_arrayNb gunNumber + +//RTCʱӵһο־ +///ȫֻеֵ +#define buf_RTCTimer_Flag uniGlobal.RTCTimer_Flag +///ṹ嶨 +#define RTCTimer_Flag_FADR (Compensation_FADR + Compensation_LEN) +#define RTCTimer_Flag_SADR (Compensation_SADR + Compensation_LEN) +#define RTCTimer_Flag_LEN (sizeof(buf_RTCTimer_Flag) + checkLen_1) +#define RTCTimer_Flag_arrayNb gunNumber + +//RTCʱӱ +///ȫֻеֵ +#define buf_RTCTimer_BKB uniGlobal.RTCTimer_BKB +///ṹ嶨 +#define RTCTimer_BKB_FADR (RTCTimer_Flag_FADR + RTCTimer_Flag_LEN) +#define RTCTimer_BKB_SADR (RTCTimer_Flag_SADR + RTCTimer_Flag_LEN) +#define RTCTimer_BKB_LEN (sizeof(buf_RTCTimer_BKB) + checkLen_1) +#define RTCTimer_BKB_arrayNb gunNumber + +//洢ñ +///ȫֻеֵ +#define buf_FRam_Flag uniGlobal.FRam_Flag +///ṹ嶨 +#define FRam_Flag_FADR (RTCTimer_BKB_FADR + RTCTimer_BKB_LEN) +#define FRam_Flag_SADR (RTCTimer_BKB_SADR + RTCTimer_BKB_LEN) +#define FRam_Flag_LEN (sizeof(buf_FRam_Flag) + checkLen_1) +#define FRam_Flag_arrayNb gunNumber + +typedef struct +{ + u32 volume; //volumesale ,ַ׵ַ + u32 sale; // + u32 price; // +}s_FuelRecord_Typedef; + +typedef struct +{ + union + { + u8 Global[100]; //ȫ + u16 Price[gunNumber]; // + + u64 M_SquadTop[gunNumber]; // + u64 V_SquadTop[gunNumber]; // + u64 S_SquadTop[gunNumber]; // + u64 MassTop[gunNumber]; // + u64 VolumeTop[gunNumber]; // + u64 SaleTop[gunNumber]; // + u64 StockTop[gunNumber]; //ж + u8 Decimal[3]; //С + u8 SystemTime[7]; //ϵͳʱ ʱ + u8 GasWorkMode[gunNumber]; //ģʽ + u32 PulseEqu[gunNumber]; //嵱 + u32 Density[gunNumber]; //ܶ + u16 MinDisp[gunNumber]; //Сʾ + u8 ValueTurnOff[gunNumber][50]; //ǰط + int8_t ValueOverShoot[gunNumber][2]; // + u32 TimeCount; //ʱ + s_FuelRecord_Typedef FuelRecord0[gunNumber];//μ + s_FuelRecord_Typedef FuelRecord1[gunNumber];//ǰμ + u32 TriesLimit; //Ƽʹ + + /*************************************/ + u8 GasAddr[gunNumber]; //ǰַ0ʼ˳ŶӦ + u16 GasScaleCoefficients[gunNumber]; //ϵ + u16 GasDensity[gunNumber]; //ܶ + u8 GasPourTo1[gunNumber]; //͵лֵ0-5 Ĭ 2 Kg/Min + u8 GasPour1To2[gunNumber]; //елֵ0-5 Ĭ 1.5Kg/Min + u8 GasFlowMax[gunNumber]; //ֵ0-90 Ĭ 50Kg/Min + u8 GasFlowMin[gunNumber]; //Сֵ0-90 Ĭ 50Kg/Min + + /******************ѹ******************/ + u16 PressureMax[gunNumber]; //ѹ0-40 Ĭ20MPa + u16 PressureMin[gunNumber]; //Сѹ + u16 Medium; // + u16 DispSet; //ʾ + float Compensation[gunNumber];// + + u8 RTCTimer_Flag; //RTC־ + u32 RTCTimer_BKB; //RTC + u8 FRam_Flag; + }u; + u8 CheckAdd; +}s_uniGlobal_Typedef; //洢д湲 + +typedef enum +{ + CF_Price, // + CF_M_SquadTop, // + CF_V_SquadTop, // + CF_S_SquadTop, // + CF_MassTop, // + CF_VolumeTop, // + CF_SaleTop, // + CF_StockTop, //ж + CF_Decimal, //С + CF_SystemTime, //ϵͳʱ + CF_GasWorkMode, //ģʽ + CF_PulseEqu, //嵱 + CF_Density, //ܶ + CF_MinDisp, //Сʾ + CF_ValueTurnOff, //ǰط + CF_ValueOverShoot, // + CF_TimeCount, //ʱ + CF_FuelRecord0, //μͼ¼ + CF_FuelRecord1, //ǰμͼ¼ + CF_TriesLimit, //Ƽʹ + CF_GasAddr, //Ƶַ + CF_GasScaleCoefficients, //Ʊϵ + CF_GasDensity, //ܶ + CF_GasPourTo1, //͵лֵ0-5 Ĭ 2 Kg/Min + CF_GasPour1To2, //͵лֵ0-5 Ĭ 2 Kg/Min + CF_GasFlowMax, //ֵ0-90 Ĭ 50Kg/Min + CF_GasFlowMin, //ֵ0-90 Ĭ 50Kg/Min + CF_PressureMax, //ѹ0-40 Ĭ20MPa + CF_Medium, // + CF_DispSet, //ʾ + CF_Compensation, // + CF_RTCTimer_Flag, + CF_RTCTimer_BKB, + + CF_FRam_Flag, //洢־ + FramItemEnd, +}FramItem; + +//******************************************************************************** +typedef struct +{ + u8* pInitData;//ʼָ + u8* upData; //ݻָ + u8* pData; //pGunָ + u16 firstAdr; //һַ + u16 secondAdr;//ڶַ + u8 len; // + u8 Tpye; // +}framDataIndex; + +void FM_Init(void); +u8 FMItemWrite(FramItem Type); +u8 FMItemRead(FramItem Type); +void FM_Data_Init(void); +#endif diff --git a/User/GPS/GPS.c b/User/GPS/GPS.c new file mode 100644 index 0000000..b25a443 --- /dev/null +++ b/User/GPS/GPS.c @@ -0,0 +1,403 @@ +#include "config.h" + +volatile u8 GPSConnectRXTask_Flag = 0;//GPSConnect־λ1 +volatile u8 GPSConnectTXTask_Flag = 0;// +volatile u8 GPSConnect_RX_Buff[1000] = {0x01,0x03,0x00,0x02,0x00,0x09,0x00,0x00};; +volatile u8 GPSConnect_TX_Buff[1000] = {0x01,0x03,0x00,0x02,0x00,0x09,0x00,0x00};; +volatile u8 GPSConnect_DMA_RX_Len = 23; +/*_____ D E F I N I T I O N __________________________________________________*/ + +u16 BigToLittle( u16 BigData) +{ + return (BigData << 8 | BigData >> 8); +} +//u32 BigToLittle( u32 BigData) +//{ +// union +// { +// u32 Temp; +// u8 Buff[4]; +// }Dat; +// +// if(sizeof(BigData) == 2) +// return (BigData << 8 | BigData >> 8); +// else if(sizeof(BigData) == 4) +// { +// Dat.Buff[0] = (BigData >> 24) & 0xff; +// Dat.Buff[1] = (BigData >> 16) & 0xff; +// Dat.Buff[2] = (BigData >> 8) & 0xff; +// Dat.Buff[3] = (BigData >> 0) & 0xff; +// return (Dat.Temp); +// } +//} +/**************************************************** +GPSConnect_IO_Configuration + GPSConnectͨѶõIOʼ + +ֵ +****************************************************/ +void GPSConnect_IO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; //GOIPýṹ + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); + + GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6); + GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOC, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//ͨģʽ + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;// + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// + GPIO_Init(GPIOC, &GPIO_InitStructure);//ʼ +} +/**************************************************** +GPSConnect_NVGPSConnect_Configuration + GPSConnectͨѶõж + +ֵ +****************************************************/ +void GPSConnect_NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; //жýṹ + + NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream6_IRQn; //USART6_TX_DMA + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + + NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn; //USART?? + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ???? + NVIC_Init(&NVIC_InitStructure); //??NVIC_InitStruct???????????NVIC???USART1 +} + + +/**************************************************** +GPSConnect_NVGPSConnect_Configuration + GPSConnectͨѶõĴ + +ֵ +****************************************************/ +void GPSConnect_USART_Configuration(u32 BaudRate) +{ + USART_InitTypeDef USART_InitStructure; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); + USART_InitStructure.USART_BaudRate =BaudRate;// Baud;//????? + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + USART_Init(USART6, &USART_InitStructure); + USART_Cmd(USART6, ENABLE); + + USART_ITConfig(USART6, USART_IT_IDLE, ENABLE); + USART_ClearFlag(USART6, USART_FLAG_IDLE); + + USART_DMACmd(USART6, USART_DMAReq_Tx | USART_DMAReq_Rx,ENABLE); + +} +/************************************************* + DMA_Configuration + DMAʼ + +ֵ +**************************************************/ +void GPSConnect_DMA_Configuration(void) +{ + DMA_InitTypeDef DMA_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); + + /*******************TX1*********************/ + DMA_DeInit(DMA2_Stream6); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + //DMA_InitStructure.DMA_BufferSize = UART_DMA_SEND_LEN; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART6->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_5; + //DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)MD_Connect_TX_Buff[0]; + + DMA_Init(DMA2_Stream6, &DMA_InitStructure); + DMA_ITConfig(DMA2_Stream6, DMA_IT_TC, ENABLE); + /*******************RX*********************/ + DMA_DeInit(DMA2_Stream1); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = 1000; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART6->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_5; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)GPSConnect_RX_Buff; + + DMA_Init(DMA2_Stream1, &DMA_InitStructure); + DMA_Cmd(DMA2_Stream1, ENABLE); + + +} +//F***************************************************************************** +//* NAME: GPSConnect_TXDataCheck +//* PURPOSE: GPSConnectͨУ麯 +//* PARAMS: pDataҪַlenݳ +//* return: +//****************************************************************************** +u8 GPSConnect_TXDataCheck(volatile u8* pData, u8 len) +{ + u8 result; + if(len == 0) len = 16; + result = *pData++; + do + { + result ^= *pData++; + }while(--len); + + return result & 0x7f; +} +void GPSConnect_DMATX_IRQHandler(void) +{ + u16 i = 0; + DMA_ClearFlag(DMA2_Stream6, DMA_IT_TCIF6); + GPSCount_TX_DMAStop(); //رDMA + while(! USART_GetFlagStatus(USART6, USART_FLAG_TC))NULL; + DMA_ClearFlag(DMA2_Stream1, DMA_IT_TCIF1); + GPSCount_RX_DMAStart(); //DMA(Gas)ѡͶʱ + GPSConnectTXTask_Flag = 1; +} +//F***************************************************************************** +//* NAME: GPSConnect_DMARX_IRQHandler +//* PURPOSE: DMAжϣGas ModBus +//* PARAMS: +//* return: +//****************************************************************************** + +void GPSConnect_DMARX_IRQHandler(void) +{ + u8 i = 0; + u16 CRC_Temp = 0; + if(USART_GetITStatus(USART6, USART_IT_IDLE) != RESET)//????????? + { + USART_ClearFlag(USART6, USART_IT_IDLE); + GPSCount_RX_DMAStop(); //DMA + USART_ClearFlag(USART6, USART_IT_IDLE); + DMA_ClearFlag(DMA2_Stream1, DMA_IT_TCIF1); + i = USART6->SR; + i = USART6->DR; + GPSCount_RX_DMALenSet(1000);//ýܳ + GPSCount_RX_DMAStart(); + GPSConnectRXTask_Flag = 1; + } +} +void StringToHex(u8 *Str,u8 *H,u8 Len) +{ + u8 i = 0; + for(i = 0;i < Len;i += 2) + { + if(*(Str + i) > 0x39) + *(H + (i / 2)) = (*(Str + i) - 0x37) << 4; + else + *(H + (i / 2)) = (*(Str + i) - 0x30) << 4; + + if(*(Str + i + 1) > 0x39) + *(H + (i / 2)) |= (*(Str + i + 1) - 0x37) & 0x0f; + else + *(H + (i / 2)) |= (*(Str + i + 1) - 0x30) & 0x0f; + } + } +u16 mystrstr(u8 *s1,u8 *s2) +{ + int len2; + u16 i= 0; + if(!(len2=strlen(s2)))//s2ָգstrlen޷ȣ + return 1; + for(;*s1;++s1) + { + i ++; + if(*s1==*s2 && strncmp(s1,s2,len2)==0) + return i; + } + return NULL; +} +//F***************************************************************************** +//* NAME: GPSConnect_Init +//* PURPOSE: GPSConnectͨѶʼ +//* PARAMS: +//* return: +//****************************************************************************** +char Bluetooth_AT_UART[]="AT+UART=9600\r\n "; +char Bluetooth_AT_NAME[]="AT+NAME=TXH_V1.1.2_0000\r\n "; +char Print_Language[]={0x1b,0x74,0x23}; +void GPSConnect_Init(void) +{ + u8 i = 0; + GPSConnect_IO_Configuration(); //IOʼ + GPSConnect_USART_Configuration(115200); //شڳʼ + GPSConnect_DMA_Configuration(); //DMAʼ + GPSConnect_NVIC_Configuration(); //жϳʼ + TXHData.GPSDataTimer.Init = 0; //ʼ־ + TXHData.GPSDataTimer.Flag = 0; //ʱ־ + TXHData.GPSDataTimer.ON_OFF = 1; // + TXHData.GPSDataTimer.Cycle = 1; //Ϊѭģʽʱ + TXHData.GPSDataTimer.TimerCountMax = 10*1000;//10S + + GPSCount_TX_DMAAddrSet((u32)Print_Language); + GPSCount_TX_DMALenSet(3); + GPSCount_TX_DMAStart(); +// while(!GPSConnectTXTask_Flag); +// delay_ms(500); +// GPSConnect_USART_Configuration(9600); +// for(i = 0;i < 10;i ++) +// Bluetooth_AT_NAME[8+i] = BoxVersion[i]; +// for(i = 0;i < 4;i ++) +// Bluetooth_AT_NAME[19+i] = TXHData.POSData.WirelessData.IMEI[16+i]; +// GPSCount_TX_DMAAddrSet((u32)Bluetooth_AT_NAME); +// GPSCount_TX_DMALenSet(25); +// GPSCount_TX_DMAStart(); +} + +void GPSConnectTast(void) +{ + u16 i = 0,j = 0,k = 0; + u32 Temp = 0; + u8 Buff[20]; + u16 POS_ConnectRX_Len=0; + u16 POS_ConnectRX_CMD = 0; + if(GPSConnectRXTask_Flag == 1) + { + GPSConnectRXTask_Flag = 0; + if(GPSConnect_RX_Buff[0] == 0xF5) // жϽջеĵһֽǷΪ 0xF5 + { + POS_ConnectRX_Len = (GPSConnect_RX_Buff[1] << 8) | GPSConnect_RX_Buff[2]; // ȡ + Temp = CRC_Check(&GPSConnect_RX_Buff[0] , POS_ConnectRX_Len); // ݰ CRC У + if(Temp == ((GPSConnect_RX_Buff[POS_ConnectRX_Len] << 8) | GPSConnect_RX_Buff[POS_ConnectRX_Len + 1])) // ж CRC УǷȷ + { + POS_ConnectRX_CMD = GPSConnect_RX_Buff[3]; // ȡֽ + switch (POS_ConnectRX_CMD) // ֽڽвͬIJ + { + case 0xF1: // APN + { + for(i = 0;i < sizeof(TXHData.POSData.WirelessData.APN);i ++) // APN + TXHData.POSData.WirelessData.APN[i] = 0; + for(i = 0;i < POS_ConnectRX_Len - 4;i ++) // ӽջȡ APN + TXHData.POSData.WirelessData.APN[i] = GPSConnect_RX_Buff[4+i]; + if(FMItemWrite(CF_POSData,0)) // д APN ݵ Flash 洢 + { + POS_Network_APN_Set(); // APN + GPSConnect_TX_Buff[0] = 0xF5; // ͻʼ + GPSConnect_TX_Buff[1] = 0x00; + GPSConnect_TX_Buff[2] = 0x05; + GPSConnect_TX_Buff[3] = 0xF1; + GPSConnect_TX_Buff[4] = 0x59; + Temp = CRC_Check(&GPSConnect_TX_Buff[0] , 5); // 㷢ݰ CRC У + GPSConnect_TX_Buff[5] = (Temp >> 8) & 0xff; // CRC Уд뷢ͻ + GPSConnect_TX_Buff[6] = Temp & 0xff; + GPSCount_TX_DMAAddrSet((u32)GPSConnect_TX_Buff); // ÷ DMA ĵַͳ + GPSCount_TX_DMALenSet(7); + GPSCount_TX_DMAStart(); // DMA + } + }break; + case 0xF2: // LORAģ + { + TXHData.MD_LORA_Slave_Flag = 1; + TXHData.MD_LORA_SlaveTimer.ON_OFF = 1; +// delay_ms(200); +// MD_Port_LORASet(0); +// MD_Port_LORASet(1); +// MD_Port_LORASet(2); +// MD_Port_LORASet(3); + { + GPSConnect_TX_Buff[0] = 0xF5; // ͻʼ + GPSConnect_TX_Buff[1] = 0x00; + GPSConnect_TX_Buff[2] = 0x05; + GPSConnect_TX_Buff[3] = 0xF2; + GPSConnect_TX_Buff[4] = 0x59; + Temp = CRC_Check(&GPSConnect_TX_Buff[0] , 5); // 㷢ݰ CRC У + GPSConnect_TX_Buff[5] = (Temp >> 8) & 0xff; // CRC Уд뷢ͻ + GPSConnect_TX_Buff[6] = Temp & 0xff; + GPSCount_TX_DMAAddrSet((u32)GPSConnect_TX_Buff); // ÷ DMA ĵַͳ + GPSCount_TX_DMALenSet(7); + GPSCount_TX_DMAStart(); // DMA + } + }break; + case 0xF3: // LORAģ + { + TXHData.MD_LORA_Slave_Flag = 0; + TXHData.MD_LORA_SlaveTimer.Init = 1; + { + GPSConnect_TX_Buff[0] = 0xF5; // ͻʼ + GPSConnect_TX_Buff[1] = 0x00; + GPSConnect_TX_Buff[2] = 0x05; + GPSConnect_TX_Buff[3] = 0xF3; + GPSConnect_TX_Buff[4] = 0x59; + Temp = CRC_Check(&GPSConnect_TX_Buff[0] , 5); // 㷢ݰ CRC У + GPSConnect_TX_Buff[5] = (Temp >> 8) & 0xff; // CRC Уд뷢ͻ + GPSConnect_TX_Buff[6] = Temp & 0xff; + GPSCount_TX_DMAAddrSet((u32)GPSConnect_TX_Buff); // ÷ DMA ĵַͳ + GPSCount_TX_DMALenSet(7); + GPSCount_TX_DMAStart(); // DMA + } + }break; + } + } + } + else if(GPSConnect_RX_Buff[25] == 'O' && GPSConnect_RX_Buff[26] == 'K') // жϽջСOK\r\nжDzûظ + { + TXHData.USART6_Drive = Bluetooth; + } + else + { + Temp = mystrstr(GPSConnect_RX_Buff,"RMC"); + if(Temp) + TXHData.USART6_Drive = GPS; + if(GPSConnect_RX_Buff[Temp + 14] == 'A')//ȡȺγϢ + { + for(k = 0;k < 9;k ++)// ȡϢ浽TXHDataṹ + Buff[k] = GPSConnect_RX_Buff[Temp + 16 + k]; + TXHData.GPSData.GPS.Longitude = (float)atof(Buff) / 100; + TXHData.GPSData.GPS.LongitudeType = GPSConnect_RX_Buff[Temp + 26]; + + for(k = 0;k < 9;k ++)// ȡάϢ浽TXHDataṹ + Buff[k] = GPSConnect_RX_Buff[Temp + 28 + k]; + TXHData.GPSData.GPS.Latitude = (float)atof(Buff) / 100; + TXHData.GPSData.GPS.LatitudeType = GPSConnect_RX_Buff[Temp + 39]; + } + else if(GPSConnect_RX_Buff[Temp + 14] == 'V')// 15ַ'V'γϢЧΪ0 + { + TXHData.GPSData.GPS.Latitude = 0; + TXHData.GPSData.GPS.LatitudeType = 0; + TXHData.GPSData.GPS.Latitude = 0; + TXHData.GPSData.GPS.LatitudeType = 0; + } + } + } +} + diff --git a/User/GPS/GPS.h b/User/GPS/GPS.h new file mode 100644 index 0000000..9484e49 --- /dev/null +++ b/User/GPS/GPS.h @@ -0,0 +1,57 @@ +#ifndef __GPS_H_ +#define __GPS_H_ +/*H****************************************************************************** +* NAME: GPSConnect.h +*********************************************************************************/ + +typedef union +{ + u8 Buff[50]; //ModBusĴ + __packed struct + { + u8 GPSNum : 8; + u8 Cmd : 8; + u8 Len : 8; + u16 OHi : 16; + u16 OHd : 16; + u16 Crc : 16; + }Register; + __packed struct + { + u8 GPSNum : 8; + u8 Cmd : 8; + u16 Addr : 16; + u16 Dat : 16; + u16 Crc : 16; + }Register_W; +}GPS_RX_Buff_Type; + +typedef enum +{ + Edle, + Bluetooth , + GPS , +}USARTDriveItem; +//****************************************************************************** +//Ӳ + +#define GPSCount_TX_DMAAddrSet(x) (DMA2_Stream6->M0AR = x) //Ʒͻַ +#define GPSCount_TX_DMALenSet(x) (DMA2_Stream6->NDTR = x) //DMAͳ +#define GPSCount_TX_DMAStart() DMA_Cmd(DMA2_Stream6,ENABLE) ;GPSConnectTXTask_Flag = 0; //DMA +#define GPSCount_TX_DMAStop() DMA_Cmd(DMA2_Stream6,DISABLE) //رDMA + +#define GPSCount_RX_DMAAddrSet(x) (DMA2_Stream1->M0AR = x) //ƽջַ +#define GPSCount_RX_DMALenSet(x) (DMA2_Stream1->NDTR = x) //DMA +#define GPSCount_RX_DMAStart() DMA_Cmd(DMA2_Stream1,ENABLE) //DMA +#define GPSCount_RX_DMAStop() DMA_Cmd(DMA2_Stream1,DISABLE) //رDMA +extern volatile u8 GPSConnectTXTask_Flag;// +extern void GPSConnect_DMATX_IRQHandler(void); +extern void GPSConnect_DMARX_IRQHandler(void); +extern u16 mystrstr(u8 *s1,u8 *s2); +extern void StringToHex(u8 *Str,u8 *H,u8 Len); +extern u16 CRC_Check(u8 *puchMsg, u16 usDataLen) ; +extern u16 BigToLittle( u16 BigData); +extern void GPSConnect_Init(void); +extern void GPSConnect_USART_Configuration(u32 BaudRate); +extern void GPSConnectTast(void); +#endif //#ifndef diff --git a/User/Log/Log.c b/User/Log/Log.c new file mode 100644 index 0000000..26dc012 --- /dev/null +++ b/User/Log/Log.c @@ -0,0 +1,201 @@ +/*C***************************************************************************** +* NAME: DOBCNT1010.c +*------------------------------------------------------------------------------- +* RELEASE: +* REVISION: 1.0 +*------------------------------------------------------------------------------- +* PURPOSE: +* ˫ǹӦó +*******************************************************************************/ + +#include "config.h" + +u8 DiskFileOpen_Flag = 0; +u64 File_Len=0; + +void Log_Init(void) +{ + u8 i= 0; + mInitCH376Host(); + delay_ms(100); + +} +/* +const char CMD_WifiWSSSID[]="AT+WSSSID=KFB-2.4G\r\n"; +const char CMD_WifiWSKEY[]="AT+WSKEY=WPA2PSK,AES,KFB123456\r\n"; +const char CMD_WifiNETP[]="AT+NETP=TCP,CLIENT,7011,test.joyfueling.com\r\n"; +*/ +u8 SysconfigFileName[20] = "\\SYSTEM.TXT"; +u16 EndLen=0,StartLen=0; +u8 FindSysconfigFile(void) +{ + u16 i=0; + + u8 Next[] = {0x0D,0x0A}; + u8 Buff[1000]; + u16 pLocate = 0; + { + if(CH376DiskConnect() == USB_INT_SUCCESS)/* UǷ */ + { + DiskFileOpen_Flag = CH376FileOpen(SysconfigFileName); + if(DiskFileOpen_Flag == USB_INT_SUCCESS) + { + File_Len = CH376GetFileSize(); + { + CH376ByteLocate(pLocate); + CH376ByteRead(Buff,500,&pLocate); + + StartLen = mystrstr(Buff,"APN="); + if(StartLen) + { + for(i = 0;i < 40;i ++) + TXHData.POSData.WirelessData.APN[i] = 0; + EndLen = mystrstr(&Buff[StartLen],";"); + for(i = 0;i < EndLen-4;i ++) + TXHData.POSData.WirelessData.APN[i] = Buff[StartLen + 3 + i]; + } + StartLen = mystrstr(Buff,"WIFINAME="); + if(StartLen) + { + for(i = 0;i < 40;i ++) + TXHData.POSData.WirelessData.WiFIName[i] = 0; + EndLen = mystrstr(&Buff[StartLen],";"); + for(i = 0;i < EndLen-9;i ++) + TXHData.POSData.WirelessData.WiFIName[i] = Buff[StartLen + 8 + i]; + } + StartLen = mystrstr(Buff,"WIFIPASSWORD="); + if(StartLen) + { + for(i = 0;i < 20;i ++) + TXHData.POSData.WirelessData.WiFIPassWord[i] = 0; + EndLen = mystrstr(&Buff[StartLen],";"); + for(i = 0;i < EndLen-13;i ++) + TXHData.POSData.WirelessData.WiFIPassWord[i] = Buff[StartLen + 12 + i]; + } + StartLen = mystrstr(Buff,"SERVER="); + if(StartLen) + { +// if(TXHData.POS_Info.NetType == POS_Net_Typ_WiFi) +// { + for(i = 0;i < 50;i ++) + TXHData.POSData.WirelessData.CMD_SOCKA[i] = 0; + EndLen = mystrstr(&Buff[StartLen],";"); + for(i = 0;i < EndLen-7;i ++) + TXHData.POSData.WirelessData.CMD_SOCKA[i] = Buff[StartLen + 6 + i]; +// } +// else +// { +// for(i = 13;i < 50;i ++) +// TXHData.POSData.WirelessData.CMD_SOCKA[i] = 0; +// EndLen = mystrstr(&Buff[StartLen],";"); +// for(i = 0;i < EndLen-7;i ++) +// TXHData.POSData.WirelessData.CMD_SOCKA[13+i] = Buff[StartLen + 6 + i]; +// strcat(TXHData.POSData.WirelessData.CMD_SOCKA, "\r\n\0"); +// } + } + FMItemWrite(CF_POSData,0); + } + CH376FileClose(TRUE); + return 1; + } + else + { + if(DiskFileOpen_Flag == ERR_MISS_FILE) + CH376FileCreate(SysconfigFileName); + else + { + CH376FileClose(TRUE); + DiskFileOpen_Flag = 0; + } + } + } + else + { + TXHData.UDisk_Flag = 0; + mInitCH376Host(); + } + } +} + u8 LogName[5][25] = { + "\\M1_0000.TXT", + "\\M2_0000.TXT", + "\\M3_0000.TXT", + "\\M4_0000.TXT", + "\\POS0000.TXT", + }; +void Log_Task(u8 *pBuff,u16 Len,u8 port,u8 Source) +{ + u16 i=0,Temp16=0; + + u8 Next[] = {0x0D,0x0A}; + u8 Buff[2000]; + u16 pLocate = 0; + if(port <= 4) + { + LogName[port][4] = ((TXHData.CTIME.Month >> 4) & 0x0f) + 0x30; + LogName[port][5] = (TXHData.CTIME.Month & 0x0f) + 0x30; + LogName[port][6] = ((TXHData.CTIME.Day >> 4) & 0x0f) + 0x30; + LogName[port][7] = (TXHData.CTIME.Day & 0x0f) + 0x30; + if(CH376DiskConnect() == USB_INT_SUCCESS)/* UǷ */ + { + if(DiskFileOpen_Flag != DEF_DISK_OPEN_FILE) + DiskFileOpen_Flag = CH376FileOpen(LogName[port]); + if(DiskFileOpen_Flag == DEF_DISK_OPEN_FILE) + { + if(Len > 1000) + Len = 1000; + File_Len = CH376GetFileSize(); + CH376ByteLocate(File_Len); + Buff[0] = ((TXHData.CTIME.Day >> 4) & 0x0f) + 0x30; + Buff[1] = (TXHData.CTIME.Day & 0x0f) + 0x30; + Buff[2] = ((TXHData.CTIME.Hour >> 4) & 0x0f) + 0x30; + Buff[3] = (TXHData.CTIME.Hour & 0x0f) + 0x30; + Buff[4] = ((TXHData.CTIME.Min >> 4) & 0x0f) + 0x30; + Buff[5] = (TXHData.CTIME.Min & 0x0f) + 0x30; + Buff[6] = ((TXHData.CTIME.Sec >> 4) & 0x0f) + 0x30; + Buff[7] = (TXHData.CTIME.Sec & 0x0f) + 0x30; + if(Source == Info_String) + { + Buff[8] = ':'; + for(i = 0;i < Len;i ++) + Buff[i+9] = *(pBuff + i); + CH376ByteWrite(Buff,Len + 9,&pLocate); + } + else + { + if(Source == Info_Issue) + Buff[8] = 'T'; + else if(Source == Info_Receive) + Buff[8] = 'R'; + Buff[9] = ':'; + for(i = 0;i < Len * 2;i += 2) + { + Temp16 = *(pBuff + i / 2) >> 4; + Buff[i + 10] = Temp16 + 0x30 + (Temp16 / 10) * 7; + Temp16 = *(pBuff + i / 2) & 0x0f; + Buff[i+11] = Temp16 + 0x30 + (Temp16 / 10) * 7; + } + CH376ByteWrite(Buff,Len*2 + 10,&pLocate); + } + CH376ByteWrite(Next,2,&pLocate); + CH376FileClose(TRUE); + DiskFileOpen_Flag = 0; + } + else + { + if(DiskFileOpen_Flag == ERR_MISS_FILE) + CH376FileCreate(LogName[port]); + else + { + CH376FileClose(TRUE); + DiskFileOpen_Flag = 0; + } + } + } + else + { + TXHData.UDisk_Flag = 0; + mInitCH376Host(); + } + } + } diff --git a/User/Log/Log.h b/User/Log/Log.h new file mode 100644 index 0000000..3b42ce2 --- /dev/null +++ b/User/Log/Log.h @@ -0,0 +1,16 @@ +#ifndef __Log_H__ +#define __Log_H__ + +typedef enum +{ + Info_Issue, + Info_Receive, + Info_String, +}Log_Info_Typ; + +void Log_Init(void); +void Log_Task(u8 *pBuff,u16 Len,u8 port,u8 Source); +u8 FindSysconfigFile(void); +//------------------------------------------------------------------------------ + +#endif diff --git a/User/MD_Connect/MD_Connect.c b/User/MD_Connect/MD_Connect.c new file mode 100644 index 0000000..6417eb2 --- /dev/null +++ b/User/MD_Connect/MD_Connect.c @@ -0,0 +1,7480 @@ +/*C***************************************************************************** + * NAME: .c + *------------------------------------------------------------------------------- + * RELEASE: + * REVISION: 1.0 + *------------------------------------------------------------------------------- + * PURMDE: + * + *******************************************************************************/ + +/*_____ I N C L U D E S ______________________________________________________*/ + +#include "config.h" //ȫ + +/*_____ M A C R O S __________________________________________________________*/ + +volatile u8 MD_ConnectRX1Task_Flag = 0; // MD_ConnectͨѶ־λ1 +volatile u8 MD_ConnectRX2Task_Flag = 0; // MD_ConnectͨѶ־λ1 +volatile u8 MD_ConnectRX3Task_Flag = 0; // MD_ConnectͨѶ־λ1 +volatile u8 MD_ConnectRX4Task_Flag = 0; // MD_ConnectͨѶ־λ1 + +/***********************WIFI*************************/ +const char MD_WifiWSSSID[] = "AT+WAP=TXH04,45535142,1\r\n"; +const char MD_WifiSOCKET[] = "AT+Socket=0,3,192.168.4.1,50000\r\n"; +const char MD_WifiRSSI[] = "AT+CWJAP?\r\n"; +const char MD_WifiRST[] = "AT+RES\r\n"; +const char MD_ATRec[] = "AT+E=OFF\r\n"; +const char MD_WMODE[] = "AT+WMODE=AP\r\n"; +/*******************************L510ָ*** + +/*_____ D E F I N I T I O N __________________________________________________*/ + +volatile u8 MD_Connect_TX_Buff[4][600]; // MD_Connectͻ棬DMAʽ +volatile u8 MD_Connect_RX_Buff[4][1000]; // MD_Connectܻ + +volatile u8 MD_Connect_TX_Flag = 1; // MD_ConnectͨѶDMA־ +/*_____ D E C L A R A T I O N ________________________________________________*/ +LORA_Set_Type LORA_Set[4]; + +unsigned short crc16_ccitt_table[256] = + { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78}; + +unsigned short do_crc(unsigned char *message, unsigned int len) +{ + unsigned short crc_reg = 0; + + while (len--) + crc_reg = (crc_reg >> 8) ^ crc16_ccitt_table[(crc_reg ^ *message++) & 0xff]; + + return crc_reg; +} +/**************************************************** +MD_Connect_IO_Configuration + MD_ConnectͨѶõIOʼ + +ֵ +****************************************************/ +void MD_Connect_IO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; // GOIPýṹ + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); + + GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3); + GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4); + GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5); + GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_8 | GPIO_Pin_9; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOD, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOC, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_10; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOD, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_12 | GPIO_Pin_11; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOG, &GPIO_InitStructure); + MD_Connect_LORA_IdleMode1; + MD_Connect_LORA_IdleMode2; + MD_Connect_LORA_IdleMode3; + MD_Connect_LORA_IdleMode4; +} +/**************************************************** +MD_Connect_NVMD_Connect_Configuration + MD_ConnectͨѶõж + +ֵ +****************************************************/ +void MD_Connect_NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; // жýṹ + + // USART2_DMA + NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream6_IRQn; // USART2_TX_DMA + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; // USART2 + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // + NVIC_Init(&NVIC_InitStructure); // + + // USART3_DMA + NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream3_IRQn; // USART2_TX_DMA + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; // USART2 + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // + NVIC_Init(&NVIC_InitStructure); // + + // USART4_DMA + NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream4_IRQn; // USART2_TX_DMA + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn; // USART2 + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // + NVIC_Init(&NVIC_InitStructure); // + + // USART5_DMA + NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream7_IRQn; // USART2_TX_DMA + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; // USART2 + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // + NVIC_Init(&NVIC_InitStructure); // +} + +/**************************************************** +MD_Connect_NVMD_Connect_Configuration + MD_ConnectͨѶõĴ + +ֵ +****************************************************/ +void MD_Connect_USART_Configuration(u8 PortNum, u32 Baud, u16 USART_WordLength, u8 Check) +{ + USART_InitTypeDef USART_InitStructure; + + switch (PortNum) + { + case 0: + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); + USART_InitStructure.USART_BaudRate = Baud; // Baud;//????? + if (Check == Check_EVEN) + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + USART_InitStructure.USART_Parity = USART_Parity_Even; + } + else if (Check == Check_ODD) + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + USART_InitStructure.USART_Parity = USART_Parity_Odd; + } + else if (Check == Check_NONE) + { + USART_InitStructure.USART_WordLength = USART_WordLength; + USART_InitStructure.USART_Parity = USART_Parity_No; + } + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + USART_Init(USART2, &USART_InitStructure); + USART_Cmd(USART2, ENABLE); + USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); + USART_ClearFlag(USART2, USART_FLAG_IDLE); + + USART_DMACmd(USART2, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE); + } + break; + case 1: + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); + USART_InitStructure.USART_BaudRate = Baud; // Baud;//????? + if (Check == Check_EVEN) + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + USART_InitStructure.USART_Parity = USART_Parity_Even; + } + else if (Check == Check_ODD) + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + USART_InitStructure.USART_Parity = USART_Parity_Odd; + } + else if (Check == Check_NONE) + { + USART_InitStructure.USART_WordLength = USART_WordLength; + USART_InitStructure.USART_Parity = USART_Parity_No; + } + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + USART_Init(UART4, &USART_InitStructure); + USART_Cmd(UART4, ENABLE); + + USART_ITConfig(UART4, USART_IT_IDLE, ENABLE); + USART_ClearFlag(UART4, USART_FLAG_IDLE); + + USART_DMACmd(UART4, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE); + } + break; + case 2: + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); + USART_InitStructure.USART_BaudRate = Baud; // Baud;//????? + if (Check == Check_EVEN) + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + USART_InitStructure.USART_Parity = USART_Parity_Even; + } + else if (Check == Check_ODD) + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + USART_InitStructure.USART_Parity = USART_Parity_Odd; + } + else if (Check == Check_NONE) + { + USART_InitStructure.USART_WordLength = USART_WordLength; + USART_InitStructure.USART_Parity = USART_Parity_No; + } + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + USART_Init(UART5, &USART_InitStructure); + USART_Cmd(UART5, ENABLE); + + USART_ITConfig(UART5, USART_IT_IDLE, ENABLE); + USART_ClearFlag(UART5, USART_FLAG_IDLE); + + USART_DMACmd(UART5, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE); + } + break; + case 3: + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); + USART_InitStructure.USART_BaudRate = Baud; // Baud;//????? + if (Check == Check_EVEN) + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + USART_InitStructure.USART_Parity = USART_Parity_Even; + } + else if (Check == Check_ODD) + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + USART_InitStructure.USART_Parity = USART_Parity_Odd; + } + else if (Check == Check_NONE) + { + USART_InitStructure.USART_WordLength = USART_WordLength; + USART_InitStructure.USART_Parity = USART_Parity_No; + } + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + USART_Init(USART3, &USART_InitStructure); + USART_Cmd(USART3, ENABLE); + + USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); + USART_ClearFlag(USART3, USART_FLAG_IDLE); + + USART_DMACmd(USART3, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE); + } + break; + } +} +/************************************************* + DMA_Configuration + DMAʼ + +ֵ +**************************************************/ +void MD_Connect_DMA_Configuration(u8 Port, u8 DateSize) +{ + DMA_InitTypeDef DMA_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); + switch (Port) + { + case 0: + { + /*******************TX1*********************/ + DMA_DeInit(DMA1_Stream6); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + // DMA_InitStructure.DMA_BufferSize = UART_DMA_SEND_LEN; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + if (DateSize == 8) + { + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + } + else if (DateSize == 16) + { + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; + } + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)MD_Connect_TX_Buff[0]; + + DMA_Init(DMA1_Stream6, &DMA_InitStructure); + DMA_ITConfig(DMA1_Stream6, DMA_IT_TC, ENABLE); + // DMA_Cmd(DMA1_Stream3, ENABLE); + + /*******************RX1*********************/ + DMA_DeInit(DMA1_Stream5); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = 1000; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)MD_Connect_RX_Buff[0]; + + DMA_Init(DMA1_Stream5, &DMA_InitStructure); + DMA_Cmd(DMA1_Stream5, ENABLE); + } + break; + case 1: + { + /*******************TX2*********************/ + DMA_DeInit(DMA1_Stream4); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + // DMA_InitStructure.DMA_BufferSize = UART_DMA_SEND_LEN; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + if (DateSize == 8) + { + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + } + else if (DateSize == 16) + { + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; + } + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&UART4->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)MD_Connect_TX_Buff[1]; + + DMA_Init(DMA1_Stream4, &DMA_InitStructure); + DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, ENABLE); + // DMA_Cmd(DMA1_Stream3, ENABLE); + + /*******************RX2*********************/ + DMA_DeInit(DMA1_Stream2); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = 1000; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&UART4->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)MD_Connect_RX_Buff[1]; + + DMA_Init(DMA1_Stream2, &DMA_InitStructure); + DMA_Cmd(DMA1_Stream2, ENABLE); + } + break; + case 2: + { + /*******************TX3*********************/ + DMA_DeInit(DMA1_Stream7); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + // DMA_InitStructure.DMA_BufferSize = UART_DMA_SEND_LEN; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + if (DateSize == 8) + { + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + } + else if (DateSize == 16) + { + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; + } + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&UART5->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)MD_Connect_TX_Buff[2]; + + DMA_Init(DMA1_Stream7, &DMA_InitStructure); + DMA_ITConfig(DMA1_Stream7, DMA_IT_TC, ENABLE); + // DMA_Cmd(DMA1_Stream7, ENABLE); + + /*******************RX3*********************/ + DMA_DeInit(DMA1_Stream0); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = 1000; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&UART5->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)MD_Connect_RX_Buff[2]; + + DMA_Init(DMA1_Stream0, &DMA_InitStructure); + DMA_Cmd(DMA1_Stream0, ENABLE); + } + break; + case 3: + { + /*******************TX4*********************/ + DMA_DeInit(DMA1_Stream3); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + // DMA_InitStructure.DMA_BufferSize = UART_DMA_SEND_LEN; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + if (DateSize == 8) + { + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + } + else if (DateSize == 16) + { + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; + } + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)MD_Connect_TX_Buff[3]; + + DMA_Init(DMA1_Stream3, &DMA_InitStructure); + DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, ENABLE); + // DMA_Cmd(DMA1_Stream3, ENABLE); + + /*******************RX4*********************/ + DMA_DeInit(DMA1_Stream1); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = 1000; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)MD_Connect_RX_Buff[3]; + + DMA_Init(DMA1_Stream1, &DMA_InitStructure); + DMA_Cmd(DMA1_Stream1, ENABLE); + } + break; + } +} +// F***************************************************************************** +//* NAME: MD_Connect_DMATX_IRQHandler +//* PURMDE: MD_ConnectͨѶDMAж +//* PARAMS: +//* return: +//****************************************************************************** +void MD_Connect_DMATX1_IRQHandler(void) +{ + u16 i = 0; + DMA_ClearFlag(DMA1_Stream6, DMA_IT_TCIF6); + MD_Connect_TX1_DMAStop(); // رDMA + while (!USART_GetFlagStatus(USART2, USART_FLAG_TC)) + NULL; + MD_Connect_RS485_Rx1EN; + DMA_ClearFlag(DMA1_Stream5, DMA_IT_TCIF5); + MD_Connect_RX1_DMAStart(); // DMA(Gas)ѡͶʱ + MD_Connect_TX_Flag = 1; +} +// F***************************************************************************** +//* NAME: MD_Connect_DMARX_IRQHandler +//* PURMDE: DMAжϣGas ModBus +//* PARAMS: +//* return: +//****************************************************************************** +volatile u8 DTTDYS = 0; +void MD_Connect_DMARX1_IRQHandler(void) +{ + u8 i = 0; + if (USART_GetITStatus(USART2, USART_IT_IDLE) == SET) //????????? + { + i = USART2->SR; + i = USART2->DR; + USART_ClearFlag(USART2, USART_IT_IDLE); + TXHData.MBCountRXIDLETimer[0].ON_OFF = 1; + TXHData.MD_Rec_NummberB[0] = 1000 - DMA1_Stream5->NDTR; + // MD_Connect_RX1_DMAStop(); //رDMA + // DMA_ClearFlag(DMA1_Stream5, DMA_IT_TCIF5); + // MD_ConnectRX1Task_Flag = 1; //ʹGas + // MD_Connect_RX1_DMALenSet(1000);//ýܳ + // MD_Connect_RX1_DMAStart(); //DMA + } +} +// F***************************************************************************** +//* NAME: MD_Connect_DMATX_IRQHandler +//* PURMDE: MD_ConnectͨѶDMAж +//* PARAMS: +//* return: +//****************************************************************************** +void MD_Connect_DMATX2_IRQHandler(void) +{ + u16 i = 0; + DMA_ClearFlag(DMA1_Stream4, DMA_IT_TCIF4); + MD_Connect_TX2_DMAStop(); // رDMA + while (!USART_GetFlagStatus(UART4, USART_FLAG_TC)) + NULL; + MD_Connect_RS485_Rx2EN; + DMA_ClearFlag(DMA1_Stream2, DMA_IT_TCIF2); + MD_Connect_RX2_DMAStart(); // DMA(Gas)ѡͶʱ + MD_Connect_TX_Flag = 1; +} +// F***************************************************************************** +//* NAME: MD_Connect_DMARX_IRQHandler +//* PURMDE: DMAжϣGas ModBus +//* PARAMS: +//* return: +//****************************************************************************** +void MD_Connect_DMARX2_IRQHandler(void) +{ + u8 i = 0; + if (USART_GetITStatus(UART4, USART_IT_IDLE) == SET) //????????? + { + i = UART4->SR; + i = UART4->DR; + TXHData.MBCountRXIDLETimer[1].ON_OFF = 1; + TXHData.MD_Rec_NummberB[1] = 1000 - DMA1_Stream2->NDTR; + // MD_Connect_RX2_DMAStop(); //رDMA + // DMA_ClearFlag(DMA1_Stream2, DMA_IT_TCIF2); + // MD_ConnectRX2Task_Flag = 1; //ʹGas + // MD_Connect_RX2_DMALenSet(1000);//ýܳ + // MD_Connect_RX2_DMAStart(); //DMA + } +} +// F***************************************************************************** +//* NAME: MD_Connect_DMATX_IRQHandler +//* PURMDE: MD_ConnectͨѶDMAж +//* PARAMS: +//* return: +//****************************************************************************** +void MD_Connect_DMATX3_IRQHandler(void) +{ + u16 i = 0; + DMA_ClearFlag(DMA1_Stream7, DMA_IT_TCIF7); + MD_Connect_TX3_DMAStop(); // رDMA + while (!USART_GetFlagStatus(UART5, USART_FLAG_TC)) + NULL; + MD_Connect_RS485_Rx3EN; + DMA_ClearFlag(DMA1_Stream0, DMA_IT_TCIF0); + MD_Connect_RX3_DMAStart(); // DMA(Gas)ѡͶʱ + MD_Connect_TX_Flag = 1; +} +// F***************************************************************************** +//* NAME: MD_Connect_DMARX_IRQHandler +//* PURMDE: DMAжϣGas ModBus +//* PARAMS: +//* return: +//****************************************************************************** +void MD_Connect_DMARX3_IRQHandler(void) +{ + u8 i = 0; + if (USART_GetITStatus(UART5, USART_IT_IDLE) == SET) //????????? + { + i = UART5->SR; + i = UART5->DR; + TXHData.MBCountRXIDLETimer[2].ON_OFF = 1; + TXHData.MD_Rec_NummberB[2] = 1000 - DMA1_Stream0->NDTR; + // MD_Connect_RX3_DMAStop(); //رDMA + // DMA_ClearFlag(DMA1_Stream0, DMA_IT_TCIF0); + // MD_ConnectRX3Task_Flag = 1; //ʹGas + // MD_Connect_RX3_DMALenSet(1000);//ýܳ + // MD_Connect_RX3_DMAStart(); //DMA + } +} +// F***************************************************************************** +//* NAME: MD_Connect_DMATX_IRQHandler +//* PURMDE: MD_ConnectͨѶDMAж +//* PARAMS: +//* return: +//****************************************************************************** +void MD_Connect_DMATX4_IRQHandler(void) +{ + u16 i = 0; + DMA_ClearFlag(DMA1_Stream3, DMA_IT_TCIF3); + MD_Connect_TX4_DMAStop(); // رDMA + while (!USART_GetFlagStatus(USART3, USART_FLAG_TC)) + NULL; + MD_Connect_RS485_Rx4EN; + DMA_ClearFlag(DMA1_Stream1, DMA_IT_TCIF1); + MD_Connect_RX4_DMAStart(); // DMA(Gas)ѡͶʱ + MD_Connect_TX_Flag = 1; +} +// F***************************************************************************** +//* NAME: MD_Connect_DMARX_IRQHandler +//* PURMDE: DMAжϣGas ModBus +//* PARAMS: +//* return: +//****************************************************************************** +void MD_Connect_DMARX4_IRQHandler(void) +{ + u8 i = 0; + if (USART_GetITStatus(USART3, USART_IT_IDLE) == SET) //????????? + { + i = USART3->SR; + i = USART3->DR; + TXHData.MBCountRXIDLETimer[3].ON_OFF = 1; + TXHData.MD_Rec_NummberB[3] = 1000 - DMA1_Stream1->NDTR; + // MD_Connect_RX4_DMAStop(); //رDMA + // DMA_ClearFlag(DMA1_Stream1, DMA_IT_TCIF1); + // MD_ConnectRX4Task_Flag = 1; //ʹGas + // MD_Connect_RX4_DMALenSet(1000);//ýܳ + // MD_Connect_RX4_DMAStart(); //DMA + } +} +// F***************************************************************************** +//* NAME: LTMD_TXDataCheck +//* PURMDE: LTMDͨУ麯 +//* PARAMS: pDataҪַlenݳ +//* return: +//****************************************************************************** +u8 MD_Connect_TXDataCheck(volatile u8 *pData, u16 len) +{ + u8 result; + if (len == 0) + len = 16; + result = *pData++; + do + { + result ^= *pData++; + } while (--len); + + return result & 0x7f; +} + +u8 InteiHEXCheck(volatile u8 *pData, u16 len) +{ + u8 i; + u8 checksum = 0; + + for (i = 0; i < len; i++) + { + checksum += *pData++; + } + return (0 - checksum); +} +// F***************************************************************************** +//* NAME: MD_Connect_u64ToBCD +//* PURMDE: u64תBCD +//* PARAMS: pDataҪתݣLen +//* return: BCD +//****************************************************************************** +u64 MD_Connect_u64ToBCD(u64 Dat) +{ + u8 i = 0; + u64 T64 = 0, Temp = 0; + u8 *pData; + pData = (u8 *)&T64; + for (i = 0; i < 8; i++) + { + Temp = Dat % 100; + *(pData + i) = ((Temp / 10) << 4) + ((Temp % 10) & 0x0F); + Dat /= 100; + } + + return T64; +} +/**************TCP/IPУͣICͨѶ***************/ +u16 CheckSum(u8 *buf, u16 nword) +{ + unsigned long long sum; + + for (sum = 0; nword > 0; nword--) + sum += *buf++; + + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + + return ~sum; +} +u8 CheckSum8(u8 *buf, u8 len) // BCCУ麯 +{ + u8 i; + u8 checksum = 0; + + for (i = 0; i < len; i++) + { + checksum += *buf++; + } + return checksum; +} +u16 TrueCharBuffSize(char *Buff) +{ + u16 i = 0; + while (*(Buff++)) + i++; + return i; +} +/*************ַת******************/ +float StrToFloat(u8 *str, u8 len) +{ + u8 i = 0; + int Temp = 0; + float TempF = 0; + u8 *Pi = (u8 *)&Temp; + u8 *Pf = (u8 *)&TempF; + for (i = 0; i < len; i++) + { + if (*(str + i) >= 0x30 && *(str + i) < 0x40) + { + Temp = Temp << 4; + Temp |= *(str + i) - 0x30; + } + else if (*(str + i) > 0x40 && *(str + i) < 0x47) + { + Temp = Temp << 4; + Temp |= *(str + i) - 0x37; + } + else + return -1; + } + for (i = 0; i < len / 2; i++) + *(Pf + i) = *(Pi + i); + return TempF; +} +/*************ַת******************/ +int StrToInt(u8 *str, u8 len) +{ + u8 i = 0; + int Temp = 0; + + for (i = 0; i < len; i++) + { + if (*(str + i) >= 0x30 && *(str + i) < 0x40) + { + Temp = Temp << 4; + Temp |= *(str + i) - 0x30; + } + else if (*(str + i) > 0x40 && *(str + i) < 0x47) + { + Temp = Temp << 4; + Temp |= *(str + i) - 0x37; + } + else + return -1; + } + + return Temp; +} +// F***************************************************************************** +//* NAME: MD_Connect_BCDTou64 +//* PURMDE: BCDתu64 +//* PARAMS: pDataҪתݣLen +//* return: u64 +//****************************************************************************** +u64 MD_Connect_BCDTou64(u64 Dat) +{ + u8 i = 0; + u64 T64 = 0; + u8 Temp; + for (i = 0; i < 8; i++) + { + Temp = Dat >> (8 * i); + T64 += ((Temp >> 4) * 10 + (Temp & 0x0f)) * pow(100, i); + } + return T64; +} +u8 BCC_CheckSum(u8 *buf, u8 len) // BCCУ麯 +{ + u8 i; + u8 checksum = 0; + + for (i = 0; i < len; i++) + { + checksum ^= *buf++; + } + + return checksum; +} +// ܺ +void Bluesky_Encrypt(unsigned char *data, unsigned int len, unsigned int key) +{ + unsigned char bytes[4]; + int i = 0, j = 0; + // ȡÿֽ + for (i = 0; i < 4; i++) + { + bytes[i] = (key >> (i * 8)) & 0xFF; + } + + // еÿֽ + for (i = 0; i < len; i++) + { + // жλǷ + int order = (i / 2) == 0 ? 1 : -1; + + // ѡ + for (j = 0; j < 4; j++) + { + data[i] ^= bytes[(order == 1) ? j : (3 - j)]; + } + } +} + +// ܺ +void Bluesky_Decrypt(unsigned char *data, unsigned int len, unsigned int key) +{ + // ܹܹͬ + Bluesky_Encrypt(data, len, key); +} +void MD_Connect_Init(void) +{ + u8 i = 0, j = 0, Port = 0; + MD_Connect_IO_Configuration(); + TXHData.MD_Port_Num_Top = 4; + for (Port = 0; Port < TXHData.MD_Port_Num_Top; Port++) + { + MD_Connect_DMA_Configuration(Port, 8); + MD_Port_Init(Port); + } + MD_Connect_NVIC_Configuration(); + TXHData.MD_LORA_SlaveTimer.Init = 0; // ʼ־ + TXHData.MD_LORA_SlaveTimer.Flag = 0; // ʱ־ + TXHData.MD_LORA_SlaveTimer.ON_OFF = 0; // + TXHData.MD_LORA_SlaveTimer.Cycle = 1; // Ϊѭģʽʱ + TXHData.MD_LORA_SlaveTimer.TimerCountMax = 1000; // 10001s +} +void MD_Port_LORASet(u8 Port, u8 Mode) +{ + u32 MCU_ID = *(u32 *)(0x1fff7a18); + + if (Mode == LORA_Master) + { + switch (Port) + { + case 0: + MD_Connect_LORA_SetMode1; + break; + case 1: + MD_Connect_LORA_SetMode2; + break; + case 2: + MD_Connect_LORA_SetMode3; + break; + case 3: + MD_Connect_LORA_SetMode4; + break; + } + } + else + { + switch (Port) + { + case 0: + MD_Connect_LORA_IdleMode1; + break; + case 1: + MD_Connect_LORA_IdleMode2; + break; + case 2: + MD_Connect_LORA_IdleMode3; + break; + case 3: + MD_Connect_LORA_IdleMode4; + break; + } + } + delay_ms(100); + // óLORAò + MD_Connect_USART_Configuration(Port, 9600, USART_WordLength_8b, Check_NONE); + // ͣͻͨѶ + TXHData.MBCountTimer[Port].Flag = 0; + TXHData.MBCountTimer[Port].TimerCount = 0; + // 㳬ʱ + TXHData.MD_LORA_SlaveTimer.TimerCountMax = TXHData.MD_Port_Data[Port].PortData.MBCountTime; + TXHData.MD_LORA_SlaveTimer.ON_OFF = 1; + LORA_Set[Port].Communication = 0x77; + switch (TXHData.MD_Port_Data[Port].PortData.POSType) + { + case PosBlueSky: + LORA_Set[Port].Communication = 0x77; + break; + case PosLY: + LORA_Set[Port].Communication = 0x97; + break; + case PosJP: + LORA_Set[Port].Communication = 0x97; + break; + case PosDart: + LORA_Set[Port].Communication = 0x6F; + break; + case PosYWY: + LORA_Set[Port].Communication = 0x67; + break; + case PosYGao: + LORA_Set[Port].Communication = 0x77; + break; + case PosSSLan: + LORA_Set[Port].Communication = 0x97; + break; + case PosBlueSkyPlus: + LORA_Set[Port].Communication = 0xD7; + break; + } + MD_Connect_TX_Buff[Port][0] = 0xC0; + MD_Connect_TX_Buff[Port][1] = 0x00; + MD_Connect_TX_Buff[Port][2] = 0x08; + MD_Connect_TX_Buff[Port][3] = (MCU_ID >> 24) & 0xFF; + MD_Connect_TX_Buff[Port][4] = (MCU_ID & 0xF0) + Port * 3; + MD_Connect_TX_Buff[Port][5] = LORA_Set[Port].Communication; + MD_Connect_TX_Buff[Port][6] = 0x20; + MD_Connect_TX_Buff[Port][7] = (MCU_ID & 0x0f) + Port * 7; + MD_Connect_TX_Buff[Port][8] = 0x80; + MD_Connect_TX_Buff[Port][9] = 'L'; + MD_Connect_TX_Buff[Port][10] = 'T'; + switch (Port) + { + case 0: + { + MD_Connect_RS485_Tx1EN; + MD_Connect_TX1_DMALenSet(11); + MD_Connect_TX1_DMAStart(); + } + break; + case 1: + { + MD_Connect_RS485_Tx2EN; + MD_Connect_TX2_DMALenSet(11); + MD_Connect_TX2_DMAStart(); + } + break; + case 2: + { + MD_Connect_RS485_Tx3EN; + MD_Connect_TX3_DMALenSet(11); + MD_Connect_TX3_DMAStart(); + } + break; + case 3: + { + MD_Connect_RS485_Tx4EN; + MD_Connect_TX4_DMALenSet(11); + MD_Connect_TX4_DMAStart(); + } + break; + } + if (TXHData.UDisk_Flag) + Log_Task(&MD_Connect_TX_Buff[Port][0], 11, Port, Info_Issue); + delay_ms(500); + TXHData.MD_LORA_Slave_Flag = 1; + switch (Port) + { + case 0: + MD_Connect_LORA_IdleMode1; + break; + case 1: + MD_Connect_LORA_IdleMode2; + break; + case 2: + MD_Connect_LORA_IdleMode3; + break; + case 3: + MD_Connect_LORA_IdleMode4; + break; + } + BEEP_OFF; +} + +void MD_Port_Init(u8 Port) +{ + u8 i = 0, j = 0, DeviceNum = 0; + u8 block_count = 0, start = 0, length = 1; + + // TXHData.MD_Port_Data[0].PortData.POSType = PosSSLan; + + if (TXHData.MD_Port_Data[Port].PortData.MDConnectType == MD_LORA) + { + MD_Port_LORASet(Port, LORA_Master); + } + + TXHData.MDConnectState[Port].Flag.WorkMode = 1; + TXHData.MBCountRXIDLETimer[Port].Init = 0; // ʼ־ + TXHData.MBCountRXIDLETimer[Port].Flag = 0; // ʱ־ + TXHData.MBCountRXIDLETimer[Port].ON_OFF = 0; // + TXHData.MBCountRXIDLETimer[Port].Cycle = 0; // Ϊѭģʽʱ + TXHData.MBCountRXIDLETimer[Port].TimerCountMax = 5; // 50.005 + + TXHData.MBCountTimer[Port].Init = 0; // ʼ־ + TXHData.MBCountTimer[Port].Flag = 0; // ʱ־ + TXHData.MBCountTimer[Port].ON_OFF = 1; // + TXHData.MBCountTimer[Port].Cycle = 1; // Ϊѭģʽʱ + TXHData.MBCountTimer[Port].TimerCountMax = TXHData.MD_Port_Data[Port].PortData.MBCountTime * 10; // + MD_Connect_DMA_Configuration(Port, 8); + MD_Connect_USART_Configuration(Port, TXHData.MD_Port_Data[Port].PortData.BaudRate, USART_WordLength_8b, TXHData.MD_Port_Data[Port].PortData.Parity_Even); + switch (TXHData.MD_Port_Data[Port].PortData.POSType) + { + case PosBlueSky: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x05; + break; + case PosLY: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x11; + break; + case PosJP: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x07; + break; + case PosDart: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x04; + break; + case PosYWY: + TXHData.MBCountTimer[Port].TimerCountMax = TXHData.MD_Port_Data[Port].PortData.MBCountTime * 100; + TXHData.MBCountRXIDLETimer[Port].TimerCountMax = 50; // 50.005 + break; + case PosRFID: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x03; + break; + case PosYGao: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x04; + break; + case PosHongYang: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x06; + MD_Connect_DMA_Configuration(Port, 16); + MD_Connect_USART_Configuration(Port, TXHData.MD_Port_Data[Port].PortData.BaudRate, USART_WordLength_9b, 0); + break; + case PosLanFeng: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x03; + break; + case PosSSLan: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x011; + break; + case PosBlueSkyPlus: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x03; + break; + case PosPLC: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x00; + MD_Connect_USART_Configuration(Port, 9600, USART_WordLength_8b, TXHData.MD_Port_Data[Port].PortData.Parity_Even); + break; + case PosPrice1_4: + TXHData.MD_Port_Info[Port].Handshake_Top = 0x02; + TXHData.MBCountTimer[Port].TimerCountMax = TXHData.MD_Port_Data[Port].PortData.MBCountTime * 100; + break; + } + if (TXHData.POS_MonitorModel == 1) // ģʽ + { + TXHData.MD_Port_Info[Port].Handshake_Top = 0; + TXHData.MBCountRXIDLETimer[Port].TimerCountMax = 1; // 50.005 + MD_Connect_RS485_Rx1EN; + MD_Connect_RS485_Rx2EN; + MD_Connect_RS485_Rx3EN; + MD_Connect_RS485_Rx4EN; + } + /*****************************************ǹ豸***************************************************/ + TXHData.MD_Port_Info[Port].GunInfo[0].FatherNum = 0; // ¼ÿ豸ĸ豸 + TXHData.MD_Port_Info[Port].GunInfo[0].SonNum = 0; // ¼ÿ豸ڸ豸еλ + for (DeviceNum = 1; DeviceNum < TXHData.MD_Port_Data[Port].PortData.DeviceNumber; DeviceNum++) + { + if (TXHData.MD_Port_Data[Port].GunData[DeviceNum].GunAddr == TXHData.MD_Port_Data[Port].GunData[DeviceNum - 1].GunAddr) // һǹַͬͬһ + { + length++; // 豸 + } + else + { + TXHData.MD_Port_Info[Port].FatherDevice[block_count].SonStart = start; + TXHData.MD_Port_Info[Port].FatherDevice[block_count].Address = TXHData.MD_Port_Data[Port].GunData[DeviceNum - 1].GunAddr; + TXHData.MD_Port_Info[Port].FatherDevice[block_count].SonNumber = length; + block_count++; // ú + start = DeviceNum; + length = 1; + } + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].FatherNum = block_count; // ¼ÿ豸ĸ豸 + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].SonNum = length - 1; // ¼ÿ豸ڸ豸еλ + } + TXHData.MD_Port_Info[Port].FatherDeviceTop = block_count + 1; + TXHData.MD_Port_Info[Port].FatherDevice[block_count].SonStart = start; + TXHData.MD_Port_Info[Port].FatherDevice[block_count].Address = TXHData.MD_Port_Data[Port].GunData[DeviceNum - 1].GunAddr; + TXHData.MD_Port_Info[Port].FatherDevice[block_count].SonNumber = length; + TXHData.MD_Port_Info[Port].FatherDevice[block_count].LTDelayTimer.Init = 0; // ʼ־ + TXHData.MD_Port_Info[Port].FatherDevice[block_count].LTDelayTimer.Flag = 0; // ʱ־ + TXHData.MD_Port_Info[Port].FatherDevice[block_count].LTDelayTimer.ON_OFF = 0; // + TXHData.MD_Port_Info[Port].FatherDevice[block_count].LTDelayTimer.Cycle = 0; // Ϊѭģʽʱ + TXHData.MD_Port_Info[Port].FatherDevice[block_count].LTDelayTimer.TimerCountMax = 1000; + + for (DeviceNum = 0; DeviceNum < TXHData.MD_Port_Data[Port].PortData.DeviceNumber; DeviceNum++) + { + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].LTDelayTimer.Init = 0; // ʼ־ + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].LTDelayTimer.Flag = 0; // ʱ־ + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].LTDelayTimer.ON_OFF = 0; // + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].LTDelayTimer.Cycle = 0; // Ϊѭģʽʱ + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].LTDelayTimer.TimerCountMax = TXHData.MD_Port_Data[Port].PortData.MBCountTime * 10 * TXHData.MD_Port_Data[Port].PortData.DeviceNumber * 2; // 10001S + TXHData.MD_Port_Data[Port].GunData[DeviceNum].GunState.Flag.Online = 0; + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].Handshake = 0; + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].GunVersion.VersionFindFlag = 0; + switch (TXHData.MD_Port_Data[Port].PortData.POSType) + { + case PosBlueSky: + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].MB_CMD_Next = C_MDConnectASKControlPower; + break; + case PosLY: + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].MB_CMD_Next = LY_MDConnectCmdPoll; + break; + case PosJP: + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].MB_CMD_Next = LY_MDConnectCmdPoll; + break; + case PosYWY: + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].MB_CMD_Next = YWY_MDConnectCmdReadData; + break; + case PosRFID: + { + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].MB_CMD_Next = RFID_MDConnectCmdReadVersion; + for (i = 0; i < TXHData.MD_Port_Num_Top; i++) + { + for (j = 0; j < TXHData.MD_Port_Data[i].PortData.DeviceNumber; j++) + { + if (TXHData.MD_Port_Data[i].GunData[j].GunNummber == TXHData.MD_Port_Data[Port].GunData[DeviceNum].RFIDBinding) + { + TXHData.MD_Port_Info[i].GunInfo[j].AssociatedDevices.Number = TXHData.MD_Port_Data[Port].GunData[DeviceNum].GunNummber; + TXHData.MD_Port_Info[i].GunInfo[j].AssociatedDevices.Port = Port; + TXHData.MD_Port_Info[i].GunInfo[j].AssociatedDevices.location = DeviceNum; + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].AssociatedDevices.Number = TXHData.MD_Port_Data[i].GunData[j].GunNummber; + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].AssociatedDevices.Port = i; + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].AssociatedDevices.location = j; + } + } + } + } + break; + case PosYGao: + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].MB_CMD_Next = YG_MDConnectControlMode; + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].Price = TXHData.PrintLastRecord[Port * 16 + DeviceNum].Price; + break; + case PosHongYang: + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].MB_CMD_Next = HY_MDConnectASKControlPower; + break; + case PosLanFeng: + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].MB_CMD_Next = LF_MDConnectASKControlPower; + break; + case PosBlueSkyPlus: + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].MB_CMD_Next = LTP_GunCMDReadStateAndData; + break; + case PosPLC: + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].MB_CMD_Next = PLC_MDConnectCmdReadData; + break; + case PosPrice1_4: + TXHData.MD_Port_Info[Port].GunInfo[DeviceNum].MB_CMD_Next = Price_MDConnectCmdReadParameter; + break; + } + } + /***************************************************ǹЭ**************************************************************/ + if (TXHData.MD_Port_Data[Port].PortData.POSType == PosDart || TXHData.MD_Port_Data[Port].PortData.POSType == PosSSLan || TXHData.MD_Port_Data[Port].PortData.POSType == PosBlueSkyPlus) + { + for (DeviceNum = 0; DeviceNum < TXHData.MD_Port_Info[Port].FatherDeviceTop; DeviceNum++) + { + switch (TXHData.MD_Port_Data[Port].PortData.POSType) + { + case PosDart: + TXHData.MD_Port_Info[Port].FatherDevice[DeviceNum].MB_CMD_Next = DART_MDConnectCmdPoll; + break; + case PosSSLan: + TXHData.MD_Port_Info[Port].FatherDevice[DeviceNum].MB_CMD_Next = LY_MDConnectCmdPoll; + break; + case PosBlueSkyPlus: + TXHData.MD_Port_Info[Port].FatherDevice[DeviceNum].MB_CMD_Next = LTP_DriverCMDReadVerAndMac; + break; + } + } + } + TXHData.MD_Gun_Num_Top = 0; +} +// F***************************************************************************** +//* NAME: KeyBoardTask +//* PURMDE: KeyBoardͨѶ +//* PARAMS: +//* return: +//****************************************************************************** +volatile u16 HY_SendBuff[25]; +volatile u8 zhtningzhuangtai = 0; +void MD_ConnectTXTask(u8 Port, u8 GunNum, u8 MD_TX_CMD) +{ + volatile u16 i = 0, j = 0, k = 0, l = 0; + volatile u8 PosTypeTemp = 0, GunAddr = 0, FatherNum = 0; + volatile u64 TempBCD = 0, Tempu64 = 0; + volatile u16 MD_ConnectTX_Len = 0; // + u8 Encrypt_Flag1 = 0; + u8 Encrypt_Flag2 = 0; + volatile u16 MD_Port_Num = 0, DeviceNumber = 0; + u8 MD_ConnectRX_Check = 0; // У + u8 Data_201[7] = "i20100"; + u8 Data_20E[7] = "i20E00"; + + u16 CRCTemp = 0; + MD_Connect_TX_Flag = 0; + { + PosTypeTemp = TXHData.MD_Port_Data[Port].PortData.POSType; + if (TXHData.MBCountCutNum[Port][GunNum] > 5) + { + TXHData.MBCountCutNum[Port][GunNum] = 6; + if (TXHData.MD_Port_Data[Port].PortData.POSType == PosDart || TXHData.MD_Port_Data[Port].PortData.POSType == PosSSLan || TXHData.MD_Port_Data[Port].PortData.POSType == PosBlueSkyPlus) // ǹ + { + TXHData.MD_Port_Info[Port].FatherDevice[GunNum].Handshake = 0; + for (i = 0; i < TXHData.MD_Port_Info[Port].FatherDevice[GunNum].SonNumber; i++) + { + TXHData.MD_Port_Data[Port].GunData[TXHData.MD_Port_Info[Port].FatherDevice[GunNum].SonStart + i].GunState.Flag.Online = 0; + TXHData.MD_Port_Info[Port].GunInfo[TXHData.MD_Port_Info[Port].FatherDevice[GunNum].SonStart + i].ROM_UpData_State.Flag.BaudRateSync_Flag = 0; + TXHData.MD_Port_Info[Port].GunInfo[TXHData.MD_Port_Info[Port].FatherDevice[GunNum].SonStart + i].ROM_UpData_State.Flag.Update_Flag = 0; + TXHData.MD_Port_Info[Port].GunInfo[TXHData.MD_Port_Info[Port].FatherDevice[GunNum].SonStart + i].Handshake = 0; + TXHData.MD_Port_Info[Port].GunInfo[TXHData.MD_Port_Info[Port].FatherDevice[GunNum].SonStart + i].MB_CMD_Next = LTP_GunCMDReadStateAndData; + } + switch (TXHData.MD_Port_Data[Port].PortData.POSType) + { + case PosDart: + TXHData.MD_Port_Info[Port].FatherDevice[GunNum].MB_CMD_Next = DART_MDConnectCmdPoll; + break; + case PosSSLan: + TXHData.MD_Port_Info[Port].FatherDevice[GunNum].MB_CMD_Next = LY_MDConnectCmdPoll; + break; + case PosBlueSkyPlus: + TXHData.MD_Port_Info[Port].FatherDevice[GunNum].MB_CMD_Next = LTP_DriverCMDReadVerAndMac; + break; + } + } + else // ǹ + { + TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake = 0; + TXHData.MD_Port_Data[Port].GunData[GunNum].GunState.Flag.Online = 0; + // MD_Connect_USART_Configuration(Port,TXHData.MD_Port_Data[Port].PortData.BaudRate,TXHData.MD_Port_Data[Port].PortData.Parity_Even); + TXHData.MD_Port_Info[Port].GunInfo[GunNum].ROM_UpData_State.Flag.BaudRateSync_Flag = 0; + TXHData.MD_Port_Info[Port].GunInfo[GunNum].ROM_UpData_State.Flag.Update_Flag = 0; + switch (TXHData.MD_Port_Data[Port].PortData.POSType) + { + case PosBlueSky: + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = C_MDConnectASKControlPower; + break; + case PosLY: + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = LY_MDConnectCmdPoll; + break; + case PosJP: + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = LY_MDConnectCmdPoll; + break; + case PosYWY: + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = YWY_MDConnectCmdReadData; + break; + case PosRFID: + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = RFID_MDConnectCmdReadVersion; + break; + case PosYGao: + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = YG_MDConnectControlMode; + break; + case PosHongYang: + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = HY_MDConnectASKControlPower; + break; + case PosLanFeng: + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = LF_MDConnectASKControlPower; + break; + case PosPLC: + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = PLC_MDConnectCmdReadData; + TXHData.CNGPLCState.Flag.Online = 0; + break; + case PosPrice1_4: + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = Price_MDConnectCmdReadParameter; + TXHData.MD_Port_Info[Port].PriceTagData.State.State = 0; + break; + } + } + } + } + if (TXHData.MDConnectState[Port].Flag.WorkMode == 1) // ģʽ + { + if (TXHData.POS_MonitorModel != 1 && PosTypeTemp) // Ǽģʽģʽ + { + switch (PosTypeTemp) + { + case PosBlueSky: + { + GunAddr = MD_Connect_u64ToBCD(TXHData.MD_Port_Data[Port].GunData[GunNum].GunAddr); + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake == TXHData.MD_Port_Info[Port].Handshake_Top) + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][GunNum]++; + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].ROM_UpData_State.Flag.BaudRateSync_Flag == 1) + { + MD_Connect_USART_Configuration(Port, BaudRateSync, USART_WordLength_9b, TXHData.MD_Port_Data[Port].PortData.Parity_Even); + } + else + { + MD_Connect_USART_Configuration(Port, TXHData.MD_Port_Data[Port].PortData.BaudRate, USART_WordLength_9b, TXHData.MD_Port_Data[Port].PortData.Parity_Even); + } + switch (MD_TX_CMD) + { + case C_MDConnectCmdReadState: // ״̬ + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = C_MDConnectCmdReadState; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case C_MDConnectCmdReadFuelState: // + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = C_MDConnectCmdReadFuelState; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case C_MDConnectCmdWritePrsetSale: // Ԥý + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + if (TXHData.MD_Port_Data[Port].PortData.Device_Type == Display_664) + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >= 0x900000) + Tempu64 = 0x900000; + else + Tempu64 = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue; + MD_Connect_TX_Buff[Port][2] = 0xA5; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][6] = C_MDConnectCmdWritePrsetSale; + MD_Connect_TX_Buff[Port][7] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 6); // У + MD_ConnectTX_Len = 8; + } + else + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >= 0x90000000) + Tempu64 = 0x90000000; + else + Tempu64 = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue; + MD_Connect_TX_Buff[Port][2] = 0xA6; + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = (Tempu64 >> ((3 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][7] = C_MDConnectCmdWritePrsetSale; + MD_Connect_TX_Buff[Port][8] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 7); // У + MD_ConnectTX_Len = 9; + } + } + break; + case C_MDConnectCmdWritePrsetVolume: // Ԥ + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + if (TXHData.MD_Port_Data[Port].PortData.Device_Type == Display_664) + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue == 0x900000) + Tempu64 = 0x900000; + else + Tempu64 = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue; + MD_Connect_TX_Buff[Port][2] = 0xA5; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][6] = C_MDConnectCmdWritePrsetVolume; + MD_Connect_TX_Buff[Port][7] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 6); // У + MD_ConnectTX_Len = 8; + } + else + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue == 0x90000000) + Tempu64 = 0x90000000; + else + Tempu64 = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue; + MD_Connect_TX_Buff[Port][2] = 0xA6; + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = (Tempu64 >> ((3 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][7] = C_MDConnectCmdWritePrsetVolume; + MD_Connect_TX_Buff[Port][8] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 7); // У + MD_ConnectTX_Len = 9; + } + } + break; + case C_MDConnectCmdStart: // + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = C_MDConnectCmdStart; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case C_MDConnectCmdStop: // ͣ + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = C_MDConnectCmdStop; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case C_MDConnectPauseFueling: // ͣ + { + zhtningzhuangtai = 1; + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = C_MDConnectPauseFueling; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case C_MDConnectResumeFueling: // + { + zhtningzhuangtai = 2; + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = C_MDConnectResumeFueling; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case C_MDConnectCmdReadPrice: // + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = C_MDConnectCmdReadPrice; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case C_MDConnectCmdWritePrice: // xie + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + if (TXHData.MD_Port_Data[Port].PortData.Device_Type == Display_664) + { + MD_Connect_TX_Buff[Port][2] = 0xA4; + for (i = 0; i < 2; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price) >> ((1 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][5] = C_MDConnectCmdWritePrice; + MD_Connect_TX_Buff[Port][6] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 5); // У + MD_ConnectTX_Len = 7; + } + else + { + MD_Connect_TX_Buff[Port][2] = 0xA5; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price) >> ((2 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][6] = C_MDConnectCmdWritePrice; + MD_Connect_TX_Buff[Port][7] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 6); // У + MD_ConnectTX_Len = 8; + } + } + break; + case C_MDConnectCmdWritePulseCoefficient: // xie + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷMD_Connect_u64ToBCD(TXHData.PulseCoefficient[GunNum - 1] + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA6; + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].PulseCoefficient) >> ((3 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][7] = C_MDConnectCmdWritePulseCoefficient; + MD_Connect_TX_Buff[Port][8] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 7); // У + MD_ConnectTX_Len = 9; + } + break; + case C_MDConnectCmdReadTotal: // + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = C_MDConnectCmdReadTotal; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case C_MDConnectCmdWriteTotal: // xie + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + if (TXHData.MD_Port_Data[Port].PortData.Device_Type == Display_664) + { + MD_Connect_TX_Buff[Port][2] = 0xAc; + for (i = 0; i < 5; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].CTOTAL.TotalLit) >> ((4 - i) * 8)) & 0xff; + } + for (i = 0; i < 5; i++) + { + MD_Connect_TX_Buff[Port][8 + i] = ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].CTOTAL.TotalMoney) >> ((4 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][13] = C_MDConnectCmdWriteTotal; + MD_Connect_TX_Buff[Port][14] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 13); // У + MD_ConnectTX_Len = 15; + } + else + { + MD_Connect_TX_Buff[Port][2] = 0xAe; + for (i = 0; i < 6; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].CTOTAL.TotalLit) >> ((5 - i) * 8)) & 0xff; + } + for (i = 0; i < 6; i++) + { + MD_Connect_TX_Buff[Port][9 + i] = ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].CTOTAL.TotalMoney) >> ((5 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][15] = C_MDConnectCmdWriteTotal; + MD_Connect_TX_Buff[Port][16] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 15); // У + MD_ConnectTX_Len = 17; + } + } + break; + case C_MDConnectASKControlPower: // ҪȨ + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = C_MDConnectASKControlPower; + // MD_Connect_TX_Buff[Port][3] = C_MDConnectReturnControlPower; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case C_MDConnectReturnControlPower: // Ȩ + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = C_MDConnectReturnControlPower; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case C_MDConnectCmdReadVersion: // 汾 + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = C_MDConnectCmdReadVersion; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake = 0x01; + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = C_MDConnectCmdReadState; + } + break; + case C_MDConnectCmdSetBaudRate: // ͬ + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA5; + MD_Connect_TX_Buff[Port][3] = (115200 >> 16) & 0xff; + MD_Connect_TX_Buff[Port][4] = (115200 >> 8) & 0xff; + MD_Connect_TX_Buff[Port][5] = 115200 & 0xff; + MD_Connect_TX_Buff[Port][6] = C_MDConnectCmdSetBaudRate; + MD_Connect_TX_Buff[Port][7] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 6); // У + MD_ConnectTX_Len = 8; + } + break; + case C_MDConnectCmdSendFrame: // ֡ + { + MD_Connect_TX_Buff[Port][0] = 0xF5; + MD_Connect_TX_Buff[Port][1] = GunAddr; + MD_Connect_TX_Buff[Port][2] = 0xff; + for (i = 0; i < 10; i++) + MD_Connect_TX_Buff[Port][3 + i] = TXHData.MD_Port_Data[Port].PortData.ROM_UpData_Version[i]; + MD_Connect_TX_Buff[Port][13] = TXHData.MD_Port_Data[Port].PortData.ROM_UpData.FrameTop >> 8; + MD_Connect_TX_Buff[Port][14] = TXHData.MD_Port_Data[Port].PortData.ROM_UpData.FrameTop; + MD_Connect_TX_Buff[Port][15] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].FrameNow >> 8; + MD_Connect_TX_Buff[Port][16] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].FrameNow; + AT45DBItemRead(CA_DeviceFrame, TXHData.MD_Port_Info[Port].GunInfo[GunNum].FrameNow + Port * 1024); + for (i = 0; i < 512; i++) + MD_Connect_TX_Buff[Port][17 + i] = TXHData.Frame[i]; + MD_Connect_TX_Buff[Port][529] = C_MDConnectCmdSendFrame; + MD_Connect_TX_Buff[Port][530] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 529); + MD_ConnectTX_Len = 531; + } + break; + } + } + break; + case PosBlueSkyPlus: + { + FatherNum = GunNum; // GunNumʾú + GunAddr = MD_Connect_u64ToBCD(TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].Address); // õַ + if (TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].Handshake == TXHData.MD_Port_Info[Port].Handshake_Top) + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][FatherNum]++; + // if(TXHData.MD_Port_Info[Port].GunInfo[GunNum].ROM_UpData_State.Flag.BaudRateSync_Flag == 1) + // { + // MD_Connect_USART_Configuration(Port,BaudRateSync,USART_WordLength_9b,TXHData.MD_Port_Data[Port].PortData.Parity_Even); + // } + // else + // { + // MD_Connect_USART_Configuration(Port,TXHData.MD_Port_Data[Port].PortData.BaudRate,USART_WordLength_9b,TXHData.MD_Port_Data[Port].PortData.Parity_Even); + // } + TXHData.RNGData = RNG_GetRandomNumber(); + MD_Connect_TX_Buff[Port][0] = 0xFB; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][4] = TXHData.CTIME.Year; + MD_Connect_TX_Buff[Port][5] = TXHData.CTIME.Month; + MD_Connect_TX_Buff[Port][6] = TXHData.CTIME.Day; + MD_Connect_TX_Buff[Port][7] = TXHData.CTIME.Hour; + MD_Connect_TX_Buff[Port][8] = TXHData.CTIME.Min; + MD_Connect_TX_Buff[Port][9] = TXHData.CTIME.Sec; + for (i = 0; i < 4; i++) + MD_Connect_TX_Buff[Port][10 + i] = TXHData.RNGData >> (8 * (3 - i)); + MD_Connect_TX_Buff[Port][14] = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].SonNumber; + MD_ConnectTX_Len = 15; + switch (MD_TX_CMD) + { + case LTP_DriverCMDReadPassword: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = LTP_DriverCMD; + MD_ConnectTX_Len++; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = MD_TX_CMD; + MD_ConnectTX_Len++; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].Password_Lever; + MD_ConnectTX_Len++; + } + break; + case LTP_DriverCMDWritePassword: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = LTP_DriverCMD; + MD_ConnectTX_Len++; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = MD_TX_CMD; + MD_ConnectTX_Len++; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].Password_Lever; + MD_ConnectTX_Len++; + for (i = 0; i < 4; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].Password >> (8 * (3 - i)); + MD_ConnectTX_Len += 4; + } + break; + case LTP_DriverCMDReadVerAndMac: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = LTP_DriverCMD; + MD_ConnectTX_Len++; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = MD_TX_CMD; + MD_ConnectTX_Len++; + } + break; + case LTP_DriverCMDLock: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = LTP_DriverCMD; + MD_ConnectTX_Len++; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = MD_TX_CMD; + MD_ConnectTX_Len++; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].LockType; + MD_ConnectTX_Len++; + switch (TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].LockType) + { + case 0: + { + } + break; + case 1: + { + for (i = 0; i < 3; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].LockTime[i]; + MD_ConnectTX_Len += 3; + } + break; + case 2: + { + for (i = 0; i < 6; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].LockValue[i]; + MD_ConnectTX_Len += 6; + } + break; + } + } + break; + case LTP_DriverCMDUnlock: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = LTP_DriverCMD; + MD_ConnectTX_Len++; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = MD_TX_CMD; + MD_ConnectTX_Len++; + } + break; + case LTP_DriverCMDSendFrame: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = LTP_DriverCMD; + MD_ConnectTX_Len++; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = MD_TX_CMD; + MD_ConnectTX_Len++; + for (i = 0; i < 10; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.MD_Port_Data[Port].PortData.ROM_UpData_Version[i]; + MD_ConnectTX_Len += 10; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Data[Port].PortData.ROM_UpData.FrameTop >> 8; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Data[Port].PortData.ROM_UpData.FrameTop; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].FrameNow >> 8; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].FrameNow; + AT45DBItemRead(CA_DeviceFrame, TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].FrameNow + Port * 1024); + for (i = 0; i < 512; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.Frame[i]; + MD_ConnectTX_Len += 512; + + TXHData.MBCountTimer[Port].TimerCountMax = 120; // ڵms + } + break; + default: + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = LTP_GunCMD; + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].SonNumber; DeviceNumber++) + { + GunNum = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].SonStart + DeviceNumber; // + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = DeviceNumber + 1; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next; + switch (TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next) + { + case LTP_GunCMDReadState: // + case LTP_GunCMDReadStateAndData: // + case LTP_GunCMDReadTotal: // + case LTP_GunCMDStop: // + case LTP_GunCMDReadEvent: // + case LTP_GunCMDReadError: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = 0; + } + break; + case LTP_GunCMDSuspend: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = 0; + } + break; + case LTP_GunCMDContinue: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = 0; + } + break; + case LTP_GunCMDWritePrset: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = 5; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresteType; + for (i = 0; i < 4; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >> (8 * (3 - i)); + MD_ConnectTX_Len += 4; + } + break; + case LTP_GunCMDAuthorize: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = 9; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresteType; + for (i = 0; i < 4; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >> (8 * (3 - i)); + MD_ConnectTX_Len += 4; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = 0; + for (i = 0; i < 3; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price >> (8 * (2 - i)); + MD_ConnectTX_Len += 3; + } + break; + case LTP_GunCMDReadParameter: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].ParameterNumber; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = 0; + } + break; + case LTP_GunCMDWriteParameter: // + { + switch (TXHData.MD_Port_Info[Port].GunInfo[GunNum].ParameterNumber) + { + case 0x01: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = 4; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].ParameterNumber; + for (i = 0; i < 3; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price >> (8 * (2 - i)); + MD_ConnectTX_Len += 3; + } + break; + case 0x02: // + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = 4; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].ParameterNumber; + for (i = 0; i < 3; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PulseCoefficient >> (8 * (2 - i)); + MD_ConnectTX_Len += 3; + } + break; + case 0x03: // ǰط + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = 3; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].ParameterNumber; + for (i = 0; i < 2; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].ValveValue >> (8 * (1 - i)); + MD_ConnectTX_Len += 2; + } + break; + case 0x04: // Сʾֵ + { + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = 3; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len++] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].ParameterNumber; + for (i = 0; i < 2; i++) + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].MinDisplay >> (8 * (1 - i)); + MD_ConnectTX_Len += 2; + } + break; + } + } + break; + } + } + if (DeviceNumber == 0) + { + if (CoreDebug->DHCSR & 1) + { // check C_DEBUGEN == 1 -> Debugger Connected + __breakpoint(0); // halt program execution here + } + } + } + break; + } + MD_Connect_TX_Buff[Port][2] = (MD_ConnectTX_Len >> 8) & 0xff; + MD_Connect_TX_Buff[Port][3] = MD_ConnectTX_Len & 0xff; + + Bluesky_Encrypt(&MD_Connect_TX_Buff[Port][14], MD_ConnectTX_Len - 14, TXHData.RNGData); + + CRCTemp = CRC_Check(&MD_Connect_TX_Buff[Port][0], MD_ConnectTX_Len); // У + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = (CRCTemp >> 8) & 0xff; + MD_ConnectTX_Len++; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = CRCTemp & 0xff; + MD_ConnectTX_Len++; + } + break; + case PosLY: + { + GunAddr = TXHData.MD_Port_Data[Port].GunData[GunNum].GunAddr; + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake == TXHData.MD_Port_Info[Port].Handshake_Top) + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][GunNum]++; + if (GunAddr > 0) + GunAddr -= 1; + switch (MD_TX_CMD) + { + case LY_MDConnectCmdHandshake: // + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x30; + MD_Connect_TX_Buff[Port][4] = 0x30; + MD_Connect_TX_Buff[Port][5] = (TXHData.MD_Port_Info[Port].GunInfo[GunNum].LYHandshakeCRC >> 4) & 0x0f; + if (MD_Connect_TX_Buff[Port][5] < 0x0A) + MD_Connect_TX_Buff[Port][5] += 0x30; + else + MD_Connect_TX_Buff[Port][5] = MD_Connect_TX_Buff[Port][5] - 0x0A + 0x41; + MD_Connect_TX_Buff[Port][6] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].LYHandshakeCRC & 0x0f; + if (MD_Connect_TX_Buff[Port][6] < 0x0A) + MD_Connect_TX_Buff[Port][6] += 0x30; + else + MD_Connect_TX_Buff[Port][6] = MD_Connect_TX_Buff[Port][6] - 0x0A + 0x41; + MD_Connect_TX_Buff[Port][7] = 0x03; + MD_Connect_TX_Buff[Port][8] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 7); // У + MD_ConnectTX_Len = 9; + // if(TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake == 0x06) + // { + // TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake = 0x07; + // } + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake = 0x08; + } + break; + case LY_MDConnectCmdPoll: // ѯ + { + MD_Connect_TX_Buff[Port][0] = 0x04; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x51; + MD_Connect_TX_Buff[Port][3] = 0x05; + MD_ConnectTX_Len = 4; + } + break; + case LY_MDConnectCmdReadState: // ״̬ + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x31; + MD_Connect_TX_Buff[Port][4] = 0x35; + MD_Connect_TX_Buff[Port][5] = 0x03; + MD_Connect_TX_Buff[Port][6] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 5); // У + MD_ConnectTX_Len = 7; + } + break; + case LY_MDConnectCmdReadTotal: // ״̬ + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x32; + MD_Connect_TX_Buff[Port][4] = 0x30; + MD_Connect_TX_Buff[Port][5] = 0x03; + MD_Connect_TX_Buff[Port][6] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 5); // У + MD_ConnectTX_Len = 7; + } + break; + case LY_MDConnectCmdChoiceGun: // ѡǹ + { + MD_Connect_TX_Buff[Port][0] = 0x04; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x05; + MD_ConnectTX_Len = 4; + // if(TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake == 0x02) + // { + // TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake = 0x03; + // } + } + break; + case LY_MDConnectCmdDisauthorize: // ȡȨ + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x31; + MD_Connect_TX_Buff[Port][4] = 0x32; + MD_Connect_TX_Buff[Port][5] = 0x03; + MD_Connect_TX_Buff[Port][6] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 5); // У + MD_ConnectTX_Len = 7; + TXHData.MD_Port_Data[Port].GunData[GunNum].GunState.Flag.AuthorizeState = 0; + } + break; + case LY_MDConnectCmdAuthorize: // Ȩ + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x31; + MD_Connect_TX_Buff[Port][4] = 0x30; + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >= 0x900000) + MD_Connect_TX_Buff[Port][5] = 0x30; + else + { + MD_Connect_TX_Buff[Port][5] = 0x32; + } + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresteType == Preset_Volume) + MD_Connect_TX_Buff[Port][6] = 0x31; + else if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresteType == Preset_Sale) + MD_Connect_TX_Buff[Port][6] = 0x32; + for (i = 0; i < 6; i++) + MD_Connect_TX_Buff[Port][7 + i] = 0x30 + ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >> (5 - i) * 4) & 0x0f); + MD_Connect_TX_Buff[Port][13] = 0x32; + for (i = 0; i < 4; i++) + MD_Connect_TX_Buff[Port][14 + i] = 0x30 + ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price >> (3 - i) * 4) & 0x0f); + MD_Connect_TX_Buff[Port][18] = 0x03; + MD_Connect_TX_Buff[Port][19] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 18); // У + MD_ConnectTX_Len = 20; + } + break; + case LY_MDConnectCmdWritePrice: // д + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x32; + MD_Connect_TX_Buff[Port][4] = 0x31; + MD_Connect_TX_Buff[Port][5] = 0x32; + + MD_Connect_TX_Buff[Port][6] = 0x32; + for (i = 0; i < 4; i++) + MD_Connect_TX_Buff[Port][7 + i] = 0x30 + ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price >> (3 - i) * 4) & 0x0f); + for (i = 0; i < 25; i++) + MD_Connect_TX_Buff[Port][11 + i] = 0x30; + MD_Connect_TX_Buff[Port][36] = 0x03; + MD_Connect_TX_Buff[Port][37] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 36); // У + MD_ConnectTX_Len = 38; + } + break; + case LY_MDConnectCmdACK0: // 1030 + { + MD_Connect_TX_Buff[Port][0] = 0x10; + MD_Connect_TX_Buff[Port][1] = 0x30; + MD_ConnectTX_Len = 2; + } + break; + case LY_MDConnectCmdACK1: // 1031 + { + MD_Connect_TX_Buff[Port][0] = 0x10; + MD_Connect_TX_Buff[Port][1] = 0x31; + MD_ConnectTX_Len = 2; + } + break; + } + } + break; + case PosJP: + { + GunAddr = TXHData.MD_Port_Data[Port].GunData[GunNum].GunAddr; + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake == TXHData.MD_Port_Info[Port].Handshake_Top) + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][GunNum]++; + if (GunAddr > 0) + GunAddr -= 1; + switch (MD_TX_CMD) + { + case LY_MDConnectCmdPoll: // ѯ + { + MD_Connect_TX_Buff[Port][0] = 0x04; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x51; + MD_Connect_TX_Buff[Port][3] = 0x05; + MD_ConnectTX_Len = 4; + } + break; + case LY_MDConnectCmdReadState: // ״̬ + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x31; + MD_Connect_TX_Buff[Port][4] = 0x35; + MD_Connect_TX_Buff[Port][5] = 0x03; + MD_Connect_TX_Buff[Port][6] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 5); // У + MD_ConnectTX_Len = 7; + } + break; + case LY_MDConnectCmdReadTotal: // + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x32; + MD_Connect_TX_Buff[Port][4] = 0x30; + MD_Connect_TX_Buff[Port][5] = 0x03; + MD_Connect_TX_Buff[Port][6] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 5); // У + MD_ConnectTX_Len = 7; + } + break; + case LY_MDConnectCmdChoiceGun: // ѡǹ + { + MD_Connect_TX_Buff[Port][0] = 0x04; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x05; + MD_ConnectTX_Len = 4; + } + break; + case LY_MDConnectCmdDisauthorize: // ȡȨ + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x31; + MD_Connect_TX_Buff[Port][4] = 0x32; + MD_Connect_TX_Buff[Port][5] = 0x03; + MD_Connect_TX_Buff[Port][6] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 5); // У + TXHData.MD_Port_Data[Port].GunData[GunNum].GunState.Flag.AuthorizeState = 0; + MD_ConnectTX_Len = 7; + } + break; + case LY_MDConnectCmdAuthorize: // Ȩ + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x31; + MD_Connect_TX_Buff[Port][4] = 0x41; + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue == 0x90000000) + MD_Connect_TX_Buff[Port][5] = 0x30; + else + { + MD_Connect_TX_Buff[Port][5] = 0x32; + } + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresteType == Preset_Volume) + MD_Connect_TX_Buff[Port][6] = 0x31; + else if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresteType == Preset_Sale) + MD_Connect_TX_Buff[Port][6] = 0x32; + for (i = 0; i < 8; i++) + MD_Connect_TX_Buff[Port][7 + i] = 0x30 + ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >> (7 - i) * 4) & 0x0f); + + MD_Connect_TX_Buff[Port][15] = 0x32; + for (i = 0; i < 6; i++) + MD_Connect_TX_Buff[Port][16 + i] = 0x30 + ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price >> (5 - i) * 4) & 0x0f); + MD_Connect_TX_Buff[Port][22] = 0x30; + for (i = 0; i < 6; i++) + MD_Connect_TX_Buff[Port][23 + i] = 0x30; + MD_Connect_TX_Buff[Port][29] = 0x30; + for (i = 0; i < 6; i++) + MD_Connect_TX_Buff[Port][30 + i] = 0x30; + MD_Connect_TX_Buff[Port][36] = 0x30; + for (i = 0; i < 6; i++) + MD_Connect_TX_Buff[Port][37 + i] = 0x30; + MD_Connect_TX_Buff[Port][43] = 0x30; + for (i = 0; i < 6; i++) + MD_Connect_TX_Buff[Port][44 + i] = 0x30; + MD_Connect_TX_Buff[Port][50] = 0x30; + for (i = 0; i < 6; i++) + MD_Connect_TX_Buff[Port][51 + i] = 0x30; + + MD_Connect_TX_Buff[Port][57] = 0x03; + MD_Connect_TX_Buff[Port][58] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 57); // У + MD_ConnectTX_Len = 59; + } + break; + case LY_MDConnectCmdWritePrice: // д + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x32; + MD_Connect_TX_Buff[Port][4] = 0x31; + MD_Connect_TX_Buff[Port][5] = 0x33; + + MD_Connect_TX_Buff[Port][6] = 0x32; + for (i = 0; i < 6; i++) + MD_Connect_TX_Buff[Port][7 + i] = 0x30 + ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price >> (5 - i) * 4) & 0x0f); + for (i = 0; i < 25; i++) + MD_Connect_TX_Buff[Port][13 + i] = 0x30; + MD_Connect_TX_Buff[Port][38] = 0x03; + MD_Connect_TX_Buff[Port][39] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 38); // У + MD_ConnectTX_Len = 40; + } + break; + case LY_MDConnectCmdACK0: // 1030 + { + MD_Connect_TX_Buff[Port][0] = 0x10; + MD_Connect_TX_Buff[Port][1] = 0x30; + MD_ConnectTX_Len = 2; + } + break; + case LY_MDConnectCmdACK1: // 1031 + { + MD_Connect_TX_Buff[Port][0] = 0x10; + MD_Connect_TX_Buff[Port][1] = 0x31; + MD_ConnectTX_Len = 2; + } + break; + } + } + break; + case PosDart: + { + GunAddr = TXHData.MD_Port_Data[Port].GunData[GunNum].GunAddr; + if (TXHData.MD_Port_Info[Port].GunInfo[i].Handshake == TXHData.MD_Port_Info[Port].Handshake_Top) + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][GunNum]++; + for (i = 0; i < TXHData.MD_Port_Data[Port].PortData.DeviceNumber; i++) + if (GunAddr == TXHData.MD_Port_Data[Port].GunData[i].GunAddr) + break; + // SunNum = GunNum - TXHData.MD_Port_Data[Port].GunData[i].GunNummber + 1;//ȷͬһַĵڼǹ + + if (GunAddr > 0) + GunAddr -= 1; + + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].DartSeq < 0x0f) // кԶ + TXHData.MD_Port_Info[Port].GunInfo[GunNum].DartSeq++; + else + TXHData.MD_Port_Info[Port].GunInfo[GunNum].DartSeq = 0; + switch (MD_TX_CMD) + { + case DART_MDConnectCmdPoll: // ѯ + { + MD_Connect_TX_Buff[Port][0] = GunAddr + 0x50; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0x20; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xFA; + MD_ConnectTX_Len = 3; + } + break; + case DART_MDConnectCmdReadState: // ״̬ + { + MD_Connect_TX_Buff[Port][0] = GunAddr + 0x50; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0x30 | TXHData.MD_Port_Info[Port].GunInfo[GunNum].DartSeq; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x01; + MD_Connect_TX_Buff[Port][3] = 0x01; + MD_Connect_TX_Buff[Port][4] = 0x00; + Tempu64 = DartCRC16(&MD_Connect_TX_Buff[Port][0], 5); + MD_Connect_TX_Buff[Port][5] = Tempu64 & 0xff; + MD_Connect_TX_Buff[Port][6] = (Tempu64 >> 8) & 0xff; + MD_Connect_TX_Buff[Port][7] = 0x03; + MD_Connect_TX_Buff[Port][8] = 0xFA; // У + MD_ConnectTX_Len = 9; + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = DART_MDConnectCmdPoll; + } + break; + case DART_MDConnectCmdReadVTotal: // 50 33 65 01 14 DE C8 03 FA + { + MD_Connect_TX_Buff[Port][0] = GunAddr + 0x50; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0x30 | TXHData.MD_Port_Info[Port].GunInfo[GunNum].DartSeq; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x65; + MD_Connect_TX_Buff[Port][3] = 0x01; + MD_Connect_TX_Buff[Port][4] = 0x00; + Tempu64 = DartCRC16(&MD_Connect_TX_Buff[Port][0], 5); + MD_Connect_TX_Buff[Port][5] = Tempu64 & 0xff; + MD_Connect_TX_Buff[Port][6] = (Tempu64 >> 8) & 0xff; + MD_Connect_TX_Buff[Port][7] = 0x03; + MD_Connect_TX_Buff[Port][8] = 0xFA; // У + MD_ConnectTX_Len = 9; + } + break; + case DART_MDConnectCmdReadPTotal: // + { + MD_Connect_TX_Buff[Port][0] = GunAddr + 0x50; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0x30 | TXHData.MD_Port_Info[Port].GunInfo[GunNum].DartSeq; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x65; + MD_Connect_TX_Buff[Port][3] = 0x01; + MD_Connect_TX_Buff[Port][4] = 0x10; + Tempu64 = DartCRC16(&MD_Connect_TX_Buff[Port][0], 5); + MD_Connect_TX_Buff[Port][5] = Tempu64 & 0xff; + MD_Connect_TX_Buff[Port][6] = (Tempu64 >> 8) & 0xff; + MD_Connect_TX_Buff[Port][7] = 0x03; + MD_Connect_TX_Buff[Port][8] = 0xFA; // У + MD_ConnectTX_Len = 9; + } + break; + case DART_MDConnectCmdReStart: // 50 3F 01 01 05 03 04 00 09 00 01 48 A3 03 FA + { + MD_Connect_TX_Buff[Port][0] = GunAddr + 0x50; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0x30 | TXHData.MD_Port_Info[Port].GunInfo[GunNum].DartSeq; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x01; + MD_Connect_TX_Buff[Port][3] = 0x01; + MD_Connect_TX_Buff[Port][4] = 0x05; + Tempu64 = DartCRC16(&MD_Connect_TX_Buff[Port][0], 5); + MD_Connect_TX_Buff[Port][5] = Tempu64 & 0xff; + MD_Connect_TX_Buff[Port][6] = (Tempu64 >> 8) & 0xff; + MD_Connect_TX_Buff[Port][7] = 0x03; + MD_Connect_TX_Buff[Port][8] = 0xFA; // У + MD_ConnectTX_Len = 9; + } + break; + case DART_MDConnectCmdACK: // 1030 + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].LYGunNeedCMD != DART_MDConnectCmdPoll) + { + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = TXHData.MD_Port_Info[Port].GunInfo[GunNum].LYGunNeedCMD; + TXHData.MD_Port_Info[Port].GunInfo[GunNum].LYGunNeedCMD = DART_MDConnectCmdPoll; + } + MD_Connect_TX_Buff[Port][0] = GunAddr + 0x50; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xC0 | TXHData.MD_Port_Info[Port].GunInfo[GunNum].DartSeq; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xFA; + MD_ConnectTX_Len = 3; + } + break; + } + } + break; + case PosYWY: + { + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][GunNum]++; + switch (TXHData.MD_Port_Data[Port].PortData.Device_Type) + { + case YWY_Bluesky: + { + switch (MD_TX_CMD) + { + case YWY_MDConnectCmdReadData: // + { + for (i = 0; i < 7; i++) + MD_Connect_TX_Buff[Port][i] = Data_201[i]; + MD_ConnectTX_Len = 7; + } + break; + case YWY_MDConnectCmdWriteApacity: // عݱ + { + for (i = 0; i < 7; i++) + MD_Connect_TX_Buff[Port][i] = Data_20E[i]; + MD_ConnectTX_Len = 7; + } + break; + } + } + break; + case YWY_Probe_KY: + { + GunAddr = GunNum + 1; + // TXHData.MBCountCutNum[Port][i] ++; + MD_Connect_TX_Buff[Port][0] = GunAddr; + MD_Connect_TX_Buff[Port][1] = 0x03; + MD_Connect_TX_Buff[Port][2] = 0x00; + MD_Connect_TX_Buff[Port][3] = 0x02; + MD_Connect_TX_Buff[Port][4] = 0x00; + MD_Connect_TX_Buff[Port][5] = 0x09; + Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0], 6); + MD_Connect_TX_Buff[Port][7] = Tempu64 >> 8; + MD_Connect_TX_Buff[Port][6] = Tempu64; + MD_ConnectTX_Len = 8; + } + break; + case YWY_Pressure: + { + GunAddr = GunNum + 1; + // TXHData.MBCountCutNum[0][i] ++; + MD_Connect_TX_Buff[Port][0] = GunAddr; + MD_Connect_TX_Buff[Port][1] = 0x03; + MD_Connect_TX_Buff[Port][2] = 0x00; + MD_Connect_TX_Buff[Port][3] = 0x00; + MD_Connect_TX_Buff[Port][4] = 0x00; + MD_Connect_TX_Buff[Port][5] = 0x02; + Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0], 6); + MD_Connect_TX_Buff[Port][7] = Tempu64 >> 8; + MD_Connect_TX_Buff[Port][6] = Tempu64; + MD_ConnectTX_Len = 8; + } + break; + } + } + break; + case PosRFID: + { + GunAddr = TXHData.MD_Port_Data[Port].GunData[GunNum].GunAddr; + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake == TXHData.MD_Port_Info[Port].Handshake_Top) + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][GunNum]++; + // if(TXHData.MD_Port_Info[Port].GunInfo[GunNum].SonDevice.SonNumber > 0)//豸ֶ֧ǹЭ + // { + // for(i = 0;i < TXHData.MD_Port_Info[Port].GunInfo[GunNum].SonDevice.SonNumber;i ++) + // if(TXHData.MD_Port_Info[Port].GunInfo[GunNum+i].Handshake != TXHData.MD_Port_Info[Port].Handshake_Top) + // break; + // if(i == TXHData.MD_Port_Info[Port].GunInfo[GunNum].SonDevice.SonNumber && MD_TX_CMD != RFID_MDConnectCmdROMownload)//ǹ,Ҳָ,ʹöǹָ + // MD_TX_CMD = RFID_MDConnectCmdAllData; + // } + switch (MD_TX_CMD) + { + // case RFID_MDConnectCmdAllData://ǹ״̬ + // { + // if(TXHData.MD_Port_Info[Port].GunInfo[GunNum].SonDevice.SonNumber > 0)//豸ֶ֧ǹЭ + // { + // if(GunAddr == TXHData.MD_Port_Info[Port].GunInfo[GunNum].SonDevice.SonAddress[0] || + // GunAddr == TXHData.MD_Port_Info[Port].GunInfo[GunNum].SonDevice.SonAddress[1] || + // GunAddr == TXHData.MD_Port_Info[Port].GunInfo[GunNum].SonDevice.SonAddress[2] || + // GunAddr == TXHData.MD_Port_Info[Port].GunInfo[GunNum].SonDevice.SonAddress[3])//һַʣµĵַ + // { + // TXHData.MD_Port_Info[Port].pGunNow += TXHData.MD_Port_Info[Port].GunInfo[GunNum].SonDevice.SonNumber-1 ; + // } + // } + // MD_Connect_TX_Buff[Port][0] = 0xF5;// + // MD_Connect_TX_Buff[Port][1] = GunAddr; + // MD_Connect_TX_Buff[Port][2] = 0; + // MD_Connect_TX_Buff[Port][3] = 0; + // MD_Connect_TX_Buff[Port][4] = RFID_MDConnectCmdAllData; + // MD_ConnectTX_Len = 5;//λ + // for(DeviceNumber = 0;DeviceNumber < TXHData.MD_Port_Info[Port].GunInfo[GunNum].SonDevice.SonNumber;DeviceNumber ++) + // { + // switch(TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].MB_CMD_Next) // ֽڽвͬIJ + // { + // case RFID_MDConnectCmdReadData: //ѯ + // { + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Data[Port].GunData[GunNum + DeviceNumber].GunAddr; + // MD_ConnectTX_Len ++; + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].MB_CMD_Next; + // MD_ConnectTX_Len ++; + // }break; + // case RFID_MDConnectCmdWriteCardInfo://дȨϢ RFID_MDConnectCmdWriteFullingInfo + // { + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Data[Port].GunData[GunNum + DeviceNumber].GunAddr; + // MD_ConnectTX_Len ++; + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].MB_CMD_Next; + // MD_ConnectTX_Len ++; + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].RFIDState; + // MD_ConnectTX_Len ++; + // if(TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].RFIDState == 0x01) + // { + // for(i = 0;i < 15;i ++) + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len+i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].RFIDUserName[i]; + // MD_ConnectTX_Len += 15; + // for(i = 0;i < 10;i ++) + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len+i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].CarLicensePlate[i]; + // MD_ConnectTX_Len += 10; + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].BalanceDecimal; + // MD_ConnectTX_Len += 1; + // for(i = 0;i < 5;i ++) + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len+i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].Balance[i]; + // MD_ConnectTX_Len += 5; + // } + // else if(TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].RFIDState == 0x20) + // { + // for(i = 0;i < 4;i ++) + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len+i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].Balance[i]; + // MD_ConnectTX_Len += 4; + // } + // }break; + // case RFID_MDConnectCmdWriteFullingInfo://дʵʱϢ + // { + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Data[Port].GunData[GunNum + DeviceNumber].GunAddr; + // MD_ConnectTX_Len ++; + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].MB_CMD_Next; + // MD_ConnectTX_Len ++; + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].RFIDState; + // MD_ConnectTX_Len ++; + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].BalanceDecimal; + // MD_ConnectTX_Len ++; + // for(i = 0;i < 5;i ++) + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len+i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum + DeviceNumber].Balance[i]; + // MD_ConnectTX_Len += 5; + // }break; + // } + // } + // MD_Connect_TX_Buff[Port][2] = MD_ConnectTX_Len >> 8; + // MD_Connect_TX_Buff[Port][3] = MD_ConnectTX_Len; + // Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0],MD_ConnectTX_Len); + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = Tempu64 >> 8; + // MD_ConnectTX_Len ++; + // MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = Tempu64; + // MD_ConnectTX_Len ++; + // }break; + case RFID_MDConnectCmdReadData: // ״̬ + { + MD_Connect_TX_Buff[Port][0] = 0xF5; + MD_Connect_TX_Buff[Port][1] = GunAddr; + MD_Connect_TX_Buff[Port][2] = 0x00; + MD_Connect_TX_Buff[Port][3] = 0x05; + MD_Connect_TX_Buff[Port][4] = RFID_MDConnectCmdReadData; + Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0], 5); + MD_Connect_TX_Buff[Port][5] = Tempu64 >> 8; + MD_Connect_TX_Buff[Port][6] = Tempu64; + MD_ConnectTX_Len = 7; + } + break; + case RFID_MDConnectCmdLossACK: // + case RFID_MDConnectCmdFindACK: // + { + MD_Connect_TX_Buff[Port][0] = 0xF5; + MD_Connect_TX_Buff[Port][1] = GunAddr; + MD_Connect_TX_Buff[Port][2] = 0x00; + MD_Connect_TX_Buff[Port][3] = 0x05; + MD_Connect_TX_Buff[Port][4] = MD_TX_CMD; + Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0], 5); + MD_Connect_TX_Buff[Port][5] = Tempu64 >> 8; + MD_Connect_TX_Buff[Port][6] = Tempu64; + MD_ConnectTX_Len = 7; + } + break; + case RFID_MDConnectCmdWriteCardInfo: // дȨϢ RFID_MDConnectCmdWriteFullingInfo + { + MD_Connect_TX_Buff[Port][0] = 0xF5; + MD_Connect_TX_Buff[Port][1] = GunAddr; + MD_Connect_TX_Buff[Port][2] = 0x00; + + MD_Connect_TX_Buff[Port][4] = RFID_MDConnectCmdWriteCardInfo; + MD_Connect_TX_Buff[Port][5] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].RFIDState; + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].RFIDState == 0x01) + { + MD_ConnectTX_Len = 37; + for (i = 0; i < 15; i++) + MD_Connect_TX_Buff[Port][6 + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].RFIDUserName[i]; + for (i = 0; i < 10; i++) + MD_Connect_TX_Buff[Port][21 + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].CarLicensePlate[i]; + MD_Connect_TX_Buff[Port][31] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].BalanceDecimal; + for (i = 0; i < 5; i++) + MD_Connect_TX_Buff[Port][32 + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].Balance[i]; + } + else if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].RFIDState == 0x20) + { + MD_ConnectTX_Len = 10; + for (i = 0; i < 4; i++) + MD_Connect_TX_Buff[Port][6 + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].Balance[i]; + } + else + { + MD_ConnectTX_Len = 6; + } + MD_Connect_TX_Buff[Port][3] = MD_ConnectTX_Len; + Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0], MD_ConnectTX_Len); + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = Tempu64 >> 8; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + 1] = Tempu64; + MD_ConnectTX_Len = MD_ConnectTX_Len + 2; + } + break; + case RFID_MDConnectCmdWriteFullingInfo: // дʵʱϢ + { + MD_Connect_TX_Buff[Port][0] = 0xF5; + MD_Connect_TX_Buff[Port][1] = GunAddr; + MD_Connect_TX_Buff[Port][2] = 0x00; + + MD_Connect_TX_Buff[Port][4] = RFID_MDConnectCmdWriteFullingInfo; + MD_Connect_TX_Buff[Port][5] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].RFIDState; + MD_ConnectTX_Len = 12; + MD_Connect_TX_Buff[Port][6] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].BalanceDecimal; + for (i = 0; i < 5; i++) + MD_Connect_TX_Buff[Port][7 + i] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].Balance[i]; + MD_Connect_TX_Buff[Port][3] = MD_ConnectTX_Len; + Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0], MD_ConnectTX_Len); + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = Tempu64 >> 8; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + 1] = Tempu64; + MD_ConnectTX_Len = MD_ConnectTX_Len + 2; + } + break; + case RFID_MDConnectCmdWriteBindingInfo: // ·Ϣ + { + MD_ConnectTX_Len = 6; + MD_Connect_TX_Buff[Port][0] = 0xF5; + MD_Connect_TX_Buff[Port][1] = GunAddr; + MD_Connect_TX_Buff[Port][2] = 0x00; + MD_Connect_TX_Buff[Port][3] = MD_ConnectTX_Len; + MD_Connect_TX_Buff[Port][4] = RFID_MDConnectCmdWriteBindingInfo; + MD_Connect_TX_Buff[Port][5] = TXHData.MD_Port_Data[Port].GunData[GunNum].RFIDBinding; + + Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0], MD_ConnectTX_Len); + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = Tempu64 >> 8; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + 1] = Tempu64; + MD_ConnectTX_Len = MD_ConnectTX_Len + 2; + } + break; + case RFID_MDConnectCmdReadVersion: // 汾 + { + MD_Connect_TX_Buff[Port][0] = 0xF5; + MD_Connect_TX_Buff[Port][1] = GunAddr; + MD_Connect_TX_Buff[Port][2] = 0x00; + MD_Connect_TX_Buff[Port][3] = 0x05; + MD_Connect_TX_Buff[Port][4] = RFID_MDConnectCmdReadVersion; + Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0], 5); + MD_Connect_TX_Buff[Port][5] = Tempu64 >> 8; + MD_Connect_TX_Buff[Port][6] = Tempu64; + MD_ConnectTX_Len = 7; + } + break; + case RFID_MDConnectCmdROMownload: // ̼· + { + MD_ConnectTX_Len = 531; + MD_Connect_TX_Buff[Port][0] = 0xF5; + MD_Connect_TX_Buff[Port][1] = GunAddr; + MD_Connect_TX_Buff[Port][2] = MD_ConnectTX_Len >> 8; + MD_Connect_TX_Buff[Port][3] = MD_ConnectTX_Len & 0xff; + MD_Connect_TX_Buff[Port][4] = RFID_MDConnectCmdROMownload; + for (i = 0; i < 10; i++) + MD_Connect_TX_Buff[Port][5 + i] = TXHData.MD_Port_Data[Port].PortData.ROM_UpData_Version[i]; + MD_Connect_TX_Buff[Port][15] = TXHData.MD_Port_Data[Port].PortData.ROM_UpData.FrameTop >> 8; + MD_Connect_TX_Buff[Port][16] = TXHData.MD_Port_Data[Port].PortData.ROM_UpData.FrameTop; + MD_Connect_TX_Buff[Port][17] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].FrameNow >> 8; + MD_Connect_TX_Buff[Port][18] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].FrameNow; + AT45DBItemRead(CA_DeviceFrame, TXHData.MD_Port_Info[Port].GunInfo[GunNum].FrameNow + Port * 1024); + for (i = 0; i < 512; i++) + MD_Connect_TX_Buff[Port][19 + i] = TXHData.Frame[i]; + Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0], MD_ConnectTX_Len); + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len] = Tempu64 >> 8; + MD_Connect_TX_Buff[Port][MD_ConnectTX_Len + 1] = Tempu64; + MD_ConnectTX_Len = MD_ConnectTX_Len + 2; + } + break; + } + } + break; + case PosYGao: + { + GunAddr = (TXHData.MD_Port_Data[Port].GunData[GunNum].GunAddr); + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake == TXHData.MD_Port_Info[Port].Handshake_Top) + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][GunNum]++; + switch (MD_TX_CMD) + { + case YG_MDConnectCmdReadFuelVolumeState: // ״̬+ + { + MD_Connect_TX_Buff[Port][0] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][2] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][3] = MD_TX_CMD; + MD_Connect_TX_Buff[Port][4] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][5] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][3], 2); // У + MD_ConnectTX_Len = 6; + } + break; + case YG_MDConnectCmdReadFuelRecord: // ¼ + { + MD_Connect_TX_Buff[Port][0] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][2] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][3] = MD_TX_CMD; + MD_Connect_TX_Buff[Port][4] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][5] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][3], 2); // У + MD_ConnectTX_Len = 6; + } + break; + case YG_MDConnectCmdReadFuelRecordConfirm: // ¼ȷϢ + { + MD_Connect_TX_Buff[Port][0] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][2] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][3] = MD_TX_CMD; + MD_Connect_TX_Buff[Port][4] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][5] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][3], 2); // У + MD_ConnectTX_Len = 6; + TXHData.MD_Port_Info[Port].GunInfo[GunNum].MB_CMD_Next = YG_MDConnectCmdReadFuelVolumeState; + } + break; + case YG_MDConnectCmdWritePrset: // Ԥ + { + MD_Connect_TX_Buff[Port][0] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][2] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][3] = MD_TX_CMD; + MD_Connect_TX_Buff[Port][4] = GunAddr; // ǹ + + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresteType == Preset_Volume) + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >= 0x90000000) + Tempu64 = 0x900000; + else + Tempu64 = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][5 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + Tempu64 = 0; + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][8 + i] = (Tempu64 >> ((3 - i) * 8)) & 0xff; + } + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][12 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + Tempu64 = TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][15 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + Tempu64 = 100000000 / TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price; + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][18 + i] = (Tempu64 >> ((3 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][22] = 0; + } + else if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresteType == Preset_Sale) + { + Tempu64 = 0; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][5 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >= 0x90000000) + Tempu64 = 0x900000; + else + Tempu64 = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue; + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][8 + i] = (Tempu64 >> ((3 - i) * 8)) & 0xff; + } + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][12 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + Tempu64 = TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][15 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + Tempu64 = 100000000 / TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price; + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][18 + i] = (Tempu64 >> ((3 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][22] = 1; + } + Tempu64 = TXHData.MD_Port_Data[Port].GunData[GunNum].OrderNumber + 1; + for (i = 0; i < 2; i++) + { + MD_Connect_TX_Buff[Port][23 + i] = (Tempu64 >> ((1 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][25] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][3], 22); // У + MD_ConnectTX_Len = 26; + } + break; + case YG_MDConnectCmdStart: // + { + MD_Connect_TX_Buff[Port][0] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][2] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][3] = MD_TX_CMD; + MD_Connect_TX_Buff[Port][4] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][5] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][3], 2); // У + MD_ConnectTX_Len = 6; + } + break; + case YG_MDConnectCmdStop: // ͣ + { + MD_Connect_TX_Buff[Port][0] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][2] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][3] = MD_TX_CMD; + MD_Connect_TX_Buff[Port][4] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][5] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][3], 2); // У + MD_ConnectTX_Len = 6; + } + break; + case YG_MDConnectCmdWritePrice: // xie + { + MD_Connect_TX_Buff[Port][0] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][2] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][3] = MD_TX_CMD; + MD_Connect_TX_Buff[Port][4] = GunAddr; // ǹ + Tempu64 = TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][5 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + Tempu64 = 100000000 / MD_Connect_BCDTou64(TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price); + Tempu64 = MD_Connect_u64ToBCD(Tempu64); + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][8 + i] = (Tempu64 >> ((3 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][12] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][3], 9); // У + MD_ConnectTX_Len = 13; + } + break; + case YG_MDConnectCmdReadTotal: // + { + MD_Connect_TX_Buff[Port][0] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][2] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][3] = MD_TX_CMD; + MD_Connect_TX_Buff[Port][4] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][5] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][3], 2); // У + MD_ConnectTX_Len = 6; + } + break; + case YG_MDConnectControlMode: // ҪȨ + { + MD_Connect_TX_Buff[Port][0] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][2] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][3] = MD_TX_CMD; + MD_Connect_TX_Buff[Port][4] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][5] = 0x55; // ģʽ + MD_Connect_TX_Buff[Port][6] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][3], 3); // У + MD_ConnectTX_Len = 7; + } + break; + case YG_MDConnectCmdLock: // + { + MD_Connect_TX_Buff[Port][0] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][2] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][3] = MD_TX_CMD; + MD_Connect_TX_Buff[Port][4] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][5] = 0xAA; // ģʽ + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][6 + i] = 0x00; + } + MD_Connect_TX_Buff[Port][9] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][3], 6); // У + MD_ConnectTX_Len = 10; + } + break; + case YG_MDConnectCmdUnLock: // + { + MD_Connect_TX_Buff[Port][0] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][2] = 0xFA; // ֡ͷ + MD_Connect_TX_Buff[Port][3] = MD_TX_CMD; + MD_Connect_TX_Buff[Port][4] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][5] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][3], 2); // У + MD_ConnectTX_Len = 6; + } + break; + } + } + break; + case PosHongYang: + { + GunAddr = TXHData.MD_Port_Data[Port].GunData[GunNum].GunAddr; + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake == TXHData.MD_Port_Info[Port].Handshake_Top) + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][GunNum]++; + switch (Port) + { + case 0: + MD_Connect_TX1_DMAAddrSet((uint32_t)&HY_SendBuff); + break; + case 1: + MD_Connect_TX2_DMAAddrSet((uint32_t)&HY_SendBuff); + break; + case 2: + MD_Connect_TX3_DMAAddrSet((uint32_t)&HY_SendBuff); + break; + case 3: + MD_Connect_TX4_DMAAddrSet((uint32_t)&HY_SendBuff); + break; + } + switch (MD_TX_CMD) + { + case HY_MDConnectCmdReadFuelData: // + { + MD_Connect_TX_Buff[Port][0] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][1] = 0x03; + MD_Connect_TX_Buff[Port][2] = HY_MDConnectCmdReadFuelData; + MD_Connect_TX_Buff[Port][3] = InteiHEXCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 4; + + if (GunAddr <= 64) + HY_SendBuff[0] = GunAddr | 0x100; + else + HY_SendBuff[0] = GunAddr; + for (i = 1; i < MD_ConnectTX_Len; i++) + HY_SendBuff[i] = MD_Connect_TX_Buff[Port][i]; + } + break; + case HY_MDConnectCmdWritePrsetSale: // Ԥý + { + MD_Connect_TX_Buff[Port][0] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = HY_MDConnectCmdWritePrsetSale; + if (TXHData.MD_Port_Data[Port].PortData.Device_Type == Display_664) + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >= 0x900000) + Tempu64 = 0x900000; + else + Tempu64 = MD_Connect_BCDTou64(TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue); + MD_Connect_TX_Buff[Port][1] = 0x06; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][6] = CheckSum8(&MD_Connect_TX_Buff[Port][0], 6); // У + MD_ConnectTX_Len = 7; + } + else + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >= 0x90000000) + Tempu64 = 0x90000000; + else + Tempu64 = MD_Connect_BCDTou64(TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue); + MD_Connect_TX_Buff[Port][1] = 0x07; + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = (Tempu64 >> ((3 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][7] = InteiHEXCheck(&MD_Connect_TX_Buff[Port][0], 7); // У + MD_ConnectTX_Len = 8; + } + if (GunAddr <= 64) + HY_SendBuff[0] = GunAddr | 0x100; + else + HY_SendBuff[0] = GunAddr; + for (i = 1; i < MD_ConnectTX_Len; i++) + HY_SendBuff[i] = MD_Connect_TX_Buff[Port][i]; + } + break; + case HY_MDConnectCmdWritePrsetVolume: // Ԥ + { + MD_Connect_TX_Buff[Port][0] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = HY_MDConnectCmdWritePrsetVolume; + if (TXHData.MD_Port_Data[Port].PortData.Device_Type == Display_664) + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue == 0x900000) + Tempu64 = 0x900000; + else + Tempu64 = MD_Connect_BCDTou64(TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue); + MD_Connect_TX_Buff[Port][1] = 0x06; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][6] = CheckSum8(&MD_Connect_TX_Buff[Port][0], 6); // У + MD_ConnectTX_Len = 7; + } + else + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue == 0x90000000) + Tempu64 = 0x90000000; + else + Tempu64 = MD_Connect_BCDTou64(TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue); + MD_Connect_TX_Buff[Port][1] = 0x07; + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = (Tempu64 >> ((3 - i) * 8)) & 0xff; + } + + MD_Connect_TX_Buff[Port][7] = InteiHEXCheck(&MD_Connect_TX_Buff[Port][0], 7); // У + MD_ConnectTX_Len = 8; + } + if (GunAddr <= 64) + HY_SendBuff[0] = GunAddr | 0x100; + else + HY_SendBuff[0] = GunAddr; + for (i = 1; i < MD_ConnectTX_Len; i++) + HY_SendBuff[i] = MD_Connect_TX_Buff[Port][i]; + } + break; + case HY_MDConnectCmdStart: // + { + MD_Connect_TX_Buff[Port][0] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][1] = 0x03; + MD_Connect_TX_Buff[Port][2] = HY_MDConnectCmdStart; + MD_Connect_TX_Buff[Port][3] = InteiHEXCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 4; + if (GunAddr <= 64) + HY_SendBuff[0] = GunAddr | 0x100; + else + HY_SendBuff[0] = GunAddr; + for (i = 1; i < MD_ConnectTX_Len; i++) + HY_SendBuff[i] = MD_Connect_TX_Buff[Port][i]; + TXHData.MD_Port_Data[Port].GunData[GunNum].GunState.Flag.AuthorizeState = 1; + FMItemWrite(CF_MD_Port_Data, Port); + } + break; + case HY_MDConnectCmdStop: // ͣ + { + MD_Connect_TX_Buff[Port][0] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][1] = 0x03; + MD_Connect_TX_Buff[Port][2] = HY_MDConnectCmdStop; + MD_Connect_TX_Buff[Port][3] = InteiHEXCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 4; + if (GunAddr <= 64) + HY_SendBuff[0] = GunAddr | 0x100; + else + HY_SendBuff[0] = GunAddr; + for (i = 1; i < MD_ConnectTX_Len; i++) + HY_SendBuff[i] = MD_Connect_TX_Buff[Port][i]; + } + break; + case HY_MDConnectCmdReadPrice: // + { + MD_Connect_TX_Buff[Port][0] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][1] = 0x03; + MD_Connect_TX_Buff[Port][2] = HY_MDConnectCmdReadPrice; + MD_Connect_TX_Buff[Port][3] = InteiHEXCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 4; + if (GunAddr <= 64) + HY_SendBuff[0] = GunAddr | 0x100; + else + HY_SendBuff[0] = GunAddr; + for (i = 1; i < MD_ConnectTX_Len; i++) + HY_SendBuff[i] = MD_Connect_TX_Buff[Port][i]; + } + break; + case HY_MDConnectCmdWritePrice: // xie + { + MD_Connect_TX_Buff[Port][0] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = HY_MDConnectCmdWritePrice; + MD_Connect_TX_Buff[Port][1] = 0x07; + Tempu64 = MD_Connect_BCDTou64(TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price); + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = ((Tempu64) >> ((3 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][7] = InteiHEXCheck(&MD_Connect_TX_Buff[Port][0], 7); // У + MD_ConnectTX_Len = 8; + if (GunAddr <= 64) + HY_SendBuff[0] = GunAddr | 0x100; + else + HY_SendBuff[0] = GunAddr; + for (i = 1; i < MD_ConnectTX_Len; i++) + HY_SendBuff[i] = MD_Connect_TX_Buff[Port][i]; + } + break; + case HY_MDConnectCmdReadTotal: // + { + MD_Connect_TX_Buff[Port][0] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][1] = 0x03; + MD_Connect_TX_Buff[Port][2] = HY_MDConnectCmdReadTotal; + MD_Connect_TX_Buff[Port][3] = InteiHEXCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 4; + if (GunAddr <= 64) + HY_SendBuff[0] = GunAddr | 0x100; + else + HY_SendBuff[0] = GunAddr; + for (i = 1; i < MD_ConnectTX_Len; i++) + HY_SendBuff[i] = MD_Connect_TX_Buff[Port][i]; + } + break; + case HY_MDConnectASKControlPower: // ҪȨ + { + MD_Connect_TX_Buff[Port][0] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][1] = 0x03; + MD_Connect_TX_Buff[Port][2] = HY_MDConnectASKControlPower; + MD_Connect_TX_Buff[Port][3] = InteiHEXCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 4; + if (GunAddr <= 64) + HY_SendBuff[0] = GunAddr | 0x100; + else + HY_SendBuff[0] = GunAddr; + for (i = 1; i < MD_ConnectTX_Len; i++) + HY_SendBuff[i] = MD_Connect_TX_Buff[Port][i]; + } + break; + case HY_MDConnectReturnControlPower: // Ȩ + { + MD_Connect_TX_Buff[Port][0] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][1] = 0x03; + MD_Connect_TX_Buff[Port][2] = HY_MDConnectReturnControlPower; + MD_Connect_TX_Buff[Port][3] = InteiHEXCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 4; + if (GunAddr <= 64) + HY_SendBuff[0] = GunAddr | 0x100; + else + HY_SendBuff[0] = GunAddr; + for (i = 1; i < MD_ConnectTX_Len; i++) + HY_SendBuff[i] = MD_Connect_TX_Buff[Port][i]; + } + break; + } + } + break; + case PosLanFeng: + { + GunAddr = MD_Connect_u64ToBCD(TXHData.MD_Port_Data[Port].GunData[GunNum].GunAddr); + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake == TXHData.MD_Port_Info[Port].Handshake_Top) + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][GunNum]++; + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].ROM_UpData_State.Flag.BaudRateSync_Flag == 1) + { + MD_Connect_USART_Configuration(Port, BaudRateSync, USART_WordLength_9b, TXHData.MD_Port_Data[Port].PortData.Parity_Even); + } + else + { + MD_Connect_USART_Configuration(Port, TXHData.MD_Port_Data[Port].PortData.BaudRate, USART_WordLength_9b, TXHData.MD_Port_Data[Port].PortData.Parity_Even); + } + switch (MD_TX_CMD) + { + case LF_MDConnectCmdReadState: // ״̬ + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = LF_MDConnectCmdReadState; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case LF_MDConnectCmdWritePrset: // Ԥý + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + if (TXHData.MD_Port_Data[Port].PortData.Device_Type == Display_664) + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >= 0x900000) + Tempu64 = 0x900000; + else + Tempu64 = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue; + MD_Connect_TX_Buff[Port][2] = 0xA5; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = (Tempu64 >> ((2 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][6] = C_MDConnectCmdWritePrsetSale; + MD_Connect_TX_Buff[Port][7] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 6); // У + MD_ConnectTX_Len = 8; + } + else + { + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >= 0x90000000) + Tempu64 = 0x90000000; + else + Tempu64 = TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue; + MD_Connect_TX_Buff[Port][2] = 0xA6; + for (i = 0; i < 4; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = (Tempu64 >> ((3 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][7] = LF_MDConnectCmdWritePrset; + MD_Connect_TX_Buff[Port][8] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 7); // У + MD_ConnectTX_Len = 9; + } + } + break; + case LF_MDConnectCmdStop: // ͣ + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = LF_MDConnectCmdStop; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case LF_MDConnectCmdWritePrice: // xie + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + if (TXHData.MD_Port_Data[Port].PortData.Device_Type == Display_664) + { + MD_Connect_TX_Buff[Port][2] = 0xA4; + for (i = 0; i < 2; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price) >> ((1 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][5] = C_MDConnectCmdWritePrice; + MD_Connect_TX_Buff[Port][6] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 5); // У + MD_ConnectTX_Len = 7; + } + else + { + MD_Connect_TX_Buff[Port][2] = 0xA5; + for (i = 0; i < 3; i++) + { + MD_Connect_TX_Buff[Port][3 + i] = ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].Price) >> ((2 - i) * 8)) & 0xff; + } + MD_Connect_TX_Buff[Port][6] = LF_MDConnectCmdWritePrice; + MD_Connect_TX_Buff[Port][7] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 6); // У + MD_ConnectTX_Len = 8; + } + } + break; + case LF_MDConnectCmdReadTotal: // + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = LF_MDConnectCmdReadTotal; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case LF_MDConnectASKControlPower: // ҪȨ + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = LF_MDConnectASKControlPower; + // MD_Connect_TX_Buff[Port][3] = C_MDConnectReturnControlPower; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + case LF_MDConnectReturnControlPower: // Ȩ + { + MD_Connect_TX_Buff[Port][0] = 0xf5; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr; // ǹ + MD_Connect_TX_Buff[Port][2] = 0xA2; + MD_Connect_TX_Buff[Port][3] = LF_MDConnectReturnControlPower; + MD_Connect_TX_Buff[Port][4] = MD_Connect_TXDataCheck(&MD_Connect_TX_Buff[Port][0], 3); // У + MD_ConnectTX_Len = 5; + } + break; + } + } + break; + case PosSSLan: // + { + FatherNum = GunNum; // GunNumʾú + GunNum = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].SonStart + TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].SonNow; // + GunAddr = TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].Address; // õַ + if (TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].Handshake == TXHData.MD_Port_Info[Port].Handshake_Top) + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][FatherNum]++; + if (GunAddr > 0) + GunAddr -= 1; + switch (MD_TX_CMD) + { + case LY_MDConnectCmdHandshake: // + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x30; + MD_Connect_TX_Buff[Port][4] = 0x30; + MD_Connect_TX_Buff[Port][5] = (TXHData.MD_Port_Info[Port].GunInfo[GunNum].LYHandshakeCRC >> 4) & 0x0f; + if (MD_Connect_TX_Buff[Port][5] < 0x0A) + MD_Connect_TX_Buff[Port][5] += 0x30; + else + MD_Connect_TX_Buff[Port][5] = MD_Connect_TX_Buff[Port][5] - 0x0A + 0x41; + MD_Connect_TX_Buff[Port][6] = TXHData.MD_Port_Info[Port].GunInfo[GunNum].LYHandshakeCRC & 0x0f; + if (MD_Connect_TX_Buff[Port][6] < 0x0A) + MD_Connect_TX_Buff[Port][6] += 0x30; + else + MD_Connect_TX_Buff[Port][6] = MD_Connect_TX_Buff[Port][6] - 0x0A + 0x41; + MD_Connect_TX_Buff[Port][7] = 0x03; + MD_Connect_TX_Buff[Port][8] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 7); // У + MD_ConnectTX_Len = 9; + // if(TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake == 0x06) + // { + // TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake = 0x07; + // } + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake = 0x08; + } + break; + case LY_MDConnectCmdPoll: // ѯ + { + MD_Connect_TX_Buff[Port][0] = 0x04; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x51; + MD_Connect_TX_Buff[Port][3] = 0x05; + MD_ConnectTX_Len = 4; + } + break; + case LY_MDConnectCmdReadState: // ״̬ + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x31; + MD_Connect_TX_Buff[Port][4] = 0x35; + MD_Connect_TX_Buff[Port][5] = 0x03; + MD_Connect_TX_Buff[Port][6] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 5); // У + MD_ConnectTX_Len = 7; + } + break; + case LY_MDConnectCmdReadTotal: // ״̬ + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x32; + MD_Connect_TX_Buff[Port][4] = 0x30; + MD_Connect_TX_Buff[Port][5] = 0x03; + MD_Connect_TX_Buff[Port][6] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 5); // У + MD_ConnectTX_Len = 7; + } + break; + case LY_MDConnectCmdChoiceGun: // ѡǹ + { + MD_Connect_TX_Buff[Port][0] = 0x04; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x05; + MD_ConnectTX_Len = 4; + // if(TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake == 0x02) + // { + // TXHData.MD_Port_Info[Port].GunInfo[GunNum].Handshake = 0x03; + // } + } + break; + case LY_MDConnectCmdDisauthorize: // ȡȨ + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x31; + MD_Connect_TX_Buff[Port][4] = 0x32; + MD_Connect_TX_Buff[Port][5] = 0x03; + MD_Connect_TX_Buff[Port][6] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 5); // У + MD_ConnectTX_Len = 7; + TXHData.MD_Port_Data[Port].GunData[GunNum].GunState.Flag.AuthorizeState = 0; + } + break; + case LY_MDConnectCmdAuthorize: // Ȩ + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x31; + MD_Connect_TX_Buff[Port][4] = 0x31; + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >= 0x900000) + MD_Connect_TX_Buff[Port][5] = 0x30; + else + { + MD_Connect_TX_Buff[Port][5] = 0x32; + } + if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresteType == Preset_Volume) + MD_Connect_TX_Buff[Port][6] = 0x31; + else if (TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresteType == Preset_Sale) + MD_Connect_TX_Buff[Port][6] = 0x32; + for (i = 0; i < 6; i++) + MD_Connect_TX_Buff[Port][7 + i] = 0x30 + ((TXHData.MD_Port_Info[Port].GunInfo[GunNum].PresetValue >> (5 - i) * 4) & 0x0f); + for (i = 0; i < 30; i++) + MD_Connect_TX_Buff[Port][13 + i] = 0x30; + for (j = 0; j < 6; j++) + { + if ((TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].SonNow == j) && TXHData.MD_Port_Info[Port].GunInfo[TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].SonStart + j].Price != 0) + MD_Connect_TX_Buff[Port][13 + j * 5] = 0x32; + else + MD_Connect_TX_Buff[Port][13 + j * 5] = 0x30; + for (i = 0; i < 4; i++) + MD_Connect_TX_Buff[Port][14 + i + j * 5] = 0x30 + ((TXHData.MD_Port_Info[Port].GunInfo[TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].SonStart + j].Price >> (3 - i) * 4) & 0x0f); + } + MD_Connect_TX_Buff[Port][13 + 30] = 0x03; + MD_Connect_TX_Buff[Port][14 + 30] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 13 + 30); // У + MD_ConnectTX_Len = 15 + 30; + } + break; + case LY_MDConnectCmdWritePrice: // д + { + MD_Connect_TX_Buff[Port][0] = 0x02; // ֡ͷ + MD_Connect_TX_Buff[Port][1] = GunAddr + 0x40; // ǹ + MD_Connect_TX_Buff[Port][2] = 0x41; + MD_Connect_TX_Buff[Port][3] = 0x32; + MD_Connect_TX_Buff[Port][4] = 0x31; + MD_Connect_TX_Buff[Port][5] = 0x32; + for (i = 0; i < 30; i++) + MD_Connect_TX_Buff[Port][6 + i] = 0x30; + for (j = 0; j < 6; j++) + { + if ((TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].SonNow == j) && TXHData.MD_Port_Info[Port].GunInfo[TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].SonStart + j].Price != 0) + MD_Connect_TX_Buff[Port][6 + j * 5] = 0x32; + else + MD_Connect_TX_Buff[Port][6 + j * 5] = 0x30; + for (i = 0; i < 4; i++) + MD_Connect_TX_Buff[Port][7 + i + j * 5] = 0x30 + ((TXHData.MD_Port_Info[Port].GunInfo[TXHData.MD_Port_Info[Port].FatherDevice[FatherNum].SonStart + j].Price >> (3 - i) * 4) & 0x0f); + } + MD_Connect_TX_Buff[Port][36] = 0x03; + MD_Connect_TX_Buff[Port][37] = BCC_CheckSum(&MD_Connect_TX_Buff[Port][1], 36); // У + MD_ConnectTX_Len = 38; + } + break; + case LY_MDConnectCmdACK0: // 1030 + { + MD_Connect_TX_Buff[Port][0] = 0x10; + MD_Connect_TX_Buff[Port][1] = 0x30; + MD_ConnectTX_Len = 2; + } + break; + case LY_MDConnectCmdACK1: // 1031 + { + MD_Connect_TX_Buff[Port][0] = 0x10; + MD_Connect_TX_Buff[Port][1] = 0x31; + MD_ConnectTX_Len = 2; + } + break; + } + } + break; + + case PosPLC: + { + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][GunNum]++; + switch (MD_TX_CMD) + { + case PLC_MDConnectCmdReadData: // ѯ + { + MD_Connect_TX_Buff[Port][0] = 0x03; + MD_Connect_TX_Buff[Port][1] = 0x03; + MD_Connect_TX_Buff[Port][2] = 0x00; + MD_Connect_TX_Buff[Port][3] = 0x00; + MD_Connect_TX_Buff[Port][4] = 0x00; + MD_Connect_TX_Buff[Port][5] = 26; + Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0], 6); + MD_Connect_TX_Buff[Port][7] = Tempu64 >> 8; + MD_Connect_TX_Buff[Port][6] = Tempu64; + MD_ConnectTX_Len = 8; + // TXHData.MD_Port_Info[Port].GunInfo[0].MB_CMD_Next = PLC_MDConnectCmdReadErro; + } + break; + case PLC_MDConnectCmdReadErro: // ״̬ + { + MD_Connect_TX_Buff[Port][0] = 0x03; + MD_Connect_TX_Buff[Port][1] = 0x03; + MD_Connect_TX_Buff[Port][2] = 0x00; + MD_Connect_TX_Buff[Port][3] = 30; + MD_Connect_TX_Buff[Port][4] = 0; + MD_Connect_TX_Buff[Port][5] = 3; + Tempu64 = CRC_Check(&MD_Connect_TX_Buff[Port][0], 6); + MD_Connect_TX_Buff[Port][7] = Tempu64 >> 8; + MD_Connect_TX_Buff[Port][6] = Tempu64; + MD_ConnectTX_Len = 8; + // TXHData.MD_Port_Info[Port].GunInfo[0].MB_CMD_Next = PLC_MDConnectCmdReadData; + } + break; + } + } + break; + case PosPrice1_4: + { + TXHData.MD_Port_Info[Port].LoopGunNextFlag = 1; + TXHData.MBCountCutNum[Port][GunNum]++; + switch (MD_TX_CMD) + { + case Price_MDConnectCmdWriteParameter: // д + { + MD_Connect_TX_Buff[Port][0] = 0xFE; + MD_Connect_TX_Buff[Port][1] = 0xFF; + MD_Connect_TX_Buff[Port][2] = 0x04; + MD_Connect_TX_Buff[Port][3] = 0x01; + MD_Connect_TX_Buff[Port][4] = 0x03; + Tempu64 = Price_DataCheck(&MD_Connect_TX_Buff[Port][2], MD_Connect_TX_Buff[Port][2] - 1); + MD_Connect_TX_Buff[Port][5] = Tempu64; + MD_Connect_TX_Buff[Port][6] = 0xEF; + MD_ConnectTX_Len = 7; + } + break; + case Price_MDConnectCmdReadParameter: // + { + MD_Connect_TX_Buff[Port][0] = 0xFE; + MD_Connect_TX_Buff[Port][1] = 0xFF; + MD_Connect_TX_Buff[Port][2] = 0x04; + MD_Connect_TX_Buff[Port][3] = 0x01; + MD_Connect_TX_Buff[Port][4] = 0x02; + Tempu64 = Price_DataCheck(&MD_Connect_TX_Buff[Port][2], MD_Connect_TX_Buff[Port][2] - 1); + MD_Connect_TX_Buff[Port][5] = Tempu64; + MD_Connect_TX_Buff[Port][6] = 0xEF; + MD_ConnectTX_Len = 7; + } + break; + case Price_MDConnectCmdWriteDecimal: // дСλMD_Port_Info_Type + { + MD_Connect_TX_Buff[Port][0] = 0xFE; + MD_Connect_TX_Buff[Port][1] = 0xFF; + MD_Connect_TX_Buff[Port][2] = 16; + MD_Connect_TX_Buff[Port][3] = 0x01; + MD_Connect_TX_Buff[Port][4] = 0x04; + for (j = 0; j < TXHData.MD_Port_Info[Port].PriceTagData.PriceNumber; j++) + { + MD_Connect_TX_Buff[Port][5 + j] = TXHData.MD_Port_Info[Port].PriceTagData.Length - TXHData.MD_Port_Info[Port].PriceTagData.Decimal[j]; + } + for (j = TXHData.MD_Port_Info[Port].PriceTagData.PriceNumber; j < 17; j++) + MD_Connect_TX_Buff[Port][5 + j] = 0; + Tempu64 = Price_DataCheck(&MD_Connect_TX_Buff[Port][2], MD_Connect_TX_Buff[Port][2] - 1); + MD_Connect_TX_Buff[Port][17] = Tempu64; + MD_Connect_TX_Buff[Port][18] = 0xEF; + MD_ConnectTX_Len = 19; + } + break; + case Price_MDConnectCmdWritePrice: // д + { + MD_Connect_TX_Buff[Port][0] = 0xFE; + MD_Connect_TX_Buff[Port][1] = 0xFF; + MD_Connect_TX_Buff[Port][2] = 40; + MD_Connect_TX_Buff[Port][3] = 0x01; + MD_Connect_TX_Buff[Port][4] = 0x01; + for (i = 5; i < 40; i++) + MD_Connect_TX_Buff[Port][i] = 0; + for (i = 0; i < TXHData.MD_Port_Info[Port].PriceTagData.PriceNumber; i++) + { + for (j = 0; j < 3; j++) + { + if (TXHData.MD_Port_Info[Port].PriceTagData.Length / 2 > j) + MD_Connect_TX_Buff[Port][5 + j + (i * 3)] = TXHData.MD_Port_Info[Port].PriceTagData.Price[i] >> ((TXHData.MD_Port_Info[Port].PriceTagData.Length / 2 - 1 - j) * 8); + else + MD_Connect_TX_Buff[Port][5 + j + (i * 3)] = 0; + } + } + Tempu64 = Price_DataCheck(&MD_Connect_TX_Buff[Port][2], MD_Connect_TX_Buff[Port][2] - 1); + MD_Connect_TX_Buff[Port][41] = Tempu64; + MD_Connect_TX_Buff[Port][42] = 0xEF; + MD_ConnectTX_Len = 43; + } + break; + case Price_MDConnectCmdReadPrice: // + { + MD_Connect_TX_Buff[Port][0] = 0xFE; + MD_Connect_TX_Buff[Port][1] = 0xFF; + MD_Connect_TX_Buff[Port][2] = 0x04; + MD_Connect_TX_Buff[Port][3] = 0x01; + MD_Connect_TX_Buff[Port][4] = 0x03; + Tempu64 = Price_DataCheck(&MD_Connect_TX_Buff[Port][2], MD_Connect_TX_Buff[Port][2] - 1); + MD_Connect_TX_Buff[Port][5] = Tempu64; + MD_Connect_TX_Buff[Port][6] = 0xEF; + MD_ConnectTX_Len = 7; + } + break; + } + } + break; + } + switch (Port) + { + case 0: + { + if (MD_ConnectTX_Len) + { + MD_Connect_RS485_Tx1EN; + MD_Connect_TX1_DMALenSet(MD_ConnectTX_Len); + MD_Connect_TX1_DMAStart(); + } + } + break; + case 1: + { + if (MD_ConnectTX_Len) + { + MD_Connect_RS485_Tx2EN; + MD_Connect_TX2_DMALenSet(MD_ConnectTX_Len); + MD_Connect_TX2_DMAStart(); + } + } + break; + case 2: + { + if (MD_ConnectTX_Len) + { + MD_Connect_RS485_Tx3EN; + MD_Connect_TX3_DMALenSet(MD_ConnectTX_Len); + MD_Connect_TX3_DMAStart(); + } + } + break; + case 3: + { + if (MD_ConnectTX_Len) + { + MD_Connect_RS485_Tx4EN; + MD_Connect_TX4_DMALenSet(MD_ConnectTX_Len); + MD_Connect_TX4_DMAStart(); + } + } + break; + } + if (TXHData.UDisk_Flag) + Log_Task(&MD_Connect_TX_Buff[Port][0], MD_ConnectTX_Len, Port, Info_Issue); + } + else + { + TXHData.MBCountCutNum[Port][GunNum]++; + } + } + else if (TXHData.MDConnectState[Port].Flag.WorkMode == 0) // ָģʽ + { + switch (TXHData.MDConnectState[Port].Flag.SetModeCMDNext) + { + case WIFI_ATRec: + { + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < strlen(MD_ATRec); i++) + MD_Connect_TX_Buff[Port][i] = MD_ATRec[i]; + MD_ConnectTX_Len = (i); // ÷DMA + TXHData.MBCountTimer[Port].TimerCountMax = 1000; + } + break; + case WIFI_WMODE: + { + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < strlen(MD_WMODE); i++) + MD_Connect_TX_Buff[Port][i] = MD_WMODE[i]; + MD_ConnectTX_Len = (i); // ÷DMA + } + break; + case WIFI_WifiRST: + { + for (i = 0; i < strlen(MD_WifiRST); i++) + MD_Connect_TX_Buff[Port][i] = MD_WifiRST[i]; + MD_ConnectTX_Len = (i); // ÷DMA + + TXHData.MBCountTimer[Port].TimerCountMax = 1000 * 10; + } + break; + case WIFI_WifiWSSSID: + { + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < strlen(MD_WifiWSSSID); i++) + MD_Connect_TX_Buff[Port][i] = MD_WifiWSSSID[i]; + MD_Connect_TX_Buff[Port][11] = 0x31 + Port; + MD_Connect_TX_Buff[Port][22] = 0x31 + Port * 3; + if (Port == 3) + { + MD_Connect_TX_Buff[Port][22] = 0x31; + MD_Connect_TX_Buff[Port][23] = 0x30; + MD_Connect_TX_Buff[Port][24] = 0x0D; + MD_Connect_TX_Buff[Port][25] = 0x0A; + i++; + } + MD_ConnectTX_Len = (i); // ÷DMA + + TXHData.MBCountTimer[Port].TimerCountMax = 1000 * 10; + } + break; + case WIFI_WifiRSSI: + { + for (i = 0; i < strlen(MD_WifiRSSI); i++) + MD_Connect_TX_Buff[Port][i] = MD_WifiRSSI[i]; + MD_ConnectTX_Len = (i); // ÷DMA + + TXHData.MDConnectState[Port].Flag.SetModeCMDNext = WIFI_WifiSOCKET; + TXHData.MBCountTimer[Port].TimerCountMax = 1000 * 2; + } + break; + case WIFI_WifiSOCKET: + { + { + for (i = 0; i < strlen(MD_WifiSOCKET); i++) + MD_Connect_TX_Buff[Port][i] = MD_WifiSOCKET[i]; + MD_ConnectTX_Len = (i); // ÷DMA + } + TXHData.MBCountTimer[Port].TimerCountMax = 1000 * 10; + } + break; + } + switch (Port) + { + case 0: + { + if (MD_ConnectTX_Len) + { + MD_Connect_RS485_Tx1EN; + MD_Connect_TX1_DMALenSet(MD_ConnectTX_Len); + MD_Connect_TX1_DMAStart(); + } + } + break; + case 1: + { + if (MD_ConnectTX_Len) + { + MD_Connect_RS485_Tx2EN; + MD_Connect_TX2_DMALenSet(MD_ConnectTX_Len); + MD_Connect_TX2_DMAStart(); + } + } + break; + case 2: + { + if (MD_ConnectTX_Len) + { + MD_Connect_RS485_Tx3EN; + MD_Connect_TX3_DMALenSet(MD_ConnectTX_Len); + MD_Connect_TX3_DMAStart(); + } + } + break; + case 3: + { + if (MD_ConnectTX_Len) + { + MD_Connect_RS485_Tx4EN; + MD_Connect_TX4_DMALenSet(MD_ConnectTX_Len); + MD_Connect_TX4_DMAStart(); + } + } + break; + } + } +} +/*F***************************************************************************** + * NAME: KeyBoardTask + * PURMDE: KeyBoardͨѶ + * PARAMS: + * return: + *******************************************************************************/ +volatile u8 KBAddr_Init[4] = {0, 0, 0, 0}; +volatile u32 MD_RX_RNGData[4] = {0, 0, 0, 0}; +void MD_ConnectRXTask(void) +{ + volatile u16 i = 0, j = 0, Port = 0, Temp = 0, DeviceNumber = 0, DeviceType = 0, DeviceDataLen = 0, DeviceNoDataLen = 0, DevicePortLen = 0; + volatile u64 TempBCD = 0, Tempu64 = 0; + volatile u8 MD_ConnectRX_Port = 0, POSType = 0, RXBuild_Port = 0, WhiteList_Num = 0; + volatile u16 MD_ConnectRX_Len = 0; // + volatile u8 MD_ConnectRX_pGun = 0; // ַǹ + volatile u8 MD_ConnectRX_pGun_Father = 0; // ǹЭ鸸豸 + volatile u8 MD_ConnectRX_pGun_SonDeviceBusy = 0; // ǿЭʶ豸ǹ߼ + volatile u16 MD_ConnectRX_CMD = 0, MD_ConnectRX_CMDType = 0; // + volatile GunState_TypeDef GunState; + u8 MD_ConnectRX_Check = 0; // У + u8 Buff[50]; + u8 Temp8 = 0; + u8 Encrypt_Flag1 = 0; + u8 Encrypt_Flag2 = 0; + u32 Temp32 = 0; + u16 Temp16 = 0; + volatile u16 Offset = 0; + volatile u32 CRC_temp = 0; + volatile float TempF = 0; + volatile u8 Tank_Num; + u8 Data_201[7] = "i20100"; + u8 Data_20E[7] = "i20E00"; + + while (TXHData.MBCountRXIDLETimer[0].Flag + TXHData.MBCountRXIDLETimer[1].Flag + TXHData.MBCountRXIDLETimer[2].Flag + TXHData.MBCountRXIDLETimer[3].Flag) + { + if (TXHData.MBCountRXIDLETimer[0].Flag) + { + TXHData.MBCountRXIDLETimer[0].Flag = 0; + if (TXHData.MD_Rec_NummberB[0] == 1000 - DMA1_Stream5->NDTR) + { + TXHData.MD_Rec_Nummber[0] = 1000 - DMA1_Stream5->NDTR; + MD_Connect_RX1_DMAStop(); // رDMA + DMA_ClearFlag(DMA1_Stream5, DMA_IT_TCIF5); + MD_ConnectRX1Task_Flag = 1; // ʹGas + MD_Connect_RX1_DMALenSet(1000); // ýܳ + MD_Connect_RX1_DMAStart(); // DMA + } + } + if (TXHData.MBCountRXIDLETimer[1].Flag) + { + TXHData.MBCountRXIDLETimer[1].Flag = 0; + if (TXHData.MD_Rec_NummberB[1] == 1000 - DMA1_Stream2->NDTR) + { + TXHData.MD_Rec_Nummber[1] = 1000 - DMA1_Stream2->NDTR; + MD_Connect_RX2_DMAStop(); // رDMA + DMA_ClearFlag(DMA1_Stream2, DMA_IT_TCIF2); + MD_ConnectRX2Task_Flag = 1; // ʹGas + MD_Connect_RX2_DMALenSet(1000); // ýܳ + MD_Connect_RX2_DMAStart(); // DMA + } + } + if (TXHData.MBCountRXIDLETimer[2].Flag) + { + TXHData.MBCountRXIDLETimer[2].Flag = 0; + if (TXHData.MD_Rec_NummberB[2] == 1000 - DMA1_Stream0->NDTR) + { + TXHData.MD_Rec_Nummber[2] = 1000 - DMA1_Stream0->NDTR; + MD_Connect_RX3_DMAStop(); // رDMA + DMA_ClearFlag(DMA1_Stream0, DMA_IT_TCIF0); + MD_ConnectRX3Task_Flag = 1; // ʹGas + MD_Connect_RX3_DMALenSet(1000); // ýܳ + MD_Connect_RX3_DMAStart(); // DMA + } + } + if (TXHData.MBCountRXIDLETimer[3].Flag) + { + TXHData.MBCountRXIDLETimer[3].Flag = 0; + if (TXHData.MD_Rec_NummberB[3] == 1000 - DMA1_Stream1->NDTR) + { + TXHData.MD_Rec_Nummber[3] = 1000 - DMA1_Stream1->NDTR; + MD_Connect_RX4_DMAStop(); // رDMA + DMA_ClearFlag(DMA1_Stream1, DMA_IT_TCIF1); + MD_ConnectRX4Task_Flag = 1; // ʹGas + MD_Connect_RX4_DMALenSet(1000); // ýܳ + MD_Connect_RX4_DMAStart(); // DMA + } + } + } + while (MD_ConnectRX1Task_Flag + MD_ConnectRX2Task_Flag + MD_ConnectRX3Task_Flag + MD_ConnectRX4Task_Flag) + { + if (MD_ConnectRX1Task_Flag) + { + MD_ConnectRX1Task_Flag = 0; + MD_ConnectRX_Port = 0; + } + else if (MD_ConnectRX2Task_Flag) + { + MD_ConnectRX2Task_Flag = 0; + MD_ConnectRX_Port = 1; + } + else if (MD_ConnectRX3Task_Flag) + { + MD_ConnectRX3Task_Flag = 0; + MD_ConnectRX_Port = 2; + } + else if (MD_ConnectRX4Task_Flag) + { + MD_ConnectRX4Task_Flag = 0; + MD_ConnectRX_Port = 3; + } + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][0] == 0xC1 && MD_Connect_RX_Buff[MD_ConnectRX_Port][2] == 0x08) // LORAûظ + { + TXHData.MD_LORA_Slave_Flag = 1; + switch (MD_ConnectRX_Port) + { + case 0: + MD_Connect_LORA_IdleMode1; + break; + case 1: + MD_Connect_LORA_IdleMode2; + break; + case 2: + MD_Connect_LORA_IdleMode3; + break; + case 3: + MD_Connect_LORA_IdleMode4; + break; + } + BEEP_OFF; + } + else if (TXHData.MDConnectState[MD_ConnectRX_Port].Flag.WorkMode == 1) // ģʽ + { + if (TXHData.UDisk_Flag) + Log_Task(&MD_Connect_RX_Buff[MD_ConnectRX_Port][0], TXHData.MD_Rec_Nummber[MD_ConnectRX_Port], MD_ConnectRX_Port, Info_Receive); + POSType = TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.POSType; + switch (POSType) + { + case PosBlueSky: + { + MD_ConnectRX_pGun = MD_Connect_BCDTou64(MD_Connect_RX_Buff[MD_ConnectRX_Port][1]); // ȡָ + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.DeviceNumber; DeviceNumber++) + if (MD_ConnectRX_pGun == TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunAddr) + { + MD_ConnectRX_pGun = DeviceNumber; + break; + } + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][2] & 0xf0) == 0xa0) + MD_ConnectRX_Len = MD_Connect_RX_Buff[MD_ConnectRX_Port][2] & 0x0f; // ȡ + else + MD_ConnectRX_Len = MD_Connect_RX_Buff[MD_ConnectRX_Port][2]; + if (MD_ConnectRX_Len == 0) + MD_ConnectRX_Len = 16; + MD_ConnectRX_CMD = MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len + 1]; // ȡ + Temp = MD_Connect_TXDataCheck(&MD_Connect_RX_Buff[MD_ConnectRX_Port][0], MD_ConnectRX_Len + 1); + if (Temp == MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len + 2] && MD_Connect_RX_Buff[MD_ConnectRX_Port][1] > 0) // жУλ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RSSI = MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len + 3]; + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun] = 0; + if (TXHData.POS_MonitorModel == 1) // ģʽ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + switch (MD_ConnectRX_CMD) + { + case C_MDConnectCmdReadState: // ״̬ + { + if (MD_ConnectRX_Len < 3) + MD_ConnectRX_CMD = 0; + break; + }; + break; + case C_MDConnectCmdReadFuelState: // + { + if (MD_ConnectRX_Len < 3) + MD_ConnectRX_CMD = 0; + break; + }; + break; + case C_MDConnectCmdReadPrice: // + { + if (MD_ConnectRX_Len < 3) + MD_ConnectRX_CMD = 0; + break; + }; + break; + case C_MDConnectCmdReadTotal: // + { + if (MD_ConnectRX_Len < 3) + MD_ConnectRX_CMD = 0; + break; + }; + break; + default: + MD_ConnectRX_CMD = 0; + break; + } + } + switch (MD_ConnectRX_CMD) + { + case C_MDConnectCmdReadState: // ״̬ + { + TXHData.LTGunState.State = MD_Connect_RX_Buff[MD_ConnectRX_Port][3]; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 1 - TXHData.LTGunState.Flag.GunUp; + // TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = TXHData.LTGunState.Flag.StartFlag; + if (TXHData.LTGunState.Flag.StartFlag == 0 && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 1) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.Start_Flag = 1; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x02; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadPrice; + } + else if (TXHData.LTGunState.Flag.TitleFlag == 0) // Ȩʧ»ȡȨ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectASKControlPower; + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 1 - TXHData.LTGunState.Flag.GunUp; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = TXHData.LTGunState.Flag.StartFlag; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag != TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.Start_Flag) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.Start_Flag = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 1) + { + // TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadFuelState; + // TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + if (TXHData.POS_Info.Link_Flag == 0 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number) + { + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState = 0x11; + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].MB_CMD_Next = RFID_MDConnectCmdWriteFullingInfo; + } + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadFuelState; + // TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 1; + if (TXHData.POS_Info.Link_Flag == 0 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number) + { + TXHData.MD_Port_Data[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].GunState.Flag.UpdateDisplay = 0; + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState = 0; + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].MB_CMD_Next = RFID_MDConnectCmdWriteFullingInfo; + } + } + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag != TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.GunUP_Flag) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.GunUP_Flag = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag == 0) // ǹ + { + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 0 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF == 0 && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadFuelState; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 1; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + } + else // ǹ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 0) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 1; + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 0; + } + if (TXHData.POS_Info.Link_Flag == 0 || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) // ,жһDzҪȨ + { + if (TXHData.OfflineAuthorize == 1 && (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax)) // Ȩ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdStart; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_NoCard; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + for (i = 0; i < 6; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i] = 0; + for (i = 0; i < 15; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CarLicensePlate[i] = 0; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1) + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == TXHData.MD_Port_Data[Port].GunData[DeviceNumber].GunNummber)//ҶӦRFID豸 + { + if (TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState == 3) // ǩ֤ͨ + { + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdStart; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_Card; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + } + } + } + } + } + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next == C_MDConnectCmdReadState) + { + // if(TXHData.POSCutTimer.Flag == 1) + // TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdStop; + // else + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadFuelState; + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD == C_MDConnectCmdWritePrice && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0 && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectASKControlPower; + } + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.Flag == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.Flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadPrice; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF == 0 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadPrice; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online == 1 && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag == 0 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 0 && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords == 0) + { + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].ROM_UpData_State.Flag.Update_Flag && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].ROM_UpData_State.Flag.Update_Flag == 0) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].GunVersion.VersionFindFlag) + { + for (i = 0; i < 6; i++) // жDzͬһϵ + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].GunVersion.Version[i] != TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.ROM_UpData_Version[i]) + break; + if (i == 6) + { + for (i = 6; i < 10; i++) // жϰ汾Dzͬ + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].GunVersion.Version[i] != TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.ROM_UpData_Version[i]) + break; + if (i != 10) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].ROM_UpData_State.Flag.Update_Flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdSetBaudRate; + } + } + } + } + } + } + break; + case C_MDConnectCmdReadFuelState: // + { + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.Device_Type == Display_664) + { + if (MD_ConnectRX_Len != 8) + break; + for (i = 0; i < 6; i++) + { + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i] & 0x0f) > 0x09) + break; + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i] & 0xf0) > 0x90) + break; + } + if (i < 6) + break; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.OilCNT = ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][4] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][5]); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.MoneyCNT = ((MD_Connect_RX_Buff[MD_ConnectRX_Port][6] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][7] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][8])); + } + else + { + if (MD_ConnectRX_Len != 10) + break; + for (i = 0; i < 8; i++) + { + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i] & 0x0f) > 0x09) + break; + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i] & 0xf0) > 0x90) + break; + } + if (i < 8) + break; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.OilCNT = ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 24) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][4] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][6])); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.MoneyCNT = ((MD_Connect_RX_Buff[MD_ConnectRX_Port][7] << 24) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][8] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][9] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][10])); + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x04; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadTotal; + } + else if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next == C_MDConnectCmdReadFuelState) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.Flag == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.Flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadPrice; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + } + break; + case C_MDConnectCmdStart: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][3] == 0x59) + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 1; + else + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + break; + case C_MDConnectCmdStop: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + } + break; + case C_MDConnectPauseFueling: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + } + break; + case C_MDConnectResumeFueling: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + } + break; + case C_MDConnectCmdWritePrsetSale: // Ԥý + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdStart; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + } + break; + case C_MDConnectCmdWritePrsetVolume: // Ԥ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdStart; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + } + break; + case C_MDConnectCmdReadPrice: // + { + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.Device_Type == Display_664) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price = ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][4]); + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price = ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][4] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][5]); + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x03; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadFuelState; + } + else + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadFuelState; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadTotal; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + } + } + break; + case C_MDConnectCmdWritePrice: // xie + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + } + break; + case C_MDConnectCmdReadTotal: // + { + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.Device_Type == Display_664) + { + if (MD_ConnectRX_Len != 12) + break; + for (i = 0; i < 10; i++) + { + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i] & 0x0f) > 0x09) + break; + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i] & 0xf0) > 0x90) + break; + } + if (i < 10) + break; + Tempu64 = 0; + for (i = 0; i < 5; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalLit = Tempu64; + Tempu64 = 0; + for (i = 0; i < 5; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][8 + i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalMoney = Tempu64; + } + else + { + if (MD_ConnectRX_Len != 14) + break; + for (i = 0; i < 12; i++) + { + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i] & 0x0f) > 0x09) + break; + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i] & 0xf0) > 0x90) + break; + } + if (i < 12) + break; + Tempu64 = 0; + for (i = 0; i < 6; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalLit = Tempu64; + Tempu64 = 0; + for (i = 0; i < 6; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][9 + i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalMoney = Tempu64; + } + + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + Tempu64 = MD_ConnectRX_Port * 16 + MD_ConnectRX_pGun; // ӡ洢λ + if (TXHData.POS_Info.Link_Flag == 0 // ,жһDzҪ߼¼ + || (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) // ȨģʽжһDzҪ߼¼ + || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType > NowAuthorizeType_Online) // ģжһDzҪ߼¼ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = 0; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].RTIME = TXHData.CTIME; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0; + for (i = 0; i < 6; i++) + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i] = TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i + 4]; // Ϣ10ֽڣֻȡ6 + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i] = 0; + AT45DBItemWrite(CA_PREXDATA, TXHData.PREXDATA_WaitUpNummber / 5); + FMItemWrite(CF_PREXDATA_TTC, 0); + if (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax) + TXHData.PREXDATA_WaitUpNummber++; + FMItemWrite(CF_PREXDATA_WaitUpNummber, 0); + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i]; + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 1; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i]; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + + TXHData.PrintLastRecord[Tempu64].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PrintLastRecord[Tempu64].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PrintLastRecord[Tempu64].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PrintLastRecord[Tempu64].RTIME = TXHData.CTIME; + TXHData.PrintLastRecord[Tempu64].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + + FMItemWrite(CF_PrintLastRecord, Tempu64); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 0; + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + } + break; + case C_MDConnectCmdWriteTotal: // xie + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + } + break; + case C_MDConnectCmdWritePulseCoefficient: // xie + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + } + break; + case C_MDConnectASKControlPower: // ҪȨ + { + TXHData.POSLOCK_Impower = 1; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x01; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadVersion; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD == C_MDConnectCmdWritePrice) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdWritePrice; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = 0; + } + else + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + } + break; + case C_MDConnectReturnControlPower: // Ȩ + { + TXHData.POSLOCK_Impower = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == 0x00) + // { + // TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + // TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x01; + // TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdReadState; + // } + // else if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD == C_MDConnectCmdWritePrice) + // { + // TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + // TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdWritePrice; + // TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = 0; + // } + } + break; + case C_MDConnectCmdReadVersion: // 汾 + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].GunVersion.VersionFindFlag = 1; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].GunVersion.Version[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 3]; + } + break; + case C_MDConnectCmdSetBaudRate: // ͬ + { + if (((MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][4] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][5]) == BaudRateSync) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FrameNow = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = C_MDConnectCmdSendFrame; + MD_Connect_USART_Configuration(MD_ConnectRX_Port, BaudRateSync, USART_WordLength_9b, TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.Parity_Even); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].ROM_UpData_State.Flag.BaudRateSync_Flag = 1; + } + } + break; + case C_MDConnectCmdSendFrame: // ֡ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FrameNow = (MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][4]; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FrameNow >= TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.ROM_UpData.FrameTop) + { + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun] = 6; // ˣϿ + } + } + break; + } + } + } + break; + case PosLY: // TXHData.LoopGunNextFlag + { + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][0] == 0x04) + MD_ConnectRX_CMD = 0x04; + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][0] == 0x15) + MD_ConnectRX_CMD = 0x15; + if (((MD_Connect_RX_Buff[MD_ConnectRX_Port][0] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][1]) == 0x1030) + MD_ConnectRX_CMD = LY_MDConnectCmdACK0; + else if (((MD_Connect_RX_Buff[MD_ConnectRX_Port][0] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][1]) == 0x1031) + MD_ConnectRX_CMD = LY_MDConnectCmdACK1; + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][0] == 0x02) + { + // BCC_CheckSum(&MD_Connect_RX_Buff[MD_ConnectRX_Port][1] , 5);//У + MD_ConnectRX_CMD = (MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][4]; + } + MD_ConnectRX_pGun = TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunNow; + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun] = 0; + if (TXHData.POS_MonitorModel == 1) // ģʽ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + } + switch (MD_ConnectRX_CMD) + { + case LY_MDConnectCmdACK0: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x05) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x06; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdHandshake; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x0a) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x0b; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdReadTotal; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x0f) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x10; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdReadState; + } + else + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next == LY_MDConnectCmdWritePrice) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD != LY_MDConnectCmdPoll) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdPoll; + } + } + } + break; + case LY_MDConnectCmdACK1: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x08) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x08; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x0b) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x0c; + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next == LY_MDConnectCmdAuthorize) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + } + break; + case 0x3030: // 1 + { + for (i = 0; i < 6; i++) + Buff[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i]; + TempBCD = do_crc(Buff, 6); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYHandshakeCRC = ((TempBCD >> 8) + TempBCD) % 256; + // TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYHandshakeCRC = Tempu64 >> 4; + + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x04; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdACK1; + } + break; + case 0x04: // + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < 0x04) // ȴ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake++; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == 0x04) // ûյ֣ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x0a; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == 0x04) // յ֣ʼ֤ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x05; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x08) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x09; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdACK1; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x09) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x0a; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x0d) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x0e; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x0e) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x0f; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x10) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x11; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdPoll; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 1) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0) + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 1; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD != LY_MDConnectCmdPoll) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD != LY_MDConnectCmdReadState) + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + else + { + if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.Flag == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.Flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdReadTotal; + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + } + } + } + } + break; + case 0x15: // ʧ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + break; + case 0x3630: // 2 + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x08) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x09; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdACK1; + } + } + break; + case 0x3632: // Ϣ + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x08) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdACK1; + } + } + break; + case 0x3631: // ״̬ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdACK1; + // if(TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.State != TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.State) + { + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x30 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunState == 0x31) + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunState == 0x33) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.TimerCountMax = 1000 * 5; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdReadTotal; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 0; + } + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x31 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 1; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 0; + if (TXHData.POS_Info.Link_Flag == 0 || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) // ,жһDzҪȨ + { + if (TXHData.OfflineAuthorize == 1 && (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax)) // Ȩ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == 0) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_NoCard; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].PresetValue = 0x90000000; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].PresteType = Preset_Sale; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdAuthorize; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1) + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == TXHData.MD_Port_Data[Port].GunData[DeviceNumber].GunNummber)//ҶӦRFID豸 + { + if (TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState == 3) // ǩ֤ͨ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_Card; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].PresetValue = 0x90000000; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].PresteType = Preset_Sale; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdAuthorize; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + } + } + } + } + } + } + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x33) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0) + { + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdReadState; + } + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x34) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF = 1;//ӸʱжǷɽ׼¼ + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.TimerCountMax = 1000*5; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdReadTotal; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + } + Tempu64 = 0; + for (i = 0; i < 6; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 6] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.OilCNT = Tempu64; + Tempu64 = 0; + for (i = 0; i < 4; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 13] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price = Tempu64; + Tempu64 = 0; + for (i = 0; i < 6; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 17] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.MoneyCNT = Tempu64; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunState = MD_Connect_RX_Buff[MD_ConnectRX_Port][5]; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.State = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.State; + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top && (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake > 0x0f)) // ȴݣֹΪ֮ǰ豸״̬ʶ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdACK1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x30) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 0; + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 1 || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 1) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 1; + Tempu64 = MD_ConnectRX_Port * 16 + MD_ConnectRX_pGun; + + TXHData.PrintLastRecord[Tempu64].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PrintLastRecord[Tempu64].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PrintLastRecord[Tempu64].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PrintLastRecord[Tempu64].RTIME = TXHData.CTIME; + TXHData.PrintLastRecord[Tempu64].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + FMItemWrite(CF_PrintLastRecord, Tempu64); + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + } + } + break; + case 0x3635: // ۼ + { + Tempu64 = 0; + for (i = 0; i < 10; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 11] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalLit = Tempu64; + Tempu64 = 0; + for (i = 0; i < 10; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 21] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalMoney = Tempu64; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + Tempu64 = MD_ConnectRX_Port * 16 + MD_ConnectRX_pGun; + if (TXHData.POS_Info.Link_Flag == 0 // ,жһDzҪ߼¼ + || (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) // ȨģʽжһDzҪ߼¼ + || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType > NowAuthorizeType_Online) // ģжһDzҪ߼¼ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = 0; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].RTIME = TXHData.CTIME; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0; + for (i = 0; i < 6; i++) + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i] = TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i + 4]; // Ϣ10ֽڣֻȡ6 + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i] = 0; + AT45DBItemWrite(CA_PREXDATA, TXHData.PREXDATA_WaitUpNummber / 5); + FMItemWrite(CF_PREXDATA_TTC, 0); + if (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax) + TXHData.PREXDATA_WaitUpNummber++; + FMItemWrite(CF_PREXDATA_WaitUpNummber, 0); + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 0; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i]; + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 1; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.TimerCount = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + + TXHData.PrintLastRecord[Tempu64].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PrintLastRecord[Tempu64].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PrintLastRecord[Tempu64].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PrintLastRecord[Tempu64].RTIME = TXHData.CTIME; + TXHData.PrintLastRecord[Tempu64].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + FMItemWrite(CF_PrintLastRecord, Tempu64); + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x0c) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x0d; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdACK1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdReadState; + } + break; + } + } + break; + case PosJP: + { + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][0] == 0x04) + MD_ConnectRX_CMD = 0x04; + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][0] == 0x15) + MD_ConnectRX_CMD = 0x15; + if (((MD_Connect_RX_Buff[MD_ConnectRX_Port][0] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][1]) == 0x1030) + MD_ConnectRX_CMD = LY_MDConnectCmdACK0; + else if (((MD_Connect_RX_Buff[MD_ConnectRX_Port][0] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][1]) == 0x1031) + MD_ConnectRX_CMD = LY_MDConnectCmdACK1; + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][0] == 0x02) + { + MD_ConnectRX_CMD = (MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][4]; + } + MD_ConnectRX_pGun = TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunNow; + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun] = 0; + if (TXHData.POS_MonitorModel == 1) // ģʽ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + } + switch (MD_ConnectRX_CMD) + { + case 0x3630: // + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == 0x00) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x01; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdACK1; + } + } + break; + case LY_MDConnectCmdACK0: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x02) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x03; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdReadTotal; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x05) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x06; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdReadState; + } + else + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next == LY_MDConnectCmdWritePrice) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD != LY_MDConnectCmdPoll) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdPoll; + } + } + } + break; + case LY_MDConnectCmdACK1: // + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next == LY_MDConnectCmdAuthorize) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + } + break; + case 0x04: // + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x01) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x02; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x04) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x05; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x06) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD != LY_MDConnectCmdPoll) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD != LY_MDConnectCmdReadState) + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + } + } + } + break; + case 0x15: // ʧ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + break; + case 0x3641: // ״̬ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdACK1; + // if(TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.State != TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.State) + { + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x30 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 0; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunState == 0x31) + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdReadTotal; + } + } + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x31 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 1; + } + // else + // { + // TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + // TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 0; + // } + + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 0; + if (TXHData.POS_Info.Link_Flag == 0 || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) // ,жһDzҪȨ + { + if (TXHData.OfflineAuthorize == 1 && (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax)) // Ȩ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == 0) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_NoCard; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].PresetValue = 0x90000000; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].PresteType = Preset_Sale; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdAuthorize; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1) + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == TXHData.MD_Port_Data[Port].GunData[DeviceNumber].GunNummber)//ҶӦRFID豸 + { + if (TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState == 3) // ǩ֤ͨ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_Card; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].PresetValue = 0x90000000; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].PresteType = Preset_Sale; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdAuthorize; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + } + } + } + } + } + } + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x33) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0) + { + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdReadState; + } + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x34) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdReadTotal; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + } + + // else + // { + // TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 0; + // TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 0; + // } + Tempu64 = 0; + for (i = 0; i < 8; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 6] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.OilCNT = Tempu64; + Tempu64 = 0; + for (i = 0; i < 6; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 15] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price = Tempu64; + Tempu64 = 0; + for (i = 0; i < 8; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 21] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.MoneyCNT = Tempu64; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunState = MD_Connect_RX_Buff[MD_ConnectRX_Port][5]; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.State = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.State; + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdACK1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 1) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 1; + Tempu64 = MD_ConnectRX_Port * 16 + MD_ConnectRX_pGun; + + TXHData.PrintLastRecord[Tempu64].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PrintLastRecord[Tempu64].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PrintLastRecord[Tempu64].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PrintLastRecord[Tempu64].RTIME = TXHData.CTIME; + TXHData.PrintLastRecord[Tempu64].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + FMItemWrite(CF_PrintLastRecord, Tempu64); + } + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + } + } + break; + case 0x3642: // ۼ + { + Tempu64 = 0; + for (i = 0; i < 12; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 11] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalLit = Tempu64; + Tempu64 = 0; + for (i = 0; i < 12; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 23] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalMoney = Tempu64; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x03) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x04; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + Tempu64 = MD_ConnectRX_Port * 16 + MD_ConnectRX_pGun; // ӡ洢λ + if (TXHData.POS_Info.Link_Flag == 0 // ,жһDzҪ߼¼ + || (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) // ȨģʽжһDzҪ߼¼ + || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType > NowAuthorizeType_Online) // ģжһDzҪ߼¼ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = 0; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].RTIME = TXHData.CTIME; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0; + for (i = 0; i < 6; i++) + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i] = TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i + 4]; // Ϣ10ֽڣֻȡ6 + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i] = 0; + AT45DBItemWrite(CA_PREXDATA, TXHData.PREXDATA_WaitUpNummber / 5); + FMItemWrite(CF_PREXDATA_TTC, 0); + if (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax) + TXHData.PREXDATA_WaitUpNummber++; + FMItemWrite(CF_PREXDATA_WaitUpNummber, 0); + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 0; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i]; + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 1; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + + TXHData.PrintLastRecord[Tempu64].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PrintLastRecord[Tempu64].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PrintLastRecord[Tempu64].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PrintLastRecord[Tempu64].RTIME = TXHData.CTIME; + TXHData.PrintLastRecord[Tempu64].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + FMItemWrite(CF_PrintLastRecord, Tempu64); + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LY_MDConnectCmdACK1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = LY_MDConnectCmdReadState; + } + break; + } + } + break; + case PosDart: + { + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun] = 0; + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][1] == 0x70 && MD_Connect_RX_Buff[MD_ConnectRX_Port][2] == 0xFA) + MD_ConnectRX_CMD = DART_MDConnectCmdPoll; + else if (((MD_Connect_RX_Buff[MD_ConnectRX_Port][1] & 0xF0) == 0xC0) && (MD_Connect_RX_Buff[MD_ConnectRX_Port][2] == 0xFA)) + { + MD_ConnectRX_CMD = DART_MDConnectCmdACK; + } + else if (((MD_Connect_RX_Buff[MD_ConnectRX_Port][0] & 0xF0) == 0x50) && ((MD_Connect_RX_Buff[MD_ConnectRX_Port][1] & 0xF0) == 0x30)) + { + MD_ConnectRX_CMD = MD_Connect_RX_Buff[MD_ConnectRX_Port][2]; + } + + MD_ConnectRX_pGun = TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunNow; + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun] = 0; + if (TXHData.POS_MonitorModel == 1) // ģʽ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + } + switch (MD_ConnectRX_CMD) + { + case DART_MDConnectCmdPoll: // ѯ + { + } + break; + case DART_MDConnectCmdACK: // + { + } + break; + case 0x01: // CD1 + { + switch (MD_Connect_RX_Buff[MD_ConnectRX_Port][4]) + { + case 0x01: // + { + } + break; + case 0x02: // Ȩ + { + } + break; + case 0x03: // ʵʱ + { + } + break; + case 0x05: // λ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = DART_MDConnectCmdACK; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = DART_MDConnectCmdReadState; + } + } + break; + } + } + break; + case 0x03: + { + TXHData.DartGunState.State = MD_Connect_RX_Buff[MD_ConnectRX_Port][7]; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = TXHData.DartGunState.Flag.State; + } + break; + case 0x65: // CD101 + { + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][4] & 0xf0) == 0) + MD_ConnectRX_CMD = DART_MDConnectCmdReadVTotal; + else + MD_ConnectRX_CMD = DART_MDConnectCmdReadPTotal; + // MD_ConnectRX_pGun_Sun = MD_Connect_RX_Buff[MD_ConnectRX_Port][4] & 0x0f; + for (i = 0; i < TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.DeviceNumber; i++) + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][0] - 0x50) == TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[i].GunAddr) + break; + // MD_ConnectRX_pGun = i + MD_ConnectRX_pGun_Sun; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 2; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = DART_MDConnectCmdReadPTotal; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 2; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = DART_MDConnectCmdReadPTotal; + } + } + break; + } + } + break; + case PosYWY: + { + switch (TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.Device_Type) + { + case YWY_Bluesky: + { + TempBCD = CheckSum(&MD_Connect_RX_Buff[MD_ConnectRX_Port][1], TXHData.MD_Rec_Nummber[MD_ConnectRX_Port] - 6); + Tempu64 = StrToInt(&MD_Connect_RX_Buff[MD_ConnectRX_Port][TXHData.MD_Rec_Nummber[MD_ConnectRX_Port] - 5], 4); + if (Tempu64 == TempBCD) + { + TXHData.MBCountCutNum[MD_ConnectRX_Port][0] = 0; + MD_ConnectRX_CMD = MD_Connect_RX_Buff[MD_ConnectRX_Port][4]; + switch (MD_ConnectRX_CMD) + { + case YWY_MDConnectCmdReadData: + { + TXHData.TankNumTop = Tempu64 = (TXHData.MD_Rec_Nummber[MD_ConnectRX_Port] - 24) / 65; + for (i = 0; i < Tempu64; i++) + { + if(MD_Connect_RX_Buff[MD_ConnectRX_Port][23 + i * 65] == 0) + TXHData.TankState[MD_ConnectRX_Port][i].State = MD_Connect_RX_Buff[MD_ConnectRX_Port][20 + i * 65]; + + TempF = StrToFloat(&MD_Connect_RX_Buff[MD_ConnectRX_Port][26 + i * 65], 8); + if(MD_Connect_RX_Buff[MD_ConnectRX_Port][26 + i * 65] != 0x3F) + TXHData.TankData[MD_ConnectRX_Port][i].Data.OV = TempF; + else + TXHData.TankData[MD_ConnectRX_Port][i].Data.OV = 0; + TempF = StrToFloat(&MD_Connect_RX_Buff[MD_ConnectRX_Port][50 + i * 65], 8); + if(MD_Connect_RX_Buff[MD_ConnectRX_Port][50 + i * 65] != 0x3F) + TXHData.TankData[MD_ConnectRX_Port][i].Data.OH = TempF; + else + TXHData.TankData[MD_ConnectRX_Port][i].Data.OH = 0; + TempF = StrToFloat(&MD_Connect_RX_Buff[MD_ConnectRX_Port][58 + i * 65], 8); + if(MD_Connect_RX_Buff[MD_ConnectRX_Port][58 + i * 65] != 0x3F) + TXHData.TankData[MD_ConnectRX_Port][i].Data.WH = TempF; + else + TXHData.TankData[MD_ConnectRX_Port][i].Data.WH = 0; + TempF = StrToFloat(&MD_Connect_RX_Buff[MD_ConnectRX_Port][66 + i * 65], 8); + if(MD_Connect_RX_Buff[MD_ConnectRX_Port][66 + i * 65] != 0x3F) + TXHData.TankData[MD_ConnectRX_Port][i].Data.TH = TempF; + else + TXHData.TankData[MD_ConnectRX_Port][i].Data.TH = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[i].GunState.Flag.Online = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RSSI = MD_Connect_RX_Buff[MD_ConnectRX_Port][TXHData.MD_Rec_Nummber[MD_ConnectRX_Port] - 1]; + } + } + break; + case YWY_MDConnectCmdWriteApacity: + { + } + break; + } + } + } + break; + case YWY_Probe_KY: + { + Tempu64 = (MD_Connect_RX_Buff[MD_ConnectRX_Port][22] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][21]; + TempBCD = CRC_Check(&MD_Connect_RX_Buff[MD_ConnectRX_Port][0], 21); + if (Tempu64 == TempBCD) + { + MD_ConnectRX_pGun = MD_Connect_RX_Buff[MD_ConnectRX_Port][0] - 1; + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun] = 0; + TXHData.TankState[MD_ConnectRX_Port][MD_ConnectRX_pGun].State = 0; + TXHData.TankData[MD_ConnectRX_Port][MD_ConnectRX_pGun].Data.OV = 0; + TXHData.TankData[MD_ConnectRX_Port][MD_ConnectRX_pGun].Data.OH = (float)((MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][4]) + (float)((MD_Connect_RX_Buff[MD_ConnectRX_Port][5] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][6]) / 65535; + TXHData.TankData[MD_ConnectRX_Port][MD_ConnectRX_pGun].Data.WH = (float)((MD_Connect_RX_Buff[MD_ConnectRX_Port][7] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][8]) + (float)((MD_Connect_RX_Buff[MD_ConnectRX_Port][9] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][10]) / 65535; + ; + if ((MD_Connect_RX_Buff[MD_ConnectRX_Port][11] & 0x80) == 0) + TXHData.TankData[MD_ConnectRX_Port][MD_ConnectRX_pGun].Data.TH = (float)((MD_Connect_RX_Buff[MD_ConnectRX_Port][11] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][12]) / 16; + else + TXHData.TankData[MD_ConnectRX_Port][MD_ConnectRX_pGun].Data.TH = 0.0 - ((float)((0 - ((MD_Connect_RX_Buff[MD_ConnectRX_Port][11] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][12])) & 0xffff) / 16.0); + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RSSI = MD_Connect_RX_Buff[MD_ConnectRX_Port][23]; + TXHData.TankNumTop = TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.DeviceNumber; + } + } + break; + case YWY_Pressure: + { + Tempu64 = (MD_Connect_RX_Buff[MD_ConnectRX_Port][8] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][7]; + TempBCD = CRC_Check(&MD_Connect_RX_Buff[MD_ConnectRX_Port][0], 7); + if (Tempu64 == TempBCD) + { + MD_ConnectRX_pGun = MD_Connect_RX_Buff[MD_ConnectRX_Port][0] - 1; + TXHData.MBCountCutNum[MD_ConnectRX_Port][0] = 0; + TXHData.TankState[MD_ConnectRX_Port][MD_ConnectRX_pGun].State = 0; + TXHData.TankData[MD_ConnectRX_Port][MD_ConnectRX_pGun].Data.OV = (float)((MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][4]) / (pow(10, MD_Connect_RX_Buff[MD_ConnectRX_Port][6])); + TXHData.TankData[MD_ConnectRX_Port][MD_ConnectRX_pGun].Data.OH = 0; + TXHData.TankData[MD_ConnectRX_Port][MD_ConnectRX_pGun].Data.WH = 0; + TXHData.TankData[MD_ConnectRX_Port][MD_ConnectRX_pGun].Data.TH = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RSSI = MD_Connect_RX_Buff[MD_ConnectRX_Port][9]; + TXHData.TankNumTop = TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.DeviceNumber; + } + } + break; + } + } + break; + case PosRFID: + { + MD_ConnectRX_Len = (MD_Connect_RX_Buff[MD_ConnectRX_Port][2] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][3]; + Tempu64 = (MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len + 1]; + TempBCD = CRC_Check(&MD_Connect_RX_Buff[MD_ConnectRX_Port][0], MD_ConnectRX_Len); + if (Tempu64 == TempBCD) + { + MD_ConnectRX_pGun = MD_Connect_RX_Buff[MD_ConnectRX_Port][1]; // ȡַָ + for (i = 0; i < TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.DeviceNumber; i++) + if (MD_ConnectRX_pGun == TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[i].GunAddr) + { + MD_ConnectRX_pGun = i; // ȡָ + break; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + MD_ConnectRX_CMD = MD_Connect_RX_Buff[MD_ConnectRX_Port][4]; + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun] = 0; + switch (MD_ConnectRX_CMD) + { + case RFID_MDConnectCmdAllData: // ״̬ + { + Offset = 6; + for (DeviceNumber = 0; DeviceNumber < MD_Connect_RX_Buff[MD_ConnectRX_Port][5]; DeviceNumber++) + { + Offset++; + MD_ConnectRX_CMD = MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset]; + Offset++; + switch (MD_ConnectRX_CMD) + { + case RFID_MDConnectCmdReadData: // ״̬ + { + MD_ConnectRX_Len = MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset]; + Offset++; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun + DeviceNumber].ROM_UpData_State.Flag.Update_Flag && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].ROM_UpData_State.Flag.Update_Flag == 0) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].GunVersion.VersionFindFlag) + { + for (i = 0; i < 4; i++) // жDzͬһϵ + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].GunVersion.Version[i] != TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.ROM_UpData_Version[i]) + break; + if (i == 4) + { + for (i = 4; i < 10; i++) // жϰ汾Dzͬ + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].GunVersion.Version[i] != TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.ROM_UpData_Version[i]) + break; + if (i != 10) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].ROM_UpData_State.Flag.Update_Flag = 1; + } + } + } + } + if (MD_ConnectRX_Len == 15) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun + DeviceNumber].GunState.Flag.UpdateDisplay = 1; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].CardNumber[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset + i]; + Offset += 10; + for (i = 0; i < 2; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].CardPSWD[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset + i]; + Offset += 2; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].Mileage = (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset + 1] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset + 2]; + Offset += 3; + if (TXHData.POS_Info.Link_Flag == 0) // + { + for (i = 0; i < 10; i++) + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].CardNumber[i] != 0) + break; + if (i == 10) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].RFIDState = 0x40; + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].RFIDState == 0) + { + for (WhiteList_Num = 0; WhiteList_Num < TXHData.WhiteList.WhiteListTop; WhiteList_Num++) // Ұ + { + for (Temp = 0; Temp < 6; Temp++) + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].CardNumber[Temp + 4] != TXHData.WhiteList.CardNum[WhiteList_Num][Temp]) + break; + if (Temp == 6) // zڰ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].RFIDState = 3; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun + DeviceNumber].GunState.Flag.UpdateDisplay = 0; + for (i = 0; i < 15; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].RFIDUserName[i] = 0x20; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].CarLicensePlate[i] = 0x20; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].BalanceDecimal = 0; + for (i = 0; i < 5; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].Balance[i] = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].Mileage; + break; + } + } + if (WhiteList_Num == TXHData.WhiteList.WhiteListTop) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].RFIDState = 0x40; + } + } + switch (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].RFIDState) + { + case 3: + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteCardInfo; + break; + case 17: + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteFullingInfo; + break; + case 0x40: + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteCardInfo; + break; + } + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun + DeviceNumber].GunState.Flag.UpdateDisplay = 0; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].ROM_UpData_State.Flag.Update_Flag) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].FrameNow = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdROMownload; + } + } + } + break; + case RFID_MDConnectCmdWriteCardInfo: // + { + switch (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].RFIDState) + { + case 0x40: + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].RFIDState = 0; + break; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdReadData; + // if(TXHData.POS_Info.Link_Flag == 0)// + } + break; + case RFID_MDConnectCmdWriteFullingInfo: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun + DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdReadData; + } + break; + } + } + } + break; + case RFID_MDConnectCmdReadData: // ״̬ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x01; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdReadVersion; + } + else + { + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].ROM_UpData_State.Flag.Update_Flag && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].ROM_UpData_State.Flag.Update_Flag == 0) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].GunVersion.VersionFindFlag) + { + for (i = 0; i < 4; i++) // жDzͬһϵ + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].GunVersion.Version[i] != TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.ROM_UpData_Version[i]) + break; + if (i == 4) + { + for (i = 4; i < 10; i++) // жϰ汾Dzͬ + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].GunVersion.Version[i] != TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.ROM_UpData_Version[i]) + break; + if (i != 10) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].ROM_UpData_State.Flag.Update_Flag = 1; + } + } + } + } + } + if (MD_ConnectRX_Len == 17) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 5]; + for (i = 0; i < 2; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardPSWD[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 15]; + } + else if (MD_ConnectRX_Len == 20) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 5]; + for (i = 0; i < 2; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardPSWD[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 15]; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Mileage = (MD_Connect_RX_Buff[MD_ConnectRX_Port][17] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][18] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][19]; + if (TXHData.POS_Info.Link_Flag == 0) // + { + for (i = 0; i < 10; i++) + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i] != 0) + break; + if (i == 10) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RFIDState = 0x40; + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RFIDState == 0) + { + for (WhiteList_Num = 0; WhiteList_Num < TXHData.WhiteList.WhiteListTop; WhiteList_Num++) // Ұ + { + for (Temp = 0; Temp < 6; Temp++) + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[Temp + 4] != TXHData.WhiteList.CardNum[WhiteList_Num][Temp]) + break; + if (Temp == 6) // zڰ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RFIDState = 3; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 0; + for (i = 0; i < 15; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RFIDUserName[i] = 0x20; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CarLicensePlate[i] = 0x20; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].BalanceDecimal = 0; + for (i = 0; i < 5; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Balance[i] = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Mileage; + break; + } + } + if (WhiteList_Num == TXHData.WhiteList.WhiteListTop) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RFIDState = 0x40; + } + } + switch (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RFIDState) + { + case 3: + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdWriteCardInfo; + break; + case 17: + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdWriteFullingInfo; + break; + case 0x40: + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdWriteCardInfo; + break; + } + } + else if (MD_ConnectRX_Len == 6) // ״̬ + { + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 1) // ǩʧ + { + zhtningzhuangtai = 3; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdLossACK; + if (TXHData.MD_Port_Data[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].GunState.Flag.Start_Flag) + { + switch (TXHData.MD_Port_Data[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].PortData.POSType) + { + case PosBlueSky: + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].MB_CMD_Next = C_MDConnectPauseFueling; + break; + case PosBlueSkyPlus: + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].MB_CMD_Next = LTP_GunCMDSuspend; + break; + } + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].pGunCapture = TXHData.MD_Port_Data[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].GunNummber; + } + } + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 2) // ǩָ + { + zhtningzhuangtai = 4; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdFindACK; + if (TXHData.MD_Port_Data[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].GunState.Flag.Start_Flag) + { + switch (TXHData.MD_Port_Data[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].PortData.POSType) + { + case PosBlueSky: + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].MB_CMD_Next = C_MDConnectResumeFueling; + break; + case PosBlueSkyPlus: + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].MB_CMD_Next = LTP_GunCMDContinue; + break; + } + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].pGunCapture = TXHData.MD_Port_Data[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].GunNummber; + } + } + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 0; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].ROM_UpData_State.Flag.Update_Flag) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FrameNow = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdROMownload; + } + } + } + break; + case RFID_MDConnectCmdFindACK: // + case RFID_MDConnectCmdLossACK: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdReadData; + } + break; + case RFID_MDConnectCmdWriteCardInfo: // + { + switch (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RFIDState) + { + case 0x40: + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RFIDState = 0; + break; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdReadData; + // if(TXHData.POS_Info.Link_Flag == 0)// + } + break; + case RFID_MDConnectCmdWriteFullingInfo: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdReadData; + } + break; + case RFID_MDConnectCmdWriteBindingInfo: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x03; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdReadData; + } + break; + case RFID_MDConnectCmdReadVersion: // 汾 + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x02; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdWriteBindingInfo; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].GunVersion.VersionFindFlag = 1; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].GunVersion.Version[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 5]; + if (MD_ConnectRX_Len == 21) + { + // TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].SonDevice.SonNumber = MD_Connect_RX_Buff[MD_ConnectRX_Port][15]; + // for(i = 0;i < 4;i ++) + // TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].SonDevice.SonAddress[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][16+i]; + } + } + break; + case RFID_MDConnectCmdROMownload: // + { + // TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdReadData; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FrameNow = (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][6]; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FrameNow >= TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.ROM_UpData.FrameTop) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = RFID_MDConnectCmdReadData; + // TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].ROM_UpData_State.Flag.Update_Flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].ROM_UpData_State.Flag.Update_Flag = 0; + // FMItemWrite(CF_MD_Port_Data,MD_ConnectRX_Port); + } + } + break; + } + } + } + break; + case PosYGao: + { + MD_ConnectRX_pGun = MD_Connect_RX_Buff[MD_ConnectRX_Port][4]; // ȡָ + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.DeviceNumber; DeviceNumber++) + { + if (MD_ConnectRX_pGun == TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunAddr) + { + MD_ConnectRX_pGun = DeviceNumber; + break; + } + } + MD_ConnectRX_CMD = MD_Connect_RX_Buff[MD_ConnectRX_Port][3]; // ȡ + switch (MD_ConnectRX_CMD) + { + case YG_MDConnectCmdWritePrset: + MD_ConnectRX_Len = 7; + break; + case YG_MDConnectCmdWritePrice: + MD_ConnectRX_Len = 7; + break; + case YG_MDConnectCmdStop: + MD_ConnectRX_Len = 6; + break; + case YG_MDConnectCmdStart: + MD_ConnectRX_Len = 6; + break; + case YG_MDConnectControlMode: + MD_ConnectRX_Len = 6; + break; + case YG_MDConnectCmdReadTotal: + MD_ConnectRX_Len = 18; + break; + case YG_MDConnectCmdRemovePrset: + MD_ConnectRX_Len = 7; + break; + case YG_MDConnectCmdReadVersion: + MD_ConnectRX_Len = 9; + break; + case YG_MDConnectCmdUnLock: + MD_ConnectRX_Len = 6; + break; + case YG_MDConnectCmdLock: + MD_ConnectRX_Len = 6; + break; + case YG_MDConnectCmdReadFuelVolumeState: + MD_ConnectRX_Len = 11; + break; + case YG_MDConnectCmdReadFuelSaleState: + MD_ConnectRX_Len = 11; + break; + case YG_MDConnectCmdReadFuelRecord: + MD_ConnectRX_Len = 42; + break; + } + Temp = BCC_CheckSum(&MD_Connect_RX_Buff[MD_ConnectRX_Port][3], MD_ConnectRX_Len - 4); + if (Temp == MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len - 1] && MD_Connect_RX_Buff[MD_ConnectRX_Port][1] > 0) // жУλ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RSSI = MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len]; + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun] = 0; + if (TXHData.POS_MonitorModel == 1) // ģʽ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + } + switch (MD_ConnectRX_CMD) + { + case YG_MDConnectCmdReadFuelVolumeState: // ״̬ + case YG_MDConnectCmdReadFuelSaleState: // + { + if (MD_ConnectRX_CMD == YG_MDConnectCmdReadFuelVolumeState) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.OilCNT = ((MD_Connect_RX_Buff[MD_ConnectRX_Port][5] << 24) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][6] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][7] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][8])); + Tempu64 = MD_Connect_BCDTou64(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.OilCNT); + TempBCD = pow(10, TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.GunDec.Dec.OilCNT + TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.GunDec.Dec.Price - TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.GunDec.Dec.MoneyCNT); // Сλ + Tempu64 = (Tempu64 * MD_Connect_BCDTou64(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price) + TempBCD / 2) / TempBCD; // + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.MoneyCNT = MD_Connect_u64ToBCD(Tempu64); + } + else if (MD_ConnectRX_CMD == YG_MDConnectCmdReadFuelSaleState) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.MoneyCNT = ((MD_Connect_RX_Buff[MD_ConnectRX_Port][5] << 24) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][6] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][7] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][8])); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].YGGunState.State = MD_Connect_RX_Buff[MD_ConnectRX_Port][9]; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].YGGunState.Flag.GunUp; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].YGGunState.Flag.State == 0x01 || TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].YGGunState.Flag.State == 0x03) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + } + else + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 0; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag != TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.Start_Flag) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.Start_Flag = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0) // ͽ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 1; + } + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag != TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.GunUP_Flag) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.GunUP_Flag = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag == 0) // ǹ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + } + else // ǹ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 0) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 1; + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 0; + } + if (TXHData.POS_Info.Link_Flag == 0 || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) // ,жһDzҪȨ + { + if (TXHData.OfflineAuthorize == 1 && (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax)) // Ȩ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == 0) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_NoCard; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdStart; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + for (i = 0; i < 20; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i] = 0; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CarLicensePlate[i] = 0; + } + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1) + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == TXHData.MD_Port_Data[Port].GunData[DeviceNumber].GunNummber)//ҶӦRFID豸 + { + if (TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState == 3) // ǩ֤ͨ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_Card; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdStart; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + } + } + } + } + } + } + + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x01) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x02; + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 0x02) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x03; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadTotal; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].YGGunState.Flag.UpdateRecords == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadFuelRecord; + } + } + } + break; + case YG_MDConnectCmdStart: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadFuelVolumeState; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 1; + } + break; + case YG_MDConnectCmdStop: // ͣ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadFuelVolumeState; + } + break; + case YG_MDConnectCmdWritePrset: // Ԥý + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadFuelVolumeState; + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdStart; + } + } + break; + case YG_MDConnectCmdWritePrice: // xie + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadFuelVolumeState; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + } + break; + case YG_MDConnectCmdReadFuelRecord: // ¼ + { + Tempu64 = 0; + for (i = 0; i < 3; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][5 + i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.MoneyCNT = MD_Connect_u64ToBCD(Tempu64); + Tempu64 = 0; + for (i = 0; i < 3; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][8 + i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.OilCNT = MD_Connect_u64ToBCD(Tempu64); + Tempu64 = 0; + for (i = 0; i < 3; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][19 + i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price = Tempu64; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadTotal; + } + break; + case YG_MDConnectCmdReadTotal: // + { + Tempu64 = 0; + for (i = 0; i < 4; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][5 + i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalMoney = MD_Connect_u64ToBCD(Tempu64); + Tempu64 = 0; + for (i = 0; i < 4; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][9 + i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalLit = MD_Connect_u64ToBCD(Tempu64); + + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].YGGunState.Flag.UpdateRecords == 1) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadFuelRecordConfirm; + else + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadFuelVolumeState; + Tempu64 = MD_ConnectRX_Port * 16 + MD_ConnectRX_pGun; // ӡ洢λ + if (TXHData.POS_Info.Link_Flag == 0 // ,жһDzҪ߼¼ + || (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) // ȨģʽжһDzҪ߼¼ + || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType > NowAuthorizeType_Online) // ģжһDzҪ߼¼ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = 0; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].RTIME = TXHData.CTIME; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0; + for (i = 0; i < 6; i++) + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i] = TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i + 4]; // Ϣ10ֽڣֻȡ6 + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i] = 0; + AT45DBItemWrite(CA_PREXDATA, TXHData.PREXDATA_WaitUpNummber / 5); + FMItemWrite(CF_PREXDATA_TTC, 0); + if (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax) + TXHData.PREXDATA_WaitUpNummber++; + FMItemWrite(CF_PREXDATA_WaitUpNummber, 0); + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 0; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i]; + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 1; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i]; + } + + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + + TXHData.PrintLastRecord[Tempu64].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PrintLastRecord[Tempu64].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PrintLastRecord[Tempu64].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PrintLastRecord[Tempu64].RTIME = TXHData.CTIME; + TXHData.PrintLastRecord[Tempu64].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + FMItemWrite(CF_PrintLastRecord, Tempu64); + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadFuelVolumeState; + } + } + break; + case YG_MDConnectControlMode: // ҪȨ + { + TXHData.POSLOCK_Impower = 1; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x01; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadFuelVolumeState; + } + } + break; + case YG_MDConnectCmdLock: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadFuelVolumeState; + } + break; + case YG_MDConnectCmdUnLock: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = YG_MDConnectCmdReadFuelVolumeState; + } + break; + } + } + } + break; + + case PosHongYang: + { + MD_ConnectRX_pGun = TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunNow; // ȡָ + MD_ConnectRX_Len = MD_Connect_RX_Buff[MD_ConnectRX_Port][0]; + MD_ConnectRX_CMD = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next; // ȡ,,ܻʱѾδ͵ʱյһָҪ취 + Temp = InteiHEXCheck(&MD_Connect_RX_Buff[MD_ConnectRX_Port][0], MD_ConnectRX_Len); + if (Temp == MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len] && MD_Connect_RX_Buff[MD_ConnectRX_Port][1] > 0) // жУλ + { + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun] = 0; + switch (MD_ConnectRX_CMD) + { + case HY_MDConnectCmdReadFuelData: // + { + if (MD_ConnectRX_Len == 0x0D) + { + TXHData.HYState.State = MD_Connect_RX_Buff[MD_ConnectRX_Port][1]; + TXHData.HYSelfTestState.State = MD_Connect_RX_Buff[MD_ConnectRX_Port][11]; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake <= 3) // ݣܸϵݲ + { + if (TXHData.HYSelfTestState.State > 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake++; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake >= 4) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 1 - TXHData.HYSelfTestState.Flag.GunUp; + if (TXHData.HYState.Flag.StartFlag == 0 && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 1) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.Start_Flag = 1; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x04; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadPrice; + } + } + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 1 - TXHData.HYSelfTestState.Flag.GunUp; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = TXHData.HYState.Flag.StartFlag; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag != TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.Start_Flag) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.Start_Flag = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 1; + } + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag != TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.GunUP_Flag) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.GunUP_Flag = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag == 0) // ǹ + { + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 0 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF == 0 && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 1; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + } + else // ǹ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 0) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 1; + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 0; + } + if (TXHData.POS_Info.Link_Flag == 0 || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) + { + if (TXHData.OfflineAuthorize == 1 && (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax)) // Ȩ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == 0) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_NoCard; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdStart; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + for (i = 0; i < 20; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i] = 0; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CarLicensePlate[i] = 0; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1) + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == TXHData.MD_Port_Data[Port].GunData[DeviceNumber].GunNummber)//ҶӦRFID豸 + { + if (TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState == 3) // ǩ֤ͨ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_Card; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdStart; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + } + } + } + } + } + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD == HY_MDConnectCmdWritePrice && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0 && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectASKControlPower; + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 1) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadFuelData; + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.Flag == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.Flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadPrice; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.Device_Type == Display_664) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.MoneyCNT = MD_Connect_u64ToBCD((MD_Connect_RX_Buff[MD_ConnectRX_Port][2] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][4]); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.OilCNT = MD_Connect_u64ToBCD((MD_Connect_RX_Buff[MD_ConnectRX_Port][5] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][6] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][7])); + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.MoneyCNT = MD_Connect_u64ToBCD((MD_Connect_RX_Buff[MD_ConnectRX_Port][2] << 24) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][4] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][5])); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.OilCNT = MD_Connect_u64ToBCD((MD_Connect_RX_Buff[MD_ConnectRX_Port][6] << 24) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][7] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][8] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][9])); + } + } + } + break; + case HY_MDConnectCmdStart: // + { + if (MD_ConnectRX_Len == 3) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadFuelData; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + // TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 1; + // FMItemWrite(CF_MD_Port_Data,MD_ConnectRX_Port); + } + } + break; + case HY_MDConnectCmdStop: // ͣ + { + if (MD_ConnectRX_Len == 3) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadFuelData; + } + break; + case HY_MDConnectCmdWritePrsetSale: // Ԥý + { + if (MD_ConnectRX_Len == 3) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadFuelData; + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdStart; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + } + } + break; + case HY_MDConnectCmdWritePrsetVolume: // Ԥ + { + if (MD_ConnectRX_Len == 3) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadFuelData; + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdStart; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + } + } + break; + case HY_MDConnectCmdReadPrice: // + { + if (MD_ConnectRX_Len == 0x08) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price = MD_Connect_u64ToBCD((MD_Connect_RX_Buff[MD_ConnectRX_Port][2] << 24) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][4] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][5]); + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x05; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadTotal; + } + else + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadFuelData; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadTotal; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + } + } + } + break; + case HY_MDConnectCmdWritePrice: // xie + { + if (MD_ConnectRX_Len == 3) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].MB_CMD_Next_End = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadPrice; + } + } + break; + case HY_MDConnectCmdReadTotal: // + { + if (MD_ConnectRX_Len == 0x0F) + { + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.Device_Type == Display_664) + { + Tempu64 = 0; + for (i = 0; i < 5; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][2 + 4 - i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalLit = Tempu64; + Tempu64 = 0; + for (i = 0; i < 5; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][7 + 4 - i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalMoney = Tempu64; + } + else + { + Tempu64 = 0; + for (i = 0; i < 6; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][2 + 5 - i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalLit = Tempu64; + Tempu64 = 0; + for (i = 0; i < 6; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][8 + 5 - i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalMoney = Tempu64; + } + + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + Tempu64 = MD_ConnectRX_Port * 16 + MD_ConnectRX_pGun; // ӡ洢λ + if (TXHData.POS_Info.Link_Flag == 0 // ,жһDzҪ߼¼ + || (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) // ȨģʽжһDzҪ߼¼ + || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType > NowAuthorizeType_Online) // ģжһDzҪ߼¼ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = 0; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].RTIME = TXHData.CTIME; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0; + for (i = 0; i < 6; i++) + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i] = TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i + 4]; // Ϣ10ֽڣֻȡ6 + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i] = 0; + AT45DBItemWrite(CA_PREXDATA, TXHData.PREXDATA_WaitUpNummber / 5); + FMItemWrite(CF_PREXDATA_TTC, 0); + if (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax) + TXHData.PREXDATA_WaitUpNummber++; + FMItemWrite(CF_PREXDATA_WaitUpNummber, 0); + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 0; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i]; + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 1; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i]; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + + TXHData.PrintLastRecord[Tempu64].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PrintLastRecord[Tempu64].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PrintLastRecord[Tempu64].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PrintLastRecord[Tempu64].RTIME = TXHData.CTIME; + TXHData.PrintLastRecord[Tempu64].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + FMItemWrite(CF_PrintLastRecord, Tempu64); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 0; + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadFuelData; + } + } + break; + case HY_MDConnectASKControlPower: // ҪȨ + { + if (MD_ConnectRX_Len == 3) + { + TXHData.POSLOCK_Impower = 1; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x01; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadFuelData; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD == HY_MDConnectCmdWritePrice) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdWritePrice; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYGunNeedCMD = 0; + } + } + } + break; + case HY_MDConnectReturnControlPower: // Ȩ + { + if (MD_ConnectRX_Len == 3) + { + TXHData.POSLOCK_Impower = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = HY_MDConnectCmdReadFuelData; + } + } + break; + } + } + } + break; + + case PosSSLan: // TXHData.LoopGunNextFlag + { + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][0] == 0x04) + MD_ConnectRX_CMD = 0x04; + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][0] == 0x15) + MD_ConnectRX_CMD = 0x15; + if (((MD_Connect_RX_Buff[MD_ConnectRX_Port][0] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][1]) == 0x1030) + MD_ConnectRX_CMD = LY_MDConnectCmdACK0; + else if (((MD_Connect_RX_Buff[MD_ConnectRX_Port][0] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][1]) == 0x1031) + MD_ConnectRX_CMD = LY_MDConnectCmdACK1; + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][0] == 0x02) + { + // BCC_CheckSum(&MD_Connect_RX_Buff[MD_ConnectRX_Port][1] , 5);//У + MD_ConnectRX_CMD = (MD_Connect_RX_Buff[MD_ConnectRX_Port][3] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][4]; + } + MD_ConnectRX_pGun_Father = TXHData.MD_Port_Info[MD_ConnectRX_Port].PumpNow; // ʾ + MD_ConnectRX_pGun = TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNow; // 豸λ + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun_Father] = 0; + for (i = 0; i < TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNumber; i++) // ͬһ豸µ豸״̬ͬ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + i].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake; + } + switch (MD_ConnectRX_CMD) + { + case LY_MDConnectCmdACK0: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x05) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x06; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdHandshake; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x0a) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x0b; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdReadTotal; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x0f) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x10; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdReadState; + } + else + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next == LY_MDConnectCmdWritePrice) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNow].GunState.Flag.UpdateDisplay = 1; + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need != LY_MDConnectCmdPoll) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need = LY_MDConnectCmdPoll; + } + } + } + break; + case LY_MDConnectCmdACK1: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x08) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x08; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x0b) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x0c; + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next == LY_MDConnectCmdAuthorize) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdPoll; + } + break; + case 0x3030: // 1 + { + for (i = 0; i < 6; i++) + Buff[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i]; + TempBCD = do_crc(Buff, 6); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun_Father].LYHandshakeCRC = ((TempBCD >> 8) + TempBCD) % 256; + // TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LYHandshakeCRC = Tempu64 >> 4; + + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun_Father].Handshake = 0x04; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdACK1; + } + break; + case 0x04: // + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake < 0x04) // ȴ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake++; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake == 0x04) // ûյ֣ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x0a; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake == 0x04) // յ֣ʼ֤ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x05; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x08) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x09; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdACK1; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x09) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x0a; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x0d) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x0e; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdPoll; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x0e) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x0f; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x10) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x11; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need = LY_MDConnectCmdPoll; + for (i = 0; i < TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNumber; i++) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + i].GunState.Flag.Online = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + i].GunState.Flag.UpdateDisplay = 1; + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 1) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0) + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 1; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need != LY_MDConnectCmdPoll) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need != LY_MDConnectCmdReadState) + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + else + { + if(TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].LTDelayTimer.Flag == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].LTDelayTimer.Flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need = LY_MDConnectCmdReadTotal; + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + } + } + } + } + break; + case 0x15: // ʧ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdPoll; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + break; + case 0x3630: // 2 + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x08) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x09; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdACK1; + } + } + break; + case 0x3632: // Ϣ + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x08) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdACK1; + } + } + break; + case 0x3631: // ״̬ + { + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][23] >= 0x31) + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNow = MD_Connect_RX_Buff[MD_ConnectRX_Port][23] - 0x31; + else + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNow = 0; + DeviceNumber = TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNow; // ݵǰ豸ڵĸ豸еλã豸 + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNow < TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNumber) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdACK1; + // if(TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.State != TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.State) + { + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x30 && TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].LYGunState == 0x31) + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].Call = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].LYGunState == 0x33) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].WaitPREXDATA_flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need = LY_MDConnectCmdReadTotal; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.GunUP_Flag = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.Start_Flag = 0; + } + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x31 && TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].WaitPREXDATA_flag == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].Call = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.GunUP_Flag = 1; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.Start_Flag = 0; + if (TXHData.POS_Info.Link_Flag == 0 || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunControlState == Control_BoxAuto) // ,жһDzҪȨ + { + if (TXHData.OfflineAuthorize == 1 && (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax)) // Ȩ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].Call == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].AssociatedDevices.Number == 0) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].NowAuthorizeType = NowAuthorizeType_Offline_NoCard; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].OrderNumber = 0x00; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].FatherNum; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].PresteType = Preset_Sale; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].PresetValue = 0x90000000; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need = LY_MDConnectCmdAuthorize; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].Call == 1) + { + // if(TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == TXHData.MD_Port_Data[Port].GunData[DeviceNumber].GunNummber)//ҶӦRFID豸 + { + if (TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].AssociatedDevices.location].RFIDState == 3) // ǩ֤ͨ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].NowAuthorizeType = NowAuthorizeType_Offline_Card; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FatherNum; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].PresteType = Preset_Sale; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].PresetValue = 0x90000000; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need = LY_MDConnectCmdAuthorize; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].OrderNumber = 0x00; + } + } + } + } + } + } + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x33) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.GunUP_Flag = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.Start_Flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + for (i = 0; i < TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNumber; i++) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + i].GunState.Flag.Online = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + i].GunState.Flag.UpdateDisplay = 1; + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.Start_Flag == 0) + { + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need = LY_MDConnectCmdReadState; + } + else if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x34 && TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.Start_Flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].WaitPREXDATA_flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need = LY_MDConnectCmdReadTotal; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].LTDelayTimer.ON_OFF = 1;//ӸʱжǷɽ׼¼ + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].LTDelayTimer.TimerCountMax = 1000*5; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + for (i = 0; i < TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNumber; i++) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + i].GunState.Flag.Online = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + i].GunState.Flag.UpdateDisplay = 1; + } + } + Tempu64 = 0; + for (i = 0; i < 6; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 6] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].FData.OilCNT = Tempu64; + Tempu64 = 0; + for (i = 0; i < 4; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 13] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].Price = Tempu64; + Tempu64 = 0; + for (i = 0; i < 6; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 17] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].FData.MoneyCNT = Tempu64; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].LYGunState = MD_Connect_RX_Buff[MD_ConnectRX_Port][5]; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].fuelState_B.State = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.State; + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdACK1; + // TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + // TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + // TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdPoll; + for (i = 0; i < TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNumber; i++) + { + if (i != TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNow) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + i].GunState.State = 0; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + i].GunState.Flag.Online = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + i].GunState.Flag.UpdateDisplay = 1; + } + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][5] == 0x30) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.GunUP_Flag = 0; + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.AuthorizeState == 1 || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.Start_Flag == 1) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.AuthorizeState = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.Start_Flag = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.UpdateRecords = 1; + Tempu64 = MD_ConnectRX_Port * 16 + MD_ConnectRX_pGun; + + TXHData.PrintLastRecord[Tempu64].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].CTOTAL; + TXHData.PrintLastRecord[Tempu64].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].FData; + TXHData.PrintLastRecord[Tempu64].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunNummber; + TXHData.PrintLastRecord[Tempu64].RTIME = TXHData.CTIME; + TXHData.PrintLastRecord[Tempu64].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].Price; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].OrderNumber; + FMItemWrite(CF_PrintLastRecord, Tempu64); + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + } + } + } + break; + case 0x3635: // ۼ + { + for (Temp8 = 0; Temp8 < TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNumber; Temp8++) + { + Tempu64 = 0; + for (i = 0; i < 10; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 11 + Temp8 * 20] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + Temp8].CTOTAL.TotalLit = Tempu64; + Tempu64 = 0; + for (i = 0; i < 10; i++) + { + Tempu64 = Tempu64 << 4; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][i + 21 + Temp8 * 20] - 0x30; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + Temp8].CTOTAL.TotalMoney = Tempu64; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + } + + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top || TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].WaitPREXDATA_flag == 1) + { + //TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + DeviceNumber = TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNow + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart; // ݵǰ豸ڵĸ豸еλã豸 + Tempu64 = MD_ConnectRX_Port * 16 + MD_ConnectRX_pGun; + if (TXHData.POS_Info.Link_Flag == 0 // ,жһDzҪ߼¼ + || (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunControlState == Control_BoxAuto) // ȨģʽжһDzҪ߼¼ + || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].NowAuthorizeType > NowAuthorizeType_Online) // ģжһDzҪ߼¼ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].NowAuthorizeType = 0; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].CTOTAL; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].FData; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].Price; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].RTIME = TXHData.CTIME; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].OrderNumber; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].OrderNumber = 0; + for (i = 0; i < 6; i++) + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i] = TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].AssociatedDevices.location].CardNumber[i + 4]; // Ϣ10ֽڣֻȡ6 + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].AssociatedDevices.location].CardNumber[i] = 0; + AT45DBItemWrite(CA_PREXDATA, TXHData.PREXDATA_WaitUpNummber / 5); + FMItemWrite(CF_PREXDATA_TTC, 0); + if (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax) + TXHData.PREXDATA_WaitUpNummber++; + FMItemWrite(CF_PREXDATA_WaitUpNummber, 0); + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.UpdateRecords = 0; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i]; + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunState.Flag.UpdateRecords = 1; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].CardNumber[i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].WaitPREXDATA_flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].LTDelayTimer.ON_OFF = 0;//ӸʱжǷɽ׼¼ + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].LTDelayTimer.TimerCount = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + + TXHData.PrintLastRecord[Tempu64].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].CTOTAL; + TXHData.PrintLastRecord[Tempu64].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].FData; + TXHData.PrintLastRecord[Tempu64].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].GunNummber; + TXHData.PrintLastRecord[Tempu64].RTIME = TXHData.CTIME; + TXHData.PrintLastRecord[Tempu64].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[DeviceNumber].Price; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[DeviceNumber].OrderNumber; + FMItemWrite(CF_PrintLastRecord, Tempu64); + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake <= 0x0c) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Handshake = 0x0d; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LY_MDConnectCmdACK1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Need = LY_MDConnectCmdReadState; + } + break; + } + } + break; + + case PosBlueSkyPlus: // TXHData.LoopGunNextFlag + { + MD_ConnectRX_pGun = MD_Connect_BCDTou64(MD_Connect_RX_Buff[MD_ConnectRX_Port][1]); // ȡָ + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDeviceTop; DeviceNumber++) + if (MD_ConnectRX_pGun == MD_Connect_u64ToBCD(TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[DeviceNumber].Address)) + { + MD_ConnectRX_pGun_Father = DeviceNumber; + break; + } + MD_ConnectRX_Len = (MD_Connect_RX_Buff[MD_ConnectRX_Port][2] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][3]; + Temp16 = CRC_Check(&MD_Connect_RX_Buff[MD_ConnectRX_Port][0], MD_ConnectRX_Len); + if (Temp16 == ((MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len + 1])) + { + TXHData.RNGData = (MD_Connect_RX_Buff[MD_ConnectRX_Port][10] << 24) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][11] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][12] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][13]; + Bluesky_Decrypt(&MD_Connect_RX_Buff[MD_ConnectRX_Port][14], MD_ConnectRX_Len - 14, TXHData.RNGData); + + TXHData.MBCountTimer[MD_ConnectRX_Port].TimerCount = TXHData.MBCountTimer[MD_ConnectRX_Port].TimerCountMax; + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun_Father] = 0; + MD_ConnectRX_CMDType = MD_Connect_RX_Buff[MD_ConnectRX_Port][15]; + Offset = 16; + if (MD_ConnectRX_CMDType == 0xA1) // ָ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = 0; + MD_ConnectRX_CMD = MD_ConnectRX_CMDType = MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++]; + switch (MD_ConnectRX_CMD) + { + case LTP_DriverCMDReadPassword: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Password_Lever = MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++]; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Password = (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++] << 24) | + (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++] << 16) | + (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++] << 8) | + MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++]; + } + break; + case LTP_DriverCMDWritePassword: // + { + } + break; + case LTP_DriverCMDReadVerAndMac: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Version.VersionFindFlag = 1; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Version.Version[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset + i]; + Offset += 10; + for (i = 0; i < 12; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Mac[i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset + i]; + Offset += 12; + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNumber; DeviceNumber++) // ͬһ豸µ豸״̬ͬ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + DeviceNumber].Handshake = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + DeviceNumber].GunVersion.VersionFindFlag = 1; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + DeviceNumber].GunVersion.Version[i] = TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Version.Version[i]; + } + } + break; + case LTP_DriverCMDLock: // + { + } + break; + case LTP_DriverCMDUnlock: // + { + } + break; + case LTP_DriverCMDSendFrame: // + { + TXHData.MBCountTimer[MD_ConnectRX_Port].TimerCountMax = TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.MBCountTime * 10; // ;//ڵms + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].FrameNow = (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset + 1]); + Offset += 2; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].FrameNow >= TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.ROM_UpData.FrameTop) + { + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun_Father] = 6; // + } + else + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LTP_DriverCMDSendFrame; + } + break; + } + } + else if (MD_ConnectRX_CMDType == 0xA2) // ǹָ + { + + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNumber; DeviceNumber++) + { + MD_ConnectRX_pGun = TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart + DeviceNumber; // + Offset++; // + MD_ConnectRX_CMD = MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++]; + DeviceDataLen = Offset++; // + switch (MD_ConnectRX_CMD) + { + case LTP_GunCMDReadStateAndData: // + { + TXHData.LTGunState.State = MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++]; + if (TXHData.LTGunState.Flag.StartFlag == 1 || TXHData.LTGunState.Flag.GunUp == 0) // ǹ߼ + { + MD_ConnectRX_pGun_SonDeviceBusy = 1; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.OilCNT = ((MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++] << 24) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++])); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData.MoneyCNT = ((MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++] << 24) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++])); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price = (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++] << 16) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++] << 8) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++]); + } + case LTP_GunCMDReadState: // + { + if (MD_ConnectRX_CMD == LTP_GunCMDReadState) // + { + TXHData.LTGunState.State = MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++]; + if (TXHData.LTGunState.Flag.StartFlag == 1 || TXHData.LTGunState.Flag.GunUp == 0) // ǹ߼ + { + MD_ConnectRX_pGun_SonDeviceBusy = 1; + } + if (DeviceNumber == (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonNumber - 1)) + { + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online == 1 && MD_ConnectRX_pGun_SonDeviceBusy == 0) + { + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart].ROM_UpData_State.Flag.Update_Flag && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart].ROM_UpData_State.Flag.Update_Flag == 0) + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Version.VersionFindFlag) + { + for (i = 0; i < 6; i++) // жDzͬһϵ + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Version.Version[i] != TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.ROM_UpData_Version[i]) + break; + if (i == 6) + { + for (i = 6; i < 10; i++) // жϰ汾Dzͬ + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].Version.Version[i] != TXHData.MD_Port_Data[MD_ConnectRX_Port].PortData.ROM_UpData_Version[i]) + break; + if (i != 10) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].FrameNow = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].SonStart].ROM_UpData_State.Flag.Update_Flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].FatherDevice[MD_ConnectRX_pGun_Father].MB_CMD_Next = LTP_DriverCMDSendFrame; + } + } + } + } + } + } + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 1 - TXHData.LTGunState.Flag.GunUp; + if (TXHData.LTGunState.Flag.StartFlag == 0 && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 1) + { + // sprintf(Buff,"%d-AuthorizeState = 1",MD_ConnectRX_pGun); + // Log_Task(Buff,TrueCharBuffSize(Buff),MD_ConnectRX_Port,Info_String); + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.Start_Flag = 1; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 0x02; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadTotal; + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 1 - TXHData.LTGunState.Flag.GunUp; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag = TXHData.LTGunState.Flag.StartFlag; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag != TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.Start_Flag) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.Start_Flag = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadStateAndData; + if (TXHData.POS_Info.Link_Flag == 0 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number) + { + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState = 0x11; + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].MB_CMD_Next = RFID_MDConnectCmdWriteFullingInfo; + } + } + else + { + // sprintf(Buff,"%d-WaitPREXDATA_flag = 1",MD_ConnectRX_pGun); + // Log_Task(Buff,TrueCharBuffSize(Buff),MD_ConnectRX_Port,Info_String); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadTotal; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.TimerCountMax = 1000 * 5; + if (TXHData.POS_Info.Link_Flag == 0 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number) + { + TXHData.MD_Port_Data[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunData[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].GunState.Flag.UpdateDisplay = 0; + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState = 0; + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].MB_CMD_Next = RFID_MDConnectCmdWriteFullingInfo; + } + } + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag != TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.GunUP_Flag) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].fuelState_B.Flag.GunUP_Flag = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag; + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag == 0) // ǹ + { + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 0 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF == 0 && TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 0) // ѾȨˣûֱӹǹͬҪ߽ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadTotal; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.TimerCountMax = 1000 * 5; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + } + else // ǹ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag == 0) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 1; + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call = 0; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.GunUP_Flag = 0; + } + if (TXHData.POS_Info.Link_Flag == 0 || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) // ,жһDzҪȨ + { + if (TXHData.OfflineAuthorize == 1 && (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax)) // Ȩ + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Number == 0) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDAuthorize; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_NoCard; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + for (i = 0; i < 6; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i] = 0; + for (i = 0; i < 15; i++) + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CarLicensePlate[i] = 0; + } + else if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Call == 1) + { + if (TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState == 3) // ǩ֤ͨ + { + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].RFIDState = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].pGunCapture = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDAuthorize; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0x00; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = NowAuthorizeType_Offline_Card; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + } + } + } + } + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + } + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.Flag == 1) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.Flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadTotal; + } + if (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Start_Flag == 1 && TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next == LTP_GunCMDReadState) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadStateAndData; + } + } + } + break; + case LTP_GunCMDReadTotal: // + { + Tempu64 = 0; + for (i = 0; i < 6; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalLit = Tempu64; + Tempu64 = 0; + for (i = 0; i < 6; i++) + { + Tempu64 <<= 8; + Tempu64 |= MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset++]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL.TotalMoney = Tempu64; + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake == TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + Tempu64 = MD_ConnectRX_Port * 16 + MD_ConnectRX_pGun; // ӡ洢λ + if (TXHData.POS_Info.Link_Flag == 0 // ,жһDzҪ߼¼ + || (TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunControlState == Control_BoxAuto) // ȨģʽжһDzҪ߼¼ + || TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType > NowAuthorizeType_Online) // ģжһDzҪ߼¼ + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].NowAuthorizeType = 0; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].RTIME = TXHData.CTIME; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber = 0; + for (i = 0; i < 6; i++) + TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i] = TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i + 4]; // Ϣ10ֽڣֻȡ6 + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].AssociatedDevices.location].CardNumber[i] = 0; + AT45DBItemWrite(CA_PREXDATA, TXHData.PREXDATA_WaitUpNummber / 5); + FMItemWrite(CF_PREXDATA_TTC, 0); + if (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax) + TXHData.PREXDATA_WaitUpNummber++; + FMItemWrite(CF_PREXDATA_WaitUpNummber, 0); + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.PREXDATA[TXHData.PREXDATA_WaitUpNummber % 5].CardNum[i]; + } + else + { + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateRecords = 1; + TXHData.PrintLastRecord[Tempu64].OrderNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].OrderNumber; + for (i = 0; i < 6; i++) + TXHData.PrintLastRecord[Tempu64].CardNum[i] = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CardNumber[i]; + } + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + TXHData.PrintLastRecord[Tempu64].CTOTAL = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].CTOTAL; + TXHData.PrintLastRecord[Tempu64].FData = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].FData; + TXHData.PrintLastRecord[Tempu64].GunNumber = TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunNummber; + TXHData.PrintLastRecord[Tempu64].RTIME = TXHData.CTIME; + TXHData.PrintLastRecord[Tempu64].Price = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Price; + + FMItemWrite(CF_PrintLastRecord, Tempu64); + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].WaitPREXDATA_flag = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.TimerCount = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].LTDelayTimer.ON_OFF = 0; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadState; + // sprintf(Buff,"%d-WaitPREXDATA_flag = 0",MD_ConnectRX_pGun); + // Log_Task(Buff,TrueCharBuffSize(Buff),MD_ConnectRX_Port,Info_String); + } + else + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadState; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.UpdateDisplay = 1; + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.Online = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + } + } + break; + case LTP_GunCMDWritePrset: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadState; + Offset += DeviceDataLen; + } + break; + case LTP_GunCMDAuthorize: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadState; + TXHData.MD_Port_Info[MD_ConnectRX_Port].LoopGunNextFlag = 1; + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][Offset] == 0x59) + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 1; + else + TXHData.MD_Port_Data[MD_ConnectRX_Port].GunData[MD_ConnectRX_pGun].GunState.Flag.AuthorizeState = 0; + FMItemWrite(CF_MD_Port_Data, MD_ConnectRX_Port); + Offset += DeviceDataLen; + } + break; + case LTP_GunCMDStop: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadState; + Offset += DeviceDataLen; + } + break; + case LTP_GunCMDContinue: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadState; + Offset += DeviceDataLen; + } + break; + case LTP_GunCMDSuspend: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadState; + Offset += DeviceDataLen; + } + break; + case LTP_GunCMDReadEvent: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadState; + Offset += DeviceDataLen; + } + break; + case LTP_GunCMDReadError: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadState; + Offset += DeviceDataLen; + } + break; + case LTP_GunCMDReadParameter: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadState; + Offset += DeviceDataLen; + } + break; + case LTP_GunCMDWriteParameter: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = LTP_GunCMDReadState; + Offset += DeviceDataLen; + } + break; + } + } + } + } + } + break; + case PosPLC: + { + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][0] == 0x03) + { + MD_ConnectRX_Len = MD_Connect_RX_Buff[MD_ConnectRX_Port][2]; + Tempu64 = (MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len + 4] << 8) | MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len + 3]; + TempBCD = CRC_Check(&MD_Connect_RX_Buff[MD_ConnectRX_Port][0], MD_ConnectRX_Len + 3); + if (Tempu64 == TempBCD) + { + TXHData.CNGPLCState.Flag.Online = 1; + TXHData.MBCountCutNum[MD_ConnectRX_Port][0] = 0; + MD_ConnectRX_CMD = TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next; + switch (MD_ConnectRX_CMD) + { + case PLC_MDConnectCmdReadData: + { + for (i = 0; i < MD_ConnectRX_Len; i += 4) + { + TXHData.CNGPLCData.Buff[i + 0] = MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i + 3]; + TXHData.CNGPLCData.Buff[i + 1] = MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i + 2]; + TXHData.CNGPLCData.Buff[i + 2] = MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i + 1]; + TXHData.CNGPLCData.Buff[i + 3] = MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i + 0]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = PLC_MDConnectCmdReadErro; + } + break; + case PLC_MDConnectCmdReadErro: + { + for (i = 0; i < MD_ConnectRX_Len; i += 2) + { + TXHData.CNGPLCData.Buff[52 + i] = MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i + 1]; + TXHData.CNGPLCData.Buff[52 + i + 1] = MD_Connect_RX_Buff[MD_ConnectRX_Port][3 + i]; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = PLC_MDConnectCmdReadData; + } + break; + } + } + } + } + break; + case PosPrice1_4: + { + MD_ConnectRX_pGun = 0; + MD_ConnectRX_Len = MD_Connect_RX_Buff[MD_ConnectRX_Port][2]; + TempBCD = Price_DataCheck(&MD_Connect_RX_Buff[MD_ConnectRX_Port][2], MD_ConnectRX_Len - 1); + Tempu64 = MD_Connect_RX_Buff[MD_ConnectRX_Port][MD_ConnectRX_Len + 1]; + if (Tempu64 == TempBCD) + { + TXHData.MBCountCutNum[MD_ConnectRX_Port][MD_ConnectRX_pGun] = 0; + MD_ConnectRX_CMD = MD_Connect_RX_Buff[MD_ConnectRX_Port][4]; + switch (MD_ConnectRX_CMD) + { + case Price_MDConnectCmdWriteParameter: // д + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = Price_MDConnectCmdReadPrice; + } + break; + case Price_MDConnectCmdReadParameter: // + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = Price_MDConnectCmdReadPrice; + TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.State.Flag.Online = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.SingleOrDouble = MD_Connect_RX_Buff[MD_ConnectRX_Port][7]; + TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.PriceNumber = MD_Connect_RX_Buff[MD_ConnectRX_Port][8]; + TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.Length = MD_Connect_RX_Buff[MD_ConnectRX_Port][9]; + TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.Brightness = MD_Connect_RX_Buff[MD_ConnectRX_Port][11]; + } + break; + case Price_MDConnectCmdWritePrice: // д + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = Price_MDConnectCmdReadPrice; + } + break; + case Price_MDConnectCmdReadPrice: // + { + if (TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake < TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.State.Flag.UpdateDisplay = 1; + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].Handshake = TXHData.MD_Port_Info[MD_ConnectRX_Port].Handshake_Top; + } + TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.State.Flag.Online = 1; + for (i = 0; i < TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.PriceNumber; i++) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.Price[i] = 0; + for (j = 0; j < TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.Length / 2; j++) + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.Price[i] |= MD_Connect_RX_Buff[MD_ConnectRX_Port][5 + j + i * TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.Length / 2] << (8 * (TXHData.MD_Port_Info[MD_ConnectRX_Port].PriceTagData.Length / 2 - 1 - j)); + } + } + } + break; + case Price_MDConnectCmdWriteDecimal: // дСλ + { + TXHData.MD_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].MB_CMD_Next = Price_MDConnectCmdWritePrice; + } + break; + } + } + } + break; + } + for (i = 0; i < 20; i++) + MD_Connect_RX_Buff[MD_ConnectRX_Port][i] = 0; + } + else if (TXHData.MDConnectState[MD_ConnectRX_Port].Flag.WorkMode == 0) // WiFiָģʽ + { + switch (TXHData.MDConnectState[MD_ConnectRX_Port].Flag.SetModeCMDNext) + { + case WIFI_ATRec: + { + Temp16 = mystrstr(MD_Connect_RX_Buff[MD_ConnectRX_Port], "OK"); + if (Temp16) + { + TXHData.MBCountTimer[MD_ConnectRX_Port].TimerCount = 0; + TXHData.MBCountTimer[MD_ConnectRX_Port].Flag = 1; + TXHData.MDConnectState[MD_ConnectRX_Port].Flag.SetModeCMDNext = WIFI_WMODE; + } + } + break; + case WIFI_WMODE: + { + Temp16 = mystrstr(MD_Connect_RX_Buff[MD_ConnectRX_Port], "OK"); + if (Temp16) + { + TXHData.MBCountTimer[MD_ConnectRX_Port].TimerCount = 0; + TXHData.MBCountTimer[MD_ConnectRX_Port].Flag = 1; + TXHData.MDConnectState[MD_ConnectRX_Port].Flag.SetModeCMDNext = WIFI_WifiRST; + } + } + break; + case WIFI_WifiWSSSID: + { + Temp16 = mystrstr(MD_Connect_RX_Buff[MD_ConnectRX_Port], "OK"); + if (Temp16) + { + TXHData.MBCountTimer[MD_ConnectRX_Port].TimerCount = 0; + TXHData.MBCountTimer[MD_ConnectRX_Port].Flag = 1; + TXHData.MDConnectState[MD_ConnectRX_Port].Flag.SetModeCMDNext = WIFI_WifiSOCKET; + } + } + break; + case WIFI_WifiRSSI: + { + // Temp16 = mystrstr(MD_Connect_RX_Buff[MD_ConnectRX_Port],"atus:"); + // if(Temp16) + { + TXHData.MBCountTimer[MD_ConnectRX_Port].TimerCount = 0; + TXHData.MBCountTimer[MD_ConnectRX_Port].Flag = 1; + TXHData.POS_Info.WiFiRSSI = MD_Connect_BCDTou64(((MD_Connect_RX_Buff[MD_ConnectRX_Port][Temp16 + 5] - 0x30) << 4) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Temp16 + 6] - 0x30)); + Temp16 = mystrstr(MD_Connect_RX_Buff[MD_ConnectRX_Port], ","); + if (Temp16) + { + if (MD_Connect_RX_Buff[MD_ConnectRX_Port][Temp16 + 1] >= 0x30) + TXHData.POS_Info.WiFiChannel = MD_Connect_BCDTou64(((MD_Connect_RX_Buff[MD_ConnectRX_Port][Temp16] - 0x30) << 4) | (MD_Connect_RX_Buff[MD_ConnectRX_Port][Temp16 + 1] - 0x30)); + else + TXHData.POS_Info.WiFiChannel = MD_Connect_BCDTou64(MD_Connect_RX_Buff[MD_ConnectRX_Port][Temp16] - 0x30); + } + TXHData.MDConnectState[MD_ConnectRX_Port].Flag.SetModeCMDNext = WIFI_WifiSOCKET; + } + } + break; + case WIFI_WifiSOCKET: + { + Temp16 = mystrstr(MD_Connect_RX_Buff[MD_ConnectRX_Port], "OK"); + if (Temp16) + { + BEEP_OFF; + TXHData.MDConnectState[MD_ConnectRX_Port].Flag.WorkMode = 1; + TXHData.MBCountTimer[MD_ConnectRX_Port].TimerCountMax = 1000; + } + } + break; + case WIFI_WifiRST: + { + Temp16 = mystrstr(MD_Connect_RX_Buff[MD_ConnectRX_Port], "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.WorkMode = 0; + TXHData.MDConnectState[MD_ConnectRX_Port].Flag.SetModeCMDNext = WIFI_WifiWSSSID; + // TXHData.POSNetSetState.Flag.POSNetSetNeedFlag = 0; + TXHData.POSReLinkTimer.Flag = 0; + TXHData.POSReLinkTimer.TimerCount = 0; + } + } + break; + } + } + } +} diff --git a/User/MD_Connect/MD_Connect.h b/User/MD_Connect/MD_Connect.h new file mode 100644 index 0000000..5ea2d4e --- /dev/null +++ b/User/MD_Connect/MD_Connect.h @@ -0,0 +1,293 @@ +#ifndef __MD_Connect_H_ +#define __MD_Connect_H_ +/*H****************************************************************************** +* NAME: MD_Connect.h +*********************************************************************************/ + +typedef struct +{ + u8 ADDRH; + u8 ADDRL; + u8 Communication; + u8 CRYPTH; + u8 CRYPTL; +} LORA_Set_Type; + +//Ӳ +#define MD_ConnectUsart1 USART2 +#define MD_Connect_DMA DMA1 + +#define MD_Connect_TX1_DMAAddrSet(x) (DMA1_Stream6->M0AR = x) //ƽջַ +#define MD_Connect_TX1_DMALenSet(x) (DMA1_Stream6->NDTR = x) //÷DMA +#define MD_Connect_TX1_DMAStart() DMA_Cmd(DMA1_Stream6,ENABLE) //DMA +#define MD_Connect_TX1_DMAStop() DMA_Cmd(DMA1_Stream6,DISABLE) //DMA + +#define MD_Connect_RX1_DMALenSet(x) (DMA1_Stream5->NDTR = x) //DMA +#define MD_Connect_RX1_DMAStart() DMA_Cmd(DMA1_Stream5,ENABLE) //DMA +#define MD_Connect_RX1_DMAStop() DMA_Cmd(DMA1_Stream5,DISABLE) //DMA + +#define MD_ConnectUsart2 USART4 +#define MD_Connect_DMA DMA1 + +#define MD_Connect_TX2_DMAAddrSet(x) (DMA1_Stream4->M0AR = x) //ƽջַ +#define MD_Connect_TX2_DMALenSet(x) (DMA1_Stream4->NDTR = x) //÷DMA +#define MD_Connect_TX2_DMAStart() DMA_Cmd(DMA1_Stream4,ENABLE) //DMA +#define MD_Connect_TX2_DMAStop() DMA_Cmd(DMA1_Stream4,DISABLE) //DMA + +#define MD_Connect_RX2_DMALenSet(x) (DMA1_Stream2->NDTR = x) //DMA +#define MD_Connect_RX2_DMAStart() DMA_Cmd(DMA1_Stream2,ENABLE) //DMA +#define MD_Connect_RX2_DMAStop() DMA_Cmd(DMA1_Stream2,DISABLE) //DMA + +#define MD_ConnectUsart3 USART5 +#define MD_Connect_DMA DMA1 + +#define MD_Connect_TX3_DMAAddrSet(x) (DMA1_Stream7->M0AR = x) //ƽջַ +#define MD_Connect_TX3_DMALenSet(x) (DMA1_Stream7->NDTR = x) //÷DMA +#define MD_Connect_TX3_DMAStart() DMA_Cmd(DMA1_Stream7,ENABLE) //DMA +#define MD_Connect_TX3_DMAStop() DMA_Cmd(DMA1_Stream7,DISABLE) //DMA + +#define MD_Connect_RX3_DMALenSet(x) (DMA1_Stream0->NDTR = x) //DMA +#define MD_Connect_RX3_DMAStart() DMA_Cmd(DMA1_Stream0,ENABLE) //DMA +#define MD_Connect_RX3_DMAStop() DMA_Cmd(DMA1_Stream0,DISABLE) //DMA + +#define MD_ConnectUsart4 USART3 +#define MD_Connect_DMA DMA1 + +#define MD_Connect_TX4_DMAAddrSet(x) (DMA1_Stream3->M0AR = x) //ƽջַ +#define MD_Connect_TX4_DMALenSet(x) (DMA1_Stream3->NDTR = x) //÷DMA +#define MD_Connect_TX4_DMAStart() DMA_Cmd(DMA1_Stream3,ENABLE) //DMA +#define MD_Connect_TX4_DMAStop() DMA_Cmd(DMA1_Stream3,DISABLE) //DMA + +#define MD_Connect_RX4_DMALenSet(x) (DMA1_Stream1->NDTR = x) //DMA +#define MD_Connect_RX4_DMAStart() DMA_Cmd(DMA1_Stream1,ENABLE) //DMA +#define MD_Connect_RX4_DMAStop() DMA_Cmd(DMA1_Stream1,DISABLE) //DMA + + +#define Check_NONE 0 +#define Check_EVEN 1 +#define Check_ODD 2 + +/*********************Эָ************************/ + +#define BaudRateSync 115200 + +#define MDConnect_start 0xF5 //ͨͷ + +#define MDConnect_false 0x4E //ʧ + +#define MDConnect_succeed 0x59 //ɹ +#define MDConnect_GetICCID 0x5A // + +#define C_MDConnectCmdWriteDensity 0XA2 //дܶ +#define C_MDConnectCmdReadDensity 0XA6 //ܶ + + +#define C_MDConnectCmdWritePrice 0XB2 //д +#define C_MDConnectResumeFueling 0xB3 // +#define C_MDConnectCmdWritePrsetSale 0xB5 //дԤý +#define C_MDConnectCmdReadPrice 0XB6 // +#define C_MDConnectCmdWritePrsetVolume 0xB9 //дԤ +#define C_MDConnectPauseFueling 0xBA //ͣ + +#define C_MDConnectCmdStart 0xC3 // +#define C_MDConnectCmdReadTotal 0xC5 // +#define C_MDConnectCmdReadSquadTop 0XC7 // +#define C_MDConnectCmdStop 0xCA //ͣ +#define C_MDConnectCmdWriteTotal 0xCE //д + +#define C_MDConnectCmdWriteValveTurnOff 0xD2 //дǰطPulseCoefficient +#define C_MDConnectCmdReadState 0xD5 //ȡͻ״̬ +#define C_MDConnectCmdReadValveTurnOff 0xD6 //ǰط +#define C_MDConnectAakIDCardNummber 0xD7 //ҪID +#define C_MDConnectCmdReadFuelState 0xD9 //ȡͻ״̬Ϣ + +#define C_MDConnectCmdWritePulseCoefficient 0xE1 //дPulseCoefficient +#define C_MDConnectCmdReadPulseCoefficient 0xE2 // +#define C_MDConnectASKControlPower 0xE5 //ҪȨ +#define C_MDConnectReturnControlPower 0xE7 //Ȩ +#define C_MDConnectCmdClrSquadTop 0XEA // +#define C_MDConnectChangePassWord 0xEB //Ļе + +#define C_MDConnectCmdReadVersion 0x11 //汾 +#define C_MDConnectCmdSetBaudRate 0x12 //ͬ +#define C_MDConnectCmdSendFrame 0x13 //֡ + +/*********************LY JPЭָ************************/ +#define LY_MDConnectCmdPoll 0XA1 //ѯ +#define LY_MDConnectCmdReadState 0XA2 //״̬ +#define LY_MDConnectCmdChoiceGun 0XA3 //ѡǹ +#define LY_MDConnectCmdAuthorize 0XA4 //Ȩ +#define LY_MDConnectCmdWritePrice 0XA5 //д +#define LY_MDConnectCmdACK0 0XA6 //1030 +#define LY_MDConnectCmdACK1 0XA7 //1031 +#define LY_MDConnectCmdHandshake 0XA8 // +#define LY_MDConnectCmdReadTotal 0XA9 // +#define LY_MDConnectCmdDisauthorize 0XAA //ȡȨ + +/*********************DartЭָ************************/ +#define DART_MDConnectCmdPoll 0XB1 //ѯ +#define DART_MDConnectCmdReadState 0XB2 //״̬ +#define DART_MDConnectCmdReStart 0XB3 // +#define DART_MDConnectCmdAuthorize 0XB4 //Ȩ +#define DART_MDConnectCmdWritePrice 0XB5 //д +#define DART_MDConnectCmdACK 0XB6 //ACK +#define DART_MDConnectCmdNAK 0XB7 //NAK +#define DART_MDConnectCmdReadVTotal 0XB8 // +#define DART_MDConnectCmdReadPTotal 0XB9 // +#define DART_MDConnectCmdDisauthorize 0XBA //ȡȨ + +/*********************ҺλЭָ************************/ +#define YWY_MDConnectCmdReadData 0X31 // +#define YWY_MDConnectCmdWriteApacity 0X45 //عݱ + +/*********************LORAЭָ************************/ +#define LORA_ParameterSet 0XFF //LORA +/*********************RFIDЭָ************************/ +#define RFID_MDConnectCmdReadData 0XF1 //ǹ +#define RFID_MDConnectCmdWriteCardInfo 0XF2 // +#define RFID_MDConnectCmdWriteFullingInfo 0XF3 // +#define RFID_MDConnectCmdReadVersion 0XF4 // +#define RFID_MDConnectCmdWriteBindingInfo 0XF6 //Ͱ󶨵ǹ +#define RFID_MDConnectCmdLossACK 0XF7 // +#define RFID_MDConnectCmdFindACK 0XF8 // +#define RFID_MDConnectCmdROMownload 0X05 // +#define RFID_MDConnectCmdAllData 0X06 //һǹ + +/*********************ӢЭָ************************/ +#define YG_MDConnectCmdWritePrset 0x01 //дԤ +#define YG_MDConnectCmdWritePrice 0X02 //д +#define YG_MDConnectCmdStop 0x04 //ͣ +#define YG_MDConnectCmdStart 0x05 //Ȩ +#define YG_MDConnectControlMode 0x06 //ͻΪѻģʽ +#define YG_MDConnectCmdReadTotal 0x07 // +#define YG_MDConnectCmdRemovePrset 0x08 //ȡԤ +#define YG_MDConnectCmdSetTime 0x0C //ͬʱ +#define YG_MDConnectCmdInTestMode 0x0D //ͬʱ +#define YG_MDConnectCmdOutTestMode 0x0E //ͬʱ +#define YG_MDConnectCmdReadVersion 0X0F //ȡͻ汾 +#define YG_MDConnectCmdUnLock 0X10 // +#define YG_MDConnectCmdLock 0X11 // +#define YG_MDConnectCmdReadFuelVolumeState 0x14 //ȡͻ״̬Ϣ +#define YG_MDConnectCmdReadFuelSaleState 0x15 //ظ +#define YG_MDConnectCmdReadFuelRecord 0x16 //ȡͼ¼ +#define YG_MDConnectCmdReadFuelRecordNull 0x18 //ظ¼ +#define YG_MDConnectCmdReadFuelRecordConfirm 0x17 //ͼ¼ȷ + +/*********************Эָ************************/ +#define HY_MDConnectCmdWritePrice 0X80 //д +#define HY_MDConnectCmdWritePrsetSale 0x89 //дԤý +#define HY_MDConnectCmdReadPrice 0X8C // +#define HY_MDConnectCmdWritePrsetVolume 0x8B //дԤ +#define HY_MDConnectCmdStart 0x08 // +#define HY_MDConnectCmdReadTotal 0x8E // +#define HY_MDConnectCmdStop 0x10 //ͣ +#define HY_MDConnectCmdReadFuelData 0x8F //ȡϢ +#define HY_MDConnectASKControlPower 0x15 //ҪȨ +#define HY_MDConnectReturnControlPower 0x14 //Ȩ +/**********************Эָ******************************/ +#define LF_MDConnectCmdWritePrice 0XA1 //д +#define LF_MDConnectCmdReadTotal 0xA3 // +#define LF_MDConnectCmdReadState 0xB0 //ȡͻ״̬ +#define LF_MDConnectCmdFuilingStateReply 0xB3 //лظ +#define LF_MDConnectCmdIdleStateReply 0xBA //״̬ظ +#define LF_MDConnectCmdRecordConfirm 0xD2 //׼¼ȷ +#define LF_MDConnectCmdReadFuelRecord 0xE3 //ȡͼ¼ +#define LF_MDConnectCmdWritePrset 0xE4 //дԤ +#define LF_MDConnectASKControlPower 0xE5 //ҪȨ +#define LF_MDConnectReturnControlPower 0xE6 //Ȩ +#define LF_MDConnectCmdStop 0xE7 //ͣ + +/**********************PlusЭָ******************************/ +#define LTP_DriverCMD 0xA1 //ָ +#define LTP_GunCMD 0XA2 //ǹ +//ָб +#define LTP_DriverCMDReadPassword 0X01 // +#define LTP_DriverCMDWritePassword 0X02 //д +#define LTP_DriverCMDReadVerAndMac 0X03 //汾Ψһ +#define LTP_DriverCMDLock 0X04 // +#define LTP_DriverCMDUnlock 0X05 // +#define LTP_DriverCMDSendFrame 0X06 //֡ +//ǹб +#define LTP_GunCMDReadState 0x01 //ȡͻ״̬ +#define LTP_GunCMDReadStateAndData 0x02 //ȡͻ״̬ +#define LTP_GunCMDReadTotal 0x03 // +#define LTP_GunCMDWritePrset 0x04 //дԤ +#define LTP_GunCMDAuthorize 0x05 //Ȩ +#define LTP_GunCMDStop 0x06 //ͣ +#define LTP_GunCMDReadEvent 0x07 //¼ +#define LTP_GunCMDReadError 0x08 // +#define LTP_GunCMDReadParameter 0x09 // +#define LTP_GunCMDWriteParameter 0x0A //д +#define LTP_GunCMDSuspend 0x0B //ͣ +#define LTP_GunCMDContinue 0x0C // +//ǹб +#define LTP_GunParameterListPrice 0x01 //۲ +#define LTP_GunParameterListPluse 0x02 //嵱 +#define LTP_GunParameterListTurnOff 0x03 //ǰط +#define LTP_GunParameterListMinDisp 0x04 //Сʾֵ + +/*********************CNGPLCָ************************/ +#define PLC_MDConnectCmdReadData 0X01 // +#define PLC_MDConnectCmdReadErro 0X02 // + +/*********************ָ************************/ +#define Price_MDConnectCmdWriteParameter 0X00 //д +#define Price_MDConnectCmdWritePrice 0X01 //д +#define Price_MDConnectCmdReadParameter 0X02 // +#define Price_MDConnectCmdReadPrice 0X03 // +#define Price_MDConnectCmdWriteDecimal 0X04 //д + +#define MD_Connect_RS485_Tx1EN GPIO_ResetBits(GPIOD,GPIO_Pin_7); +#define MD_Connect_RS485_Rx1EN GPIO_SetBits(GPIOD,GPIO_Pin_7); +#define MD_Connect_RS485_Tx2EN GPIO_ResetBits(GPIOD,GPIO_Pin_3); +#define MD_Connect_RS485_Rx2EN GPIO_SetBits(GPIOD,GPIO_Pin_3); +#define MD_Connect_RS485_Tx3EN GPIO_ResetBits(GPIOA,GPIO_Pin_8); +#define MD_Connect_RS485_Rx3EN GPIO_SetBits(GPIOA,GPIO_Pin_8); +#define MD_Connect_RS485_Tx4EN GPIO_ResetBits(GPIOD,GPIO_Pin_10); +#define MD_Connect_RS485_Rx4EN GPIO_SetBits(GPIOD,GPIO_Pin_10); + +#define MD_Connect_LORA_SetMode1 GPIO_SetBits(GPIOG,GPIO_Pin_14); +#define MD_Connect_LORA_IdleMode1 GPIO_ResetBits(GPIOG,GPIO_Pin_14); +#define MD_Connect_LORA_SetMode2 GPIO_SetBits(GPIOG,GPIO_Pin_13); +#define MD_Connect_LORA_IdleMode2 GPIO_ResetBits(GPIOG,GPIO_Pin_13); +#define MD_Connect_LORA_SetMode3 GPIO_SetBits(GPIOG,GPIO_Pin_12); +#define MD_Connect_LORA_IdleMode3 GPIO_ResetBits(GPIOG,GPIO_Pin_12); +#define MD_Connect_LORA_SetMode4 GPIO_SetBits(GPIOG,GPIO_Pin_11); +#define MD_Connect_LORA_IdleMode4 GPIO_ResetBits(GPIOG,GPIO_Pin_11); + +//****************************************************************************** +//*-------------- ----------------------------------------------------- +//****************************************************************************** +typedef enum +{ + LORA_Master, + LORA_Slave, + +}LORA_MODE_Tyye; +extern volatile u8 MD_ConnectRX1Task_Flag; //MD_ConnectͨѶDMAɱ־־ +extern volatile u8 MD_ConnectRX2Task_Flag; //MD_ConnectͨѶDMAɱ־־ +extern volatile u8 MD_ConnectRX3Task_Flag; //MD_ConnectͨѶDMAɱ־־ +extern volatile u8 MD_ConnectRX4Task_Flag; //MD_ConnectͨѶDMAɱ־־ + +//****************************************************************************** +//*-------------- ----------------------------------------------------- +//****************************************************************************** +extern void MD_Connect_USART_Configuration(u8 PortNum,u32 Baud,u16 USART_WordLength,u8 Check); +extern void MD_Connect_Init(void); //MD_Connectʼ +extern void MD_Port_Init(u8 Port); +extern void MD_Connect_DMARX1_IRQHandler(void); //MD_Connect̽жϷ +extern void MD_Connect_DMATX1_IRQHandler(void); //DMAжϷ +extern void MD_Connect_DMARX2_IRQHandler(void); //MD_Connect̽жϷ +extern void MD_Connect_DMATX2_IRQHandler(void); //DMAжϷ +extern void MD_Connect_DMARX3_IRQHandler(void); //MD_Connect̽жϷ +extern void MD_Connect_DMATX3_IRQHandler(void); //DMAжϷ +extern void MD_Connect_DMARX4_IRQHandler(void); //MD_Connect̽жϷ +extern void MD_Connect_DMATX4_IRQHandler(void); //DMAжϷ +extern u64 MD_Connect_u64ToBCD(u64 Dat); +extern u64 MD_Connect_BCDTou64(u64 Dat); +extern void MD_ConnectRXTask(void); +extern void MD_ConnectTXTask(u8 Port,u8 GunNum,u8 MD_TX_CMD); +extern void MD_Port_LORASet(u8 Port,u8 Mode); +extern u8 BCC_CheckSum(u8 *buf, u8 len);//BCCУ麯; +extern float StrToFloat(u8 *str,u8 len); +#endif //#ifndef diff --git a/User/Multiplex_Port/Multiplex_Port.c b/User/Multiplex_Port/Multiplex_Port.c new file mode 100644 index 0000000..5635beb --- /dev/null +++ b/User/Multiplex_Port/Multiplex_Port.c @@ -0,0 +1,829 @@ +#include "config.h" + +volatile u8 Multiplex_Port_RX_Flag = 0;//Multiplex_Port־λ1 +volatile u8 Multiplex_Port_TX_Flag = 0;// +volatile u8 Multiplex_Port_RX_Buff[1000] = {0x01,0x03,0x00,0x02,0x00,0x09,0x00,0x00};; +volatile u8 Multiplex_Port_TX_Buff[1000] = {0x01,0x03,0x00,0x02,0x00,0x09,0x00,0x00};; +volatile u8 Multiplex_Port_DMA_RX_Len = 23; +/*_____ D E F I N I T I O N __________________________________________________*/ + +u16 BigToLittle( u16 BigData) +{ + return (BigData << 8 | BigData >> 8); +} +//u32 BigToLittle( u32 BigData) +//{ +// union +// { +// u32 Temp; +// u8 Buff[4]; +// }Dat; +// +// if(sizeof(BigData) == 2) +// return (BigData << 8 | BigData >> 8); +// else if(sizeof(BigData) == 4) +// { +// Dat.Buff[0] = (BigData >> 24) & 0xff; +// Dat.Buff[1] = (BigData >> 16) & 0xff; +// Dat.Buff[2] = (BigData >> 8) & 0xff; +// Dat.Buff[3] = (BigData >> 0) & 0xff; +// return (Dat.Temp); +// } +//} +/**************************************************** +Multiplex_Port_IO_Configuration + Multiplex_PortͨѶõIOʼ + +ֵ +****************************************************/ +void Multiplex_Port_IO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; //GOIPýṹ + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); + + GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6); + GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOC, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_13 | GPIO_Pin_14; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//ͨģʽ + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;// + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// + GPIO_Init(GPIOC, &GPIO_InitStructure);//ʼ + Multiplex_Port_RS485_RxEN1; + Multiplex_Port_RS485_RxEN2; +} +/**************************************************** +Multiplex_Port_NVMultiplex_Port_Configuration + Multiplex_PortͨѶõж + +ֵ +****************************************************/ +void Multiplex_Port_NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; //жýṹ + + NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream6_IRQn; //USART6_TX_DMA + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + + NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn; //USART?? + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ???? + NVIC_Init(&NVIC_InitStructure); //??NVIC_InitStruct???????????NVIC???USART1 +} + + +/**************************************************** +Multiplex_Port_NVMultiplex_Port_Configuration + Multiplex_PortͨѶõĴ + +ֵ +****************************************************/ +void Multiplex_Port_USART_Configuration(u32 Baud,u8 Check) +{ + USART_InitTypeDef USART_InitStructure; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); + USART_InitStructure.USART_BaudRate =Baud;// Baud;//????? + if(Check == Check_EVEN) + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + USART_InitStructure.USART_Parity = USART_Parity_Even; + } + else if(Check == Check_ODD) + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + USART_InitStructure.USART_Parity = USART_Parity_Odd; + } + else if(Check == Check_NONE) + { + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_Parity = USART_Parity_No; + } + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + USART_Init(USART6, &USART_InitStructure); + USART_Cmd(USART6, ENABLE); + + USART_ITConfig(USART6, USART_IT_IDLE, ENABLE); + USART_ClearFlag(USART6, USART_FLAG_IDLE); + + USART_DMACmd(USART6, USART_DMAReq_Tx | USART_DMAReq_Rx,ENABLE); + +} +/************************************************* + DMA_Configuration + DMAʼ + +ֵ +**************************************************/ +void Multiplex_Port_DMA_Configuration(void) +{ + DMA_InitTypeDef DMA_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); + + /*******************TX1*********************/ + DMA_DeInit(DMA2_Stream6); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + //DMA_InitStructure.DMA_BufferSize = UART_DMA_SEND_LEN; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART6->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_5; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Multiplex_Port_TX_Buff; + + DMA_Init(DMA2_Stream6, &DMA_InitStructure); + DMA_ITConfig(DMA2_Stream6, DMA_IT_TC, ENABLE); + /*******************RX*********************/ + DMA_DeInit(DMA2_Stream1); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = 1000; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART6->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_5; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Multiplex_Port_RX_Buff; + + DMA_Init(DMA2_Stream1, &DMA_InitStructure); + DMA_Cmd(DMA2_Stream1, ENABLE); + + +} +//F***************************************************************************** +//* NAME: Multiplex_Port_TXDataCheck +//* PURPOSE: Multiplex_PortͨУ麯 +//* PARAMS: pDataҪַlenݳ +//* return: +//****************************************************************************** +u8 Multiplex_Port_TXDataCheck(volatile u8* pData, u8 len) +{ + u8 result; + if(len == 0) len = 16; + result = *pData++; + do + { + result ^= *pData++; + }while(--len); + + return result & 0x7f; +} +void Multiplex_Port_DMATX_IRQHandler(void) +{ + u16 i = 0; + DMA_ClearFlag(DMA2_Stream6, DMA_IT_TCIF6); + Multiplex_Port_TX_DMAStop(); //رDMA + while(! USART_GetFlagStatus(USART6, USART_FLAG_TC))NULL; + Multiplex_Port_RS485_RxEN1; + Multiplex_Port_RS485_RxEN2; + DMA_ClearFlag(DMA2_Stream1, DMA_IT_TCIF1); + Multiplex_Port_RX_DMAStart(); //DMA(Gas)ѡͶʱ + Multiplex_Port_TX_Flag = 1; +} +//F***************************************************************************** +//* NAME: Multiplex_Port_DMARX_IRQHandler +//* PURPOSE: DMAжϣGas ModBus +//* PARAMS: +//* return: +//****************************************************************************** + +void Multiplex_Port_DMARX_IRQHandler(void) +{ + u8 i = 0; + u16 CRC_Temp = 0; + if(USART_GetITStatus(USART6, USART_IT_IDLE) != RESET)//????????? + { + USART_ClearFlag(USART6, USART_IT_IDLE); + i = USART6->SR; + i = USART6->DR; + TXHData.MD_MultiplexRXIDLETimer.ON_OFF = 1; + TXHData.MD_Multiplex_Rec_NummberB = 1000 - DMA2_Stream1->NDTR; + } +} +//F***************************************************************************** +//* NAME: Price_DataCheck +//* PURMDE: Ƽ㷨 +//* PARAMS: pDataҪַlenݳ +//* return: +//****************************************************************************** +u8 Price_DataCheck(volatile u8* pData, u16 len) +{ + u8 result = 0; + do + { + result += *pData++; + }while(--len); + + return result; +} +void StringToHex(u8 *Str,u8 *H,u8 Len) +{ + u8 i = 0; + for(i = 0;i < Len;i += 2) + { + if(*(Str + i) > 0x39) + *(H + (i / 2)) = (*(Str + i) - 0x37) << 4; + else + *(H + (i / 2)) = (*(Str + i) - 0x30) << 4; + + if(*(Str + i + 1) > 0x39) + *(H + (i / 2)) |= (*(Str + i + 1) - 0x37) & 0x0f; + else + *(H + (i / 2)) |= (*(Str + i + 1) - 0x30) & 0x0f; + } + } +u16 mystrstr(u8 *s1,u8 *s2) +{ + int len2; + u16 i= 0; + if(!(len2=strlen(s2)))//s2ָգstrlen޷ȣ + return 1; + for(;*s1;++s1) + { + i ++; + if(*s1==*s2 && strncmp(s1,s2,len2)==0) + return i; + } + return NULL; +} + +void Multiplex_Port_Choose(u8 Port) +{ + switch(Port) + { + case 0: + { + GPIO_ResetBits(GPIOC,GPIO_Pin_13);//B + GPIO_ResetBits(GPIOC,GPIO_Pin_8);//A + }break; + case 1: + { + GPIO_ResetBits(GPIOC,GPIO_Pin_13);//B + GPIO_SetBits(GPIOC,GPIO_Pin_8);//A + }break; + case 2: + { + GPIO_SetBits(GPIOC,GPIO_Pin_13);//B + GPIO_ResetBits(GPIOC,GPIO_Pin_8);//A + }break; + case 3: + { + GPIO_SetBits(GPIOC,GPIO_Pin_13);//B + GPIO_SetBits(GPIOC,GPIO_Pin_8);//A + }break; + } +} +//F***************************************************************************** +//* NAME: Multiplex_Port_Init +//* PURPOSE: Multiplex_PortͨѶʼ +//* PARAMS: +//* return: +//****************************************************************************** + +void Multiplex_Port_Init(void) +{ + u8 i = 0; + Multiplex_Port_IO_Configuration(); //IOʼ + Multiplex_Port_USART_Configuration(115200,Check_NONE); //شڳʼ + Multiplex_Port_DMA_Configuration(); //DMAʼ + Multiplex_Port_NVIC_Configuration(); //жϳʼ + + TXHData.MD_MultiplexRXIDLETimer.Init = 0; //ʼ־ + TXHData.MD_MultiplexRXIDLETimer.Flag = 0; //ʱ־ + TXHData.MD_MultiplexRXIDLETimer.ON_OFF = 0; // + TXHData.MD_MultiplexRXIDLETimer.Cycle = 0; //Ϊѭģʽʱ + TXHData.MD_MultiplexRXIDLETimer.TimerCountMax = 5;//10001s + + TXHData.MD_MultiplexTimer.Init = 0; //ʼ־ + TXHData.MD_MultiplexTimer.Flag = 0; //ʱ־ + TXHData.MD_MultiplexTimer.ON_OFF = 1; // + TXHData.MD_MultiplexTimer.Cycle = 1; //Ϊѭģʽʱ + TXHData.MD_MultiplexTimer.TimerCountMax = 1000;//10001s + //TXHData.MD_Multiplex_Port_Data.PortData[0].POSType = 1; +// TXHData.MD_Multiplex_Port_Data.DeviceNumber =1; + if(TXHData.MD_Multiplex_Port_Data.DeviceNumber == 0) + { + if(TXHData.HardwareVersion >= 26)//汾26֮GPSģ + { + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[0].Init = 0; //ʼ־ + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[0].Flag = 0; //ʱ־ + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[0].ON_OFF = 1; // + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[0].Cycle = 1; //Ϊѭģʽʱ + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[0].TimerCountMax = 10*1000;//10001s + TXHData.MD_Multiplex_Port_Data.PortData[0].MBCountTime = 10*100; + TXHData.MD_Multiplex_Port_Data.PortData[0].POSType = Multiplex_GPS; + TXHData.MD_Multiplex_Port_Data.PortData[0].BaudRate = 9600; + TXHData.MD_Multiplex_Port_Data.PortData[0].StopBits = 1; + TXHData.MD_Multiplex_Port_Data.DeviceNumber += 1;//GPSģһλ + } + } + else + { + for(i = 0;i < TXHData.MD_Multiplex_Port_Data.DeviceNumber;i ++) + { + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[i].Init = 0; //ʼ־ + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[i].Flag = 0; //ʱ־ + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[i].ON_OFF = 1; // + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[i].Cycle = 1; //Ϊѭģʽʱ + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[i].TimerCountMax = TXHData.MD_Multiplex_Port_Data.PortData[i].MBCountTime * 10;//10001s + switch(TXHData.MD_Multiplex_Port_Data.PortData[i].POSType) + { + case Multiplex_Print:TXHData.MD_Multiplex_Port_Info.MB_CMD_Next[i] = PT_Null;break; + case Multiplex_YWY : + TXHData.MD_MultiplexRXIDLETimer.TimerCountMax = 50;//10001s + TXHData.MD_Multiplex_Port_Info.MB_CMD_Next[i] = YWY_MDConnectCmdReadData; + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[i].TimerCountMax = TXHData.MD_Multiplex_Port_Data.PortData[i].MBCountTime * 100;break; + case Multiplex_Price:TXHData.MD_Multiplex_Port_Info.MB_CMD_Next[i] = Price_MDConnectCmdReadParameter; + TXHData.MD_Multiplex_Port_Info.Handshake_Top[i] = 2; + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[i].TimerCountMax = TXHData.MD_Multiplex_Port_Data.PortData[i].MBCountTime * 100;break; + } + } + } +} + +void Multiplex_PortTXTask(u8 PosTypeTemp,u8 MD_TX_CMD) +{ + u16 i = 0,j = 0,k = 0,MD_Port_Num = 0,DeviceNumber = 0,MD_ConnectTX_Len = 0; + u8 GunNum = 0,GunAddr = 0,SunNum = 0; + u64 TempBCD = 0,Tempu64 = 0; + u8 Data_201[7] = "i20100"; + u8 Data_20E[7] = "i20E00"; + + Multiplex_Port_TX_Flag = 0; + if(TXHData.MD_Multiplex_Port_Info.MBCountCutNum[PosTypeTemp] >= 4) + { + TXHData.MD_Multiplex_Port_Info.MBCountCutNum[PosTypeTemp] = 5; + TXHData.MD_Multiplex_Port_Info.Handshake[PosTypeTemp] = 0; + TXHData.MD_Multiplex_Port_Data.State[PosTypeTemp].Flag.Online = 0; + switch(TXHData.MD_Multiplex_Port_Data.PortData[PosTypeTemp].POSType) + { + case Multiplex_Print:TXHData.MD_Multiplex_Port_Info.MB_CMD_Next[PosTypeTemp] = PT_Null;break; + case Multiplex_YWY :TXHData.MD_Multiplex_Port_Info.MB_CMD_Next[PosTypeTemp] = YWY_MDConnectCmdReadData;break; + case Multiplex_Price:TXHData.MD_Multiplex_Port_Info.MB_CMD_Next[PosTypeTemp] = Price_MDConnectCmdReadParameter;TXHData.MD_Multiplex_Port_Info.Handshake[PosTypeTemp] = 0;break; + } + } + switch(TXHData.MD_Multiplex_Port_Data.PortData[PosTypeTemp].POSType) + { + case Multiplex_Print: + { + if(TXHData.MD_Multiplex_Port_Info.PrintType != PT_Null) + { + Multiplex_Port_Choose(0); + Multiplex_Port_USART_Configuration(TXHData.MD_Multiplex_Port_Data.PortData[PosTypeTemp].BaudRate,TXHData.MD_Multiplex_Port_Data.PortData[PosTypeTemp].Parity_Even); + switch(TXHData.MD_Multiplex_Port_Info.PrintType) + { + case PT_LastRecord: + { + DeviceNumber = TXHData.MD_Multiplex_Port_Info.PrintPlaceNumber; + GunNum = TXHData.PrintLastRecord[DeviceNumber].GunNumber; + TXHData.PrintRecord.FData = TXHData.PrintLastRecord[DeviceNumber].FData; + TXHData.PrintRecord.Price = TXHData.PrintLastRecord[DeviceNumber].Price; + TXHData.PrintRecord.RTIME = TXHData.PrintLastRecord[DeviceNumber].RTIME; + MD_Port_Num = DeviceNumber / 16; + }break; + case PT_Record: + { + GunNum = TXHData.PrintRecord.GunNumber; + for(MD_Port_Num = 0;MD_Port_Num < TXHData.MD_Port_Num_Top;MD_Port_Num ++) + { + for(DeviceNumber = 0;DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber;DeviceNumber ++) + { + if(TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber == GunNum) + break; + } + if(DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber) + break; + } + }break; + } + + Print_Num(0,6,MD_Connect_u64ToBCD(GunNum),0); + Print_Num(0,7,TXHData.PrintRecord.FData.MoneyCNT,TXHData.MD_Port_Data[MD_Port_Num].PortData.GunDec.Dec.MoneyCNT); + Print_Num(0,8,TXHData.PrintRecord.FData.OilCNT,TXHData.MD_Port_Data[MD_Port_Num].PortData.GunDec.Dec.OilCNT); + Print_Num(0,9,TXHData.PrintRecord.Price,TXHData.MD_Port_Data[MD_Port_Num].PortData.GunDec.Dec.Price); + + TXHData.PrintInfo.PrintBuff[11][30-18] = '2';TXHData.PrintInfo.PrintBuff[11][30-17] = '0'; + TXHData.PrintInfo.PrintBuff[11][30-16] = ((TXHData.PrintRecord.RTIME.Year>>4)&0x0f)+'0';TXHData.PrintInfo.PrintBuff[11][30-15] = ((TXHData.PrintRecord.RTIME.Year)&0x0f)+'0'; + TXHData.PrintInfo.PrintBuff[11][30-14] = '-'; + TXHData.PrintInfo.PrintBuff[11][30-13] = ((TXHData.PrintRecord.RTIME.Month>>4)&0x0f)+'0';TXHData.PrintInfo.PrintBuff[11][30-12] = ((TXHData.PrintRecord.RTIME.Month)&0x0f)+'0'; + TXHData.PrintInfo.PrintBuff[11][30-11] = '-'; + TXHData.PrintInfo.PrintBuff[11][30-10] = ((TXHData.PrintRecord.RTIME.Day>>4)&0x0f)+'0';TXHData.PrintInfo.PrintBuff[11][30-9] = ((TXHData.PrintRecord.RTIME.Day)&0x0f)+'0'; + + TXHData.PrintInfo.PrintBuff[11][30-7] = ((TXHData.PrintRecord.RTIME.Hour>>4)&0x0f)+'0';TXHData.PrintInfo.PrintBuff[11][30-6] = ((TXHData.PrintRecord.RTIME.Hour)&0x0f)+'0'; + TXHData.PrintInfo.PrintBuff[11][30-5] = ':'; + TXHData.PrintInfo.PrintBuff[11][30-4] = ((TXHData.PrintRecord.RTIME.Min>>4)&0x0f)+'0';TXHData.PrintInfo.PrintBuff[11][30-3] = ((TXHData.PrintRecord.RTIME.Min)&0x0f)+'0'; + TXHData.PrintInfo.PrintBuff[11][30-2] = ':'; + TXHData.PrintInfo.PrintBuff[11][30-1] = ((TXHData.PrintRecord.RTIME.Sec>>4)&0x0f)+'0';TXHData.PrintInfo.PrintBuff[11][30] = (TXHData.PrintRecord.RTIME.Sec & 0x0f)+'0'; + Print_Num(0,12,MD_Connect_u64ToBCD(TXHData.PrintRecord.OrderNumber),0); + for(i = 0;i < 650;i++) + Multiplex_Port_TX_Buff[i] = 0x20; + Multiplex_Port_TX_Buff[0] = LF; + Multiplex_Port_TX_Buff[1] = LF; + for(i = 0;i< 20;i++) + { + for(j = 0;j< 32;j++) + if(TXHData.PrintInfo.PrintBuff[i][j] != 0x20) + break; + if(j < 31) + { + for(j = 0;j< 32;j++) + Multiplex_Port_TX_Buff[k*32+j] = TXHData.PrintInfo.PrintBuff[i][j]; + k ++; + } + } + Multiplex_Port_TX_Buff[k*32+32+0] = LF; + Multiplex_Port_TX_Buff[k*32+32+1] = LF; + Multiplex_Port_TX_Buff[k*32+32+2] = LF; + Multiplex_Port_TX_Buff[k*32+32+3] = LF; + Multiplex_Port_TX_Buff[k*32+32+4] = LF; + Multiplex_Port_TX_Buff[k*32+32+5] = LF; + MD_ConnectTX_Len = k*32+32+5; + TXHData.MD_Multiplex_Port_Info.PrintType = PT_Null; + } + }break; + case Multiplex_YWY: + { + Multiplex_Port_Choose(1); + Multiplex_Port_RS485_TxEN1; + Multiplex_Port_USART_Configuration(TXHData.MD_Multiplex_Port_Data.PortData[PosTypeTemp].BaudRate,TXHData.MD_Multiplex_Port_Data.PortData[PosTypeTemp].Parity_Even); + TXHData.MD_Multiplex_Port_Info.MBCountCutNum[GunNum] ++; + //switch(TXHData.MD_Port_Data[PosTypeTemp].PortData.Device_Type) + { + //case YWY_Bluesky: + { + switch (MD_TX_CMD) + { + case YWY_MDConnectCmdReadData:// + { + for(i = 0;i < 7;i ++) + Multiplex_Port_TX_Buff[i] = Data_201[i]; + MD_ConnectTX_Len = 7; + } + break; + case YWY_MDConnectCmdWriteApacity://عݱ + { + for(i = 0;i < 7;i ++) + Multiplex_Port_TX_Buff[i] = Data_20E[i]; + MD_ConnectTX_Len = 7; + } + break; + } + }//break; + } + }break; + case Multiplex_Price: + { + Multiplex_Port_Choose(2); + Multiplex_Port_RS485_TxEN2; + TXHData.MD_Multiplex_Port_Info.MBCountCutNum[PosTypeTemp] ++; + Multiplex_Port_USART_Configuration(TXHData.MD_Multiplex_Port_Data.PortData[PosTypeTemp].BaudRate,TXHData.MD_Multiplex_Port_Data.PortData[PosTypeTemp].Parity_Even); + switch (MD_TX_CMD) + { + case Price_MDConnectCmdWriteParameter://д + { + Multiplex_Port_TX_Buff[0] = 0xFE; + Multiplex_Port_TX_Buff[1] = 0xFF; + Multiplex_Port_TX_Buff[2] = 0x04; + Multiplex_Port_TX_Buff[3] = 0x01; + Multiplex_Port_TX_Buff[4] = 0x03; + Tempu64 = Price_DataCheck(&Multiplex_Port_TX_Buff[2],Multiplex_Port_TX_Buff[2]-1); + Multiplex_Port_TX_Buff[5] = Tempu64; + Multiplex_Port_TX_Buff[6] = 0xEF; + MD_ConnectTX_Len = 7; + } + break; + case Price_MDConnectCmdReadParameter:// + { + Multiplex_Port_TX_Buff[0] = 0xFE; + Multiplex_Port_TX_Buff[1] = 0xFF; + Multiplex_Port_TX_Buff[2] = 0x04; + Multiplex_Port_TX_Buff[3] = 0x01; + Multiplex_Port_TX_Buff[4] = 0x02; + Tempu64 = Price_DataCheck(&Multiplex_Port_TX_Buff[2],Multiplex_Port_TX_Buff[2]-1); + Multiplex_Port_TX_Buff[5] = Tempu64; + Multiplex_Port_TX_Buff[6] = 0xEF; + MD_ConnectTX_Len = 7; + } + break; + case Price_MDConnectCmdWriteDecimal://дСλ + { + Multiplex_Port_TX_Buff[0] = 0xFE; + Multiplex_Port_TX_Buff[1] = 0xFF; + Multiplex_Port_TX_Buff[2] = 16; + Multiplex_Port_TX_Buff[3] = 0x01; + Multiplex_Port_TX_Buff[4] = 0x04; + for(j = 0;j < TXHData.MD_Multiplex_Port_Info.PriceTagData.PriceNumber;j ++) + { + Multiplex_Port_TX_Buff[5 + j] = TXHData.MD_Multiplex_Port_Info.PriceTagData.Length - TXHData.MD_Multiplex_Port_Info.PriceTagData.Decimal[j]; + } + for(j = TXHData.MD_Multiplex_Port_Info.PriceTagData.PriceNumber;j < 17;j ++) + Multiplex_Port_TX_Buff[5 + j] = 0; + Tempu64 = Price_DataCheck(&Multiplex_Port_TX_Buff[2],Multiplex_Port_TX_Buff[2]-1); + Multiplex_Port_TX_Buff[17] = Tempu64; + Multiplex_Port_TX_Buff[18] = 0xEF; + MD_ConnectTX_Len = 19; + } + break; + case Price_MDConnectCmdWritePrice://д + { + Multiplex_Port_TX_Buff[0] = 0xFE; + Multiplex_Port_TX_Buff[1] = 0xFF; + Multiplex_Port_TX_Buff[2] = 40; + Multiplex_Port_TX_Buff[3] = 0x01; + Multiplex_Port_TX_Buff[4] = 0x01; + for(i = 5;i < 40; i++) + Multiplex_Port_TX_Buff[i] = 0; + for(i = 0;i < TXHData.MD_Multiplex_Port_Info.PriceTagData.PriceNumber; i++) + { + for(j = 0;j < 3;j ++) + { + if(TXHData.MD_Multiplex_Port_Info.PriceTagData.Length/2 > j) + Multiplex_Port_TX_Buff[5+ j + (i * 3)] = TXHData.MD_Multiplex_Port_Info.PriceTagData.Price[i] >> ((TXHData.MD_Multiplex_Port_Info.PriceTagData.Length/2-1-j)*8); + else + Multiplex_Port_TX_Buff[5+ j + (i * 3)] = 0; + } + } + Tempu64 = Price_DataCheck(&Multiplex_Port_TX_Buff[2],Multiplex_Port_TX_Buff[2]-1); + Multiplex_Port_TX_Buff[41] = Tempu64; + Multiplex_Port_TX_Buff[42] = 0xEF; + MD_ConnectTX_Len = 43; + } + break; + case Price_MDConnectCmdReadPrice:// + { + Multiplex_Port_TX_Buff[0] = 0xFE; + Multiplex_Port_TX_Buff[1] = 0xFF; + Multiplex_Port_TX_Buff[2] = 0x04; + Multiplex_Port_TX_Buff[3] = 0x01; + Multiplex_Port_TX_Buff[4] = 0x03; + Tempu64 = Price_DataCheck(&Multiplex_Port_TX_Buff[2],Multiplex_Port_TX_Buff[2]-1); + Multiplex_Port_TX_Buff[5] = Tempu64; + Multiplex_Port_TX_Buff[6] = 0xEF; + MD_ConnectTX_Len = 7; + } + break; + } + }break; + case Multiplex_GPS: + { + Multiplex_Port_Choose(3); + TXHData.MD_Multiplex_Port_Info.MBCountCutNum[GunNum] ++; + Multiplex_Port_USART_Configuration(TXHData.MD_Multiplex_Port_Data.PortData[PosTypeTemp].BaudRate,TXHData.MD_Multiplex_Port_Data.PortData[PosTypeTemp].Parity_Even); + }break; + } + if(MD_ConnectTX_Len) + { + Multiplex_Port_TX_DMALenSet(MD_ConnectTX_Len); + Multiplex_Port_TX_DMAStart(); + } +} + +void Multiplex_PortRXTask(void) +{ + volatile u16 i = 0,j = 0,Temp = 0,DeviceNumber = 0; + volatile u64 TempBCD = 0,Tempu64 = 0; + volatile u8 MD_ConnectRX_Port = 0; + volatile u8 MD_ConnectRX_Len = 0; // + volatile u8 MD_ConnectRX_pGun = 0; //ַǹ + volatile u8 MD_ConnectRX_pGun_Sun = 0; //dartЭǹ + volatile u16 MD_ConnectRX_CMD = 0; // + u8 MD_ConnectRX_Check = 0; //У + u8 Buff[50]; + u8 POSType_Temp = 0; + volatile u32 CRC_temp = 0; + volatile float TempF = 0; + volatile u8 Tank_Num; + u8 Data_201[7] = "i20100"; + u8 Data_20E[7] = "i20E00"; + + if(TXHData.MD_MultiplexRXIDLETimer.Flag) + { + TXHData.MD_MultiplexRXIDLETimer.Flag = 0; + if(TXHData.MD_Multiplex_Rec_NummberB == 1000 - DMA2_Stream1->NDTR) + { + TXHData.MD_Multiplex_Rec_Nummber = 1000 - DMA2_Stream1->NDTR; + Multiplex_Port_RX_DMAStop(); //رDMA + DMA_ClearFlag(DMA2_Stream1, DMA_IT_TCIF1); + Multiplex_Port_RX_Flag = 1; //ʹGas + Multiplex_Port_RX_DMALenSet(1000);//ýܳ + Multiplex_Port_RX_DMAStart(); //DMA + } + } + if(Multiplex_Port_RX_Flag == 1) + { + Multiplex_Port_RX_Flag = 0; + POSType_Temp = TXHData.MD_Multiplex_Port_Data.PortData[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow].POSType; + switch(POSType_Temp) + { + case Multiplex_Print: + { + TXHData.MD_MultiplexTimer.Flag = 1; + TXHData.MD_MultiplexTimer.TimerCount = 0; + }break; + case Multiplex_YWY: + { + //switch(TXHData.MD_Multiplex_Port_Data.PortData[POSType_Temp].Device_Type) + { + //case YWY_Bluesky: + { + TempBCD = CheckSum(&Multiplex_Port_RX_Buff[1],TXHData.MD_Multiplex_Rec_Nummber - 6); + Tempu64 = StrToInt(&Multiplex_Port_RX_Buff[TXHData.MD_Multiplex_Rec_Nummber - 5],4); + if(Tempu64 == TempBCD) + { + TXHData.MD_Multiplex_Port_Info.MBCountCutNum[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow] = 0; + MD_ConnectRX_CMD = Multiplex_Port_RX_Buff[4]; + switch(MD_ConnectRX_CMD) + { + case YWY_MDConnectCmdReadData: + { + TXHData.TankNumTop = Tempu64 = (TXHData.MD_Multiplex_Rec_Nummber - 24) / 65; + for(i = 0;i < Tempu64;i ++) + { + if(Multiplex_Port_RX_Buff[23 + i * 65] == 0) + TXHData.TankState[4][i].State = Multiplex_Port_RX_Buff[20 + i * 65]; + TempF = StrToFloat(&Multiplex_Port_RX_Buff[26 + i * 65], 8); + if(Multiplex_Port_RX_Buff[26 + i * 65] != 0x3F) + TXHData.TankData[4][i].Data.OV = TempF; + else + TXHData.TankData[4][i].Data.OV = 0; + TempF = StrToFloat(&Multiplex_Port_RX_Buff[50 + i * 65], 8); + if(Multiplex_Port_RX_Buff[50 + i * 65] != 0x3F) + TXHData.TankData[4][i].Data.OH = TempF; + else + TXHData.TankData[4][i].Data.OH = 0; + TempF = StrToFloat(&Multiplex_Port_RX_Buff[58 + i * 65], 8); + if(Multiplex_Port_RX_Buff[58 + i * 65] != 0x3F) + TXHData.TankData[4][i].Data.WH = TempF; + else + TXHData.TankData[4][i].Data.WH = 0; + TempF = StrToFloat(&Multiplex_Port_RX_Buff[66 + i * 65], 8); + if(Multiplex_Port_RX_Buff[66 + i * 65] != 0x3F) + TXHData.TankData[4][i].Data.TH = TempF; + else + TXHData.TankData[4][i].Data.TH = 0; + TXHData.MD_Multiplex_Port_Data.State[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow].Flag.Online = 1; + //TXHData.MD_Multiplex_Port_Info[MD_ConnectRX_Port].GunInfo[MD_ConnectRX_pGun].RSSI = Multiplex_Port_RX_Buff[TXHData.MD_Multiplex_Rec_Nummber - 1]; + } + }break; + case YWY_MDConnectCmdWriteApacity: + { + + }break; + } + } + }//break; + } + TXHData.MD_MultiplexTimer.Flag = 1; + TXHData.MD_MultiplexTimer.TimerCount = 0; + }break; + case Multiplex_Price: + { + MD_ConnectRX_Len = Multiplex_Port_RX_Buff[2]; + TempBCD = Price_DataCheck(&Multiplex_Port_RX_Buff[2],MD_ConnectRX_Len - 1); + Tempu64 = Multiplex_Port_RX_Buff[MD_ConnectRX_Len+1]; + if(Tempu64 == TempBCD) + { + TXHData.MD_Multiplex_Port_Info.MBCountCutNum[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow] = 0; + TXHData.MD_MultiplexTimer.Flag = 1; + TXHData.MD_MultiplexTimer.TimerCount = 0; + MD_ConnectRX_CMD = Multiplex_Port_RX_Buff[4]; + switch (MD_ConnectRX_CMD) + { + case Price_MDConnectCmdWriteParameter://д + { + TXHData.MD_Multiplex_Port_Info.MB_CMD_Next[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow] = Price_MDConnectCmdReadPrice; + } + break; + case Price_MDConnectCmdReadParameter:// + { + TXHData.MD_Multiplex_Port_Info.Handshake[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow] = 1; + TXHData.MD_Multiplex_Port_Info.MB_CMD_Next[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow] = Price_MDConnectCmdReadPrice; + TXHData.MD_Multiplex_Port_Info.PriceTagData.State.Flag.Online = 1; + TXHData.MD_Multiplex_Port_Info.PriceTagData.SingleOrDouble = Multiplex_Port_RX_Buff[7]; + TXHData.MD_Multiplex_Port_Info.PriceTagData.PriceNumber = Multiplex_Port_RX_Buff[8]; + TXHData.MD_Multiplex_Port_Info.PriceTagData.Length = Multiplex_Port_RX_Buff[9]; + TXHData.MD_Multiplex_Port_Info.PriceTagData.Brightness = Multiplex_Port_RX_Buff[11]; + } + break; + case Price_MDConnectCmdWritePrice://д + { + TXHData.MD_Multiplex_Port_Info.MB_CMD_Next[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow] = Price_MDConnectCmdReadPrice; + } + break; + case Price_MDConnectCmdReadPrice:// + { + if(TXHData.MD_Multiplex_Port_Info.Handshake[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow] < TXHData.MD_Multiplex_Port_Info.Handshake_Top[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow] ) + { + TXHData.MD_Multiplex_Port_Data.State[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow].Flag.UpdateDisplay = 1; + TXHData.MD_Multiplex_Port_Info.Handshake[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow] = TXHData.MD_Multiplex_Port_Info.Handshake_Top[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow]; + } + TXHData.MD_Multiplex_Port_Data.State[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow].Flag.Online = 1; + for(i = 0;i < TXHData.MD_Multiplex_Port_Info.PriceTagData.PriceNumber; i++) + { + TXHData.MD_Multiplex_Port_Info.PriceTagData.Price[i] = 0; + for(j = 0;j < TXHData.MD_Multiplex_Port_Info.PriceTagData.Length/2;j ++) + { + TXHData.MD_Multiplex_Port_Info.PriceTagData.Price[i] |= Multiplex_Port_RX_Buff[5 + j + i*TXHData.MD_Multiplex_Port_Info.PriceTagData.Length/2] << (8*(TXHData.MD_Multiplex_Port_Info.PriceTagData.Length/2 - 1 -j)); + } + } + } + break; + case Price_MDConnectCmdWriteDecimal://дСλ + { + TXHData.MD_Multiplex_Port_Info.MB_CMD_Next[TXHData.MD_Multiplex_Port_Info.DevicerTypeNow] = Price_MDConnectCmdWritePrice; + } + break; + } + } + }break; + case Multiplex_GPS: + { + TXHData.MD_MultiplexTimer.Flag = 1; + TXHData.MD_MultiplexTimer.TimerCount = 0; + Temp = mystrstr(Multiplex_Port_RX_Buff,"RMC"); + if(Temp && Temp < 800) + { + for(i = 0;i < 30;i ++) + Multiplex_Port_RX_Buff[i] = Multiplex_Port_RX_Buff[Temp + 14 + i]; + TXHData.USART6_Drive = GPS; + if(Multiplex_Port_RX_Buff[0] == 'A')//ȡȺγϢ + { + for(i = 0;i < 11;i ++)// ȡϢ浽TXHDataṹ + { + if(Multiplex_Port_RX_Buff[2+i] == ',') + break; + Buff[i] = Multiplex_Port_RX_Buff[2 + i]; + } + TempF = (float)atof(Buff) / 100; + Tempu64 = TempF; + TempF -= Tempu64; + TXHData.GPSData.GPS.Longitude = Tempu64 + TempF * 100 / 60; + TXHData.GPSData.GPS.LongitudeType = Multiplex_Port_RX_Buff[3 + i]; + Temp = 5 + i; + for(i = 0;i < 11;i ++)// ȡάϢ浽TXHDataṹ + { + if(Multiplex_Port_RX_Buff[Temp + i] == ',') + break; + Buff[i] = Multiplex_Port_RX_Buff[Temp + i]; + } + TempF = (float)atof(Buff) / 100; + Tempu64 = TempF; + TempF -= Tempu64; + TXHData.GPSData.GPS.Latitude = Tempu64 + TempF * 100 / 60; + TXHData.GPSData.GPS.LatitudeType = Multiplex_Port_RX_Buff[Temp + i + 1]; + + } + else //γϢЧΪ0 + { + TXHData.GPSData.GPS.Latitude = 0; + TXHData.GPSData.GPS.LatitudeType = 0; + TXHData.GPSData.GPS.Latitude = 0; + TXHData.GPSData.GPS.LatitudeType = 0; + } + } + else //γϢЧΪ0 + { + TXHData.GPSData.GPS.Latitude = 0; + TXHData.GPSData.GPS.LatitudeType = 0; + TXHData.GPSData.GPS.Latitude = 0; + TXHData.GPSData.GPS.LatitudeType = 0; + } + + }break; + } + for(i = 0;i < 20;i ++) + Multiplex_Port_RX_Buff[i] = 0; + } +} + diff --git a/User/Multiplex_Port/Multiplex_Port.h b/User/Multiplex_Port/Multiplex_Port.h new file mode 100644 index 0000000..e7a1726 --- /dev/null +++ b/User/Multiplex_Port/Multiplex_Port.h @@ -0,0 +1,47 @@ +#ifndef __Multiplex_Port_H_ +#define __Multiplex_Port_H_ +/*H****************************************************************************** +* NAME: Multiplex_Port.h +*********************************************************************************/ + +//****************************************************************************** +//Ӳ + +typedef enum +{ + Multiplex_Normal, + Multiplex_GPS=1, + Multiplex_Print=4, + Multiplex_Price=5, + Multiplex_YWY=6, + +}MultiplexItem; + +#define Multiplex_Port_RS485_RxEN1 GPIO_ResetBits(GPIOC,GPIO_Pin_9); +#define Multiplex_Port_RS485_TxEN1 GPIO_SetBits(GPIOC,GPIO_Pin_9); +#define Multiplex_Port_RS485_RxEN2 GPIO_ResetBits(GPIOC,GPIO_Pin_14); +#define Multiplex_Port_RS485_TxEN2 GPIO_SetBits(GPIOC,GPIO_Pin_14); + +#define Multiplex_Port_TX_DMAAddrSet(x) (DMA2_Stream6->M0AR = x) //Ʒͻַ +#define Multiplex_Port_TX_DMALenSet(x) (DMA2_Stream6->NDTR = x) //DMAͳ +#define Multiplex_Port_TX_DMAStart() DMA_Cmd(DMA2_Stream6,ENABLE) ;Multiplex_Port_TX_Flag = 0; //DMA +#define Multiplex_Port_TX_DMAStop() DMA_Cmd(DMA2_Stream6,DISABLE) //رDMA + +#define Multiplex_Port_RX_DMAAddrSet(x) (DMA2_Stream1->M0AR = x) //ƽջַ +#define Multiplex_Port_RX_DMALenSet(x) (DMA2_Stream1->NDTR = x) //DMA +#define Multiplex_Port_RX_DMAStart() DMA_Cmd(DMA2_Stream1,ENABLE) //DMA +#define Multiplex_Port_RX_DMAStop() DMA_Cmd(DMA2_Stream1,DISABLE) //رDMA +extern volatile u8 Multiplex_Port_TX_Flag;// +extern volatile u8 Multiplex_Port_RX_Flag;// +extern void Multiplex_Port_DMATX_IRQHandler(void); +extern void Multiplex_Port_DMARX_IRQHandler(void); +extern u16 mystrstr(u8 *s1,u8 *s2); +extern void StringToHex(u8 *Str,u8 *H,u8 Len); +extern u16 CRC_Check(u8 *puchMsg, u16 usDataLen) ; +extern u16 BigToLittle( u16 BigData); +extern void Multiplex_Port_Init(void); +extern void Multiplex_Port_USART_Configuration(u32 Baud,u8 Check); +extern void Multiplex_PortTXTask(u8 PosTypeTemp,u8 MD_TX_CMD); +extern void Multiplex_PortRXTask(void); +extern u8 Price_DataCheck(volatile u8* pData, u16 len); +#endif //#ifndef diff --git a/User/OLED/bmp.h b/User/OLED/bmp.h new file mode 100644 index 0000000..4f07645 --- /dev/null +++ b/User/OLED/bmp.h @@ -0,0 +1,43 @@ +#ifndef __BMP_H +#define __BMP_H +const unsigned char BMP_Bluesky_Con_48[] = +{ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0xF8,0xF8,0xF8,0xF8,0x00,0x80,0x80,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0xD8,0xFC,0xFC,0xFF,0xFF, + 0xFF,0xFF,0x7F,0x1F,0x07,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x0F,0x0F,0x0F,0x06,0x00,0x20,0x40,0x80,0x00,0x00, + 0x00,0x80,0xE0,0xF8,0x3C,0x0F,0x07,0x01,0xC0,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0x8F,0x81,0xC0,0xC0,0xE0,0xF8,0x7C,0x7E,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x87,0xFC,0x00,0xFC,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x07,0x07,0x07,0x03,0x03, + 0x03,0x03,0x01,0x01,0x00,0x00,0x00,0xE0,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0x30,0x1C,0x07,0x00,0x00, + 0x07,0x1F,0x3F,0xFC,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x03,0x00,0x80,0x80, + 0xC0,0xC0,0x60,0x70,0x70,0x38,0x0C,0x06,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x07,0x07,0x0E,0x0E,0x0E,0x1C,0x1C,0x1C,0x1C, + 0x1C,0x1C,0x1C,0x1C,0x1C,0x1D,0x1D,0x1F,0x0F,0x0F,0x0E,0x07,0x07,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00/*"G:\ͼ.bmp",0*/ +}; +const unsigned char BMP_Bluesky_Con_24[] = +{ + 0x00,0x00,0x00,0x80,0xC0,0x60,0xF0,0xF8,0xFE,0xFE,0x3E,0x18,0x08,0x08,0x08,0x08,0x08,0x00,0x30,0x30,0x00,0x40,0x80,0x00,0xF8,0xFE,0x07,0x01,0x1C,0x3F,0x3F,0x1F, + 0x1B,0x18,0x0E,0xCF,0xFF,0xFF,0xFF,0x7F,0x0F,0x0F,0x0F,0x07,0x80,0xC0,0x7B,0x0E,0x07,0x0F,0x1C,0x38,0x30,0x30,0x60,0x60,0x60,0x60,0x7E,0x7F,0x3F,0x3F,0x31,0x18, + 0x18,0x0C,0x0E,0x03,0x03,0x00,0x00,0x00};/*"G:\ͼ24.bmp",0*/; +const unsigned char BMP_Bluesky_Empty_8[] = + {0xFF,0x81,0x81,0x81,0x81,0x81,0x81,0xFF};/*"",0*/ +const unsigned char BMP_Bluetooth_9[] = +{0x00,0x01,0x82,0x44,0xFF,0x11,0xAA,0x44,0x00,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x00};/*"",0*/ +const unsigned char BMP_GPS_9[] = +{0x10,0x38,0x54,0x82,0xD7,0x82,0x54,0x38,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00};/*"λ",0*/ +const unsigned char BMP_GPS_None_9[] = +{0x10,0x38,0x54,0x82,0xC7,0x82,0x54,0x38,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00};/*"λ",0*/ +const unsigned char BMP_WIFI0_14x8[] = +{0x00,0x00,0x00,0x82,0x44,0x28,0x10,0x28,0x44,0x82,0x00,0x00,0x00,0x00};/*"F:\BlueSky\ͨѶ\WIFI-3.bmp",0*/ +const unsigned char BMP_WIFI1_14x8[] = +{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00};/*"F:\BlueSky\ͨѶ\WIFI-3.bmp",0*/ +const unsigned char BMP_WIFI2_14x8[] = +{0x00,0x00,0x00,0x00,0x20,0x10,0xD0,0xD0,0x10,0x20,0x00,0x00,0x00,0x00};/*"F:\BlueSky\ͨѶ\WIFI-3.bmp",0*/ + +const unsigned char BMP_WIFI3_14x8[] = +{0x00,0x00,0x10,0x08,0x24,0x14,0xD4,0xD4,0x14,0x24,0x08,0x10,0x00,0x00};/*"F:\BlueSky\ͨѶ\WIFI-3.bmp",0*/ + +const unsigned char BMP_WIFI4_14x8[] = +{0x08,0x04,0x12,0x09,0x25,0x15,0xD5,0xD5,0x15,0x25,0x09,0x12,0x04,0x08};/*"F:\BlueSky\ͨѶ\WIFI-3.bmp",0*/ + +#endif + + diff --git a/User/OLED/oled.c b/User/OLED/oled.c new file mode 100644 index 0000000..aa12ef3 --- /dev/null +++ b/User/OLED/oled.c @@ -0,0 +1,449 @@ +#include "config.h" +#include "oledfont.h" + +u8 OLED_GRAM[144][8]; + +//Ժ +void OLED_ColorTurn(u8 i) +{ + if(i==0) + { + OLED_WR_Byte(0xA6,OLED_CMD);//ʾ + } + if(i==1) + { + OLED_WR_Byte(0xA7,OLED_CMD);//ɫʾ + } +} + +//Ļת180 +void OLED_DisplayTurn(u8 i) +{ + if(i==0) + { + OLED_WR_Byte(0xC8,OLED_CMD);//ʾ + OLED_WR_Byte(0xA1,OLED_CMD); + } + if(i==1) + { + OLED_WR_Byte(0xC0,OLED_CMD);//תʾ + OLED_WR_Byte(0xA0,OLED_CMD); + } +} + +/**************************************************** +OLED_SPI2_SendByte + FM洢õSPIͺ + dt Ҫ͵ +ֵ +****************************************************/ +u8 OLED_SPI2_SendByte(u8 dt) +{ + while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); + SPI_I2S_SendData(SPI2, dt); + while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); + return SPI_I2S_ReceiveData(SPI2); +} + +void OLED_WR_Byte(u8 dat,u8 cmd) +{ + if(cmd) + OLED_DC_Set(); + else + OLED_DC_Clr(); + OLED_CS_Clr(); + OLED_SPI2_SendByte(dat); + OLED_CS_Set(); + OLED_DC_Set(); +} + +//OLEDʾ +void OLED_DisPlay_On(void) +{ + OLED_WR_Byte(0x8D,OLED_CMD);//ɱʹ + OLED_WR_Byte(0x14,OLED_CMD);//ɱ + OLED_WR_Byte(0xAF,OLED_CMD);//Ļ +} + +//رOLEDʾ +void OLED_DisPlay_Off(void) +{ + OLED_WR_Byte(0x8D,OLED_CMD);//ɱʹ + OLED_WR_Byte(0x10,OLED_CMD);//رյɱ + OLED_WR_Byte(0xAE,OLED_CMD);//رĻ +} + +//Դ浽OLED 1.8ms +void OLED_Refresh(void) +{ + u8 i=0,n=0; + OLED_WR_Byte(0xb0+i,OLED_CMD); //ʼַ + OLED_WR_Byte(0x00,OLED_CMD); //õʼַ + OLED_WR_Byte(0x10,OLED_CMD); //øʼַ + for(i=0;i<8;i++) + { + for(n=0;n<128;n++) + OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); + } +} +// +void OLED_Clear(void) +{ + u8 i,n; + for(i=0;i<8;i++) + { + for(n=0;n<128;n++) + { + OLED_GRAM[n][i]=0;// + } + } + //OLED_Refresh();//ʾ +} + +// +//x:0~127 +//y:0~63 +//t:1 0, +void OLED_DrawPoint(u8 x,u8 y,u8 t) +{ + u8 i,m,n; + i=y/8; + m=y%8; + n=1<0)incx=1; //õ + else if (delta_x==0)incx=0;//ֱ + else {incx=-1;delta_x=-delta_x;} + if(delta_y>0)incy=1; + else if (delta_y==0)incy=0;//ˮƽ + else {incy=-1;delta_y=-delta_x;} + if(delta_x>delta_y)distance=delta_x; //ѡȡ + else distance=delta_y; + for(t=0;tdistance) + { + xerr-=distance; + uRow+=incx; + } + if(yerr>distance) + { + yerr-=distance; + uCol+=incy; + } + } +} +//x,y:Բ +//r:Բİ뾶 +void OLED_DrawCircle(u8 x,u8 y,u8 r) +{ + int a, b,num; + a = 0; + b = r; + while(2 * b * b >= r * r) + { + OLED_DrawPoint(x + a, y - b,1); + OLED_DrawPoint(x - a, y - b,1); + OLED_DrawPoint(x - a, y + b,1); + OLED_DrawPoint(x + a, y + b,1); + + OLED_DrawPoint(x + b, y + a,1); + OLED_DrawPoint(x + b, y - a,1); + OLED_DrawPoint(x - b, y - a,1); + OLED_DrawPoint(x - b, y + a,1); + + a++; + num = (a * a + b * b) - r*r;//㻭ĵԲĵľ + if(num > 0) + { + b--; + a--; + } + } +} +void OLED_DrawArc(int rx,int ry,int r, int j) + { + float x, y,i = 0; + float angleInRadians = j * (3.1415926 / 180.0); // ǶתΪ + float startAngle = -angleInRadians / 2.0; // ʼǶȣȣ + float endAngle = angleInRadians / 2.0; // Ƕȣȣ + float increment = (endAngle - startAngle) / 20.0; + for (i = startAngle; i <= angleInRadians; i += increment) { + x = rx + (r * sin(i)); + y = ry - (r * cos(i)); // עYķҪʾ豸 + + OLED_DrawPoint(x, y, 1); // Ƶ㣬WHITEҪʹõɫ + } +} +//ָλʾһַ,ַ +//x:0~127 +//y:0~63 +//size1:ѡ 6x8/6x12/8x16/12x24 +//mode:0,ɫʾ;1,ʾ +void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1,u8 mode) +{ + u8 i,m,temp,size2,chr1; + u8 x0=x,y0=y; + if(size1==8)size2=6; + else size2=(size1/8+((size1%8)?1:0))*(size1/2); //õһַӦռֽ + chr1=chr-' '; //ƫƺֵ + for(i=0;i>=1; + y++; + } + x++; + if((size1!=8)&&((x-x0)==size1/2)) + {x=x0;y0=y0+8;} + y=y0; + } +} + + +//ʾַ +//x,y: +//size1:С +//*chr:ַʼַ +//mode:0,ɫʾ;1,ʾ +void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Maxlen,u8 size1,u8 mode) +{ + while(Maxlen && (*chr>=' ') && (*chr<='~'))//жDzǷǷַ! + { + OLED_ShowChar(x,y,*chr,size1,mode); + if(size1==8)x+=6; + else x+=size1/2; + chr++; + Maxlen --; + } +} +//ʾ +//x,y: +//sizex: +//sizex: +//Num +//mode:0,ɫʾ;1,ʾ +void OLED_ProgressBar(u8 x,u8 y,u8 sizex,u8 sizey,u8 num,u8 mode) +{ + u8 Setp = sizex * num / 100; + u8 i = 0; + OLED_DrawLine(x,y,x+sizex,y,1); + OLED_DrawLine(x,y+sizey,x+sizex,y+sizey,1); + OLED_DrawLine(x,y,x,y+sizey,1); + OLED_DrawLine(x+sizex,y,x+sizex,y+sizey,1); + + for(i = 0;i < sizey;i ++) + { + OLED_DrawLine(x,y+i,x+Setp,y+i,1); + } + } +//m^n +u32 OLED_Pow(u8 m,u8 n) +{ + u32 result=1; + while(n--) + { + result*=m; + } + return result; +} + +//ʾ +//x,y : +//num :Ҫʾ +//len :ֵλ,0ʾӦ +//size:С +//mode:0,ɫʾ;1,ʾ +//u8 OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1,u8 mode) +//{ +// u8 t,temp,m=0; +// if(len == 0) +// len = (int)(log10(num) + 1); +// if(size1==8)m=2; +// for(t=0;t 0) + { + OLED_ShowChar(x, y, '0', size1, mode); + x += (size1 / 2 + m); + } + for(t = 0; t < len+d; t++) + { + if(t == len - Dec) + { // жǷСλ + OLED_ShowChar(x + (size1 / 2 + m) * t, y, '.', size1, mode); // ʾС + d = 1; + continue; + } +// if(t >= len - Dec) +// d = 1; +// else +// d = 0; + temp = (num / OLED_Pow(10, len+d - t - 1)) % 10; + if(temp == 0) + { + OLED_ShowChar(d + x + (size1 / 2 + m) * t, y, '0', size1, mode); + } + else + { + OLED_ShowChar(d + x + (size1 / 2 + m) * t, y, temp + '0', size1, mode); + } + } + return len; +} + +//x,y +//sizex,sizey,ͼƬ +//BMP[]ҪдͼƬ +//mode:0,ɫʾ;1,ʾ +void OLED_ShowPicture(u8 x,u8 y,u8 sizex,u8 sizey,u8 BMP[],u8 mode) +{ + u16 j=0; + u8 i,n,temp,m; + u8 x0=x,y0=y; + sizey=sizey/8+((sizey%8)?1:0); + for(n=0;n>=1; + y++; + } + x++; + if((x-x0)==sizex) + { + x=x0; + y0=y0+8; + } + y=y0; + } + } +} +//OLEDijʼ +void OLED_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOB,ENABLE);//ʹPORTA~E,PORTGʱ + + + //GPIOʼ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//ͨģʽ + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;// + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// + GPIO_Init(GPIOD, &GPIO_InitStructure);//ʼ + + //GPIOʼ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//ͨģʽ + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;// + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// + GPIO_Init(GPIOB, &GPIO_InitStructure);//ʼ + delay_ms(200); + OLED_RES_Clr(); + delay_ms(200); + OLED_RES_Set(); + delay_ms(200); + OLED_WR_Byte(0xFD,OLED_CMD); + OLED_WR_Byte(0x12,OLED_CMD); + OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel + OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency + OLED_WR_Byte(0xA0,OLED_CMD); + OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64) + OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty + OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F) + OLED_WR_Byte(0x00,OLED_CMD);//-not offset + OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F) + if(TXHData.HardwareVersion > 31)//24-31Ǵ壬32-38С + { + OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0ҷ 0xa1 + OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0· 0xc8 + } + else + { + OLED_WR_Byte(0xA0,OLED_CMD);//--Set SEG/Column Mapping 0xa0ҷ 0xa1 + OLED_WR_Byte(0xC0,OLED_CMD);//Set COM/Row Scan Direction 0xc0· 0xc8 + } + OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration + OLED_WR_Byte(0x12,OLED_CMD); + OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register + OLED_WR_Byte(0x7F,OLED_CMD);// Set SEG Output Current Brightness + OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period + OLED_WR_Byte(0x82,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock + OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh + OLED_WR_Byte(0x34,OLED_CMD);//Set VCOM Deselect Level + OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5) + OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) + OLED_WR_Byte(0x20,OLED_CMD); + OLED_WR_Byte(0x00,OLED_CMD); + OLED_Clear(); + OLED_WR_Byte(0xAF,OLED_CMD); + //OLED_ShowPicture(0,0,128,64,BMP1,1); + OLED_Refresh(); +} + + diff --git a/User/OLED/oled.h b/User/OLED/oled.h new file mode 100644 index 0000000..863766c --- /dev/null +++ b/User/OLED/oled.h @@ -0,0 +1,42 @@ +#ifndef __OLED_H +#define __OLED_H + + +//-----------------OLED˿ڶ---------------- + +#define OLED_RES_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_10)//RES +#define OLED_RES_Set() GPIO_SetBits(GPIOB,GPIO_Pin_10) + +#define OLED_DC_Clr() GPIO_ResetBits(GPIOD,GPIO_Pin_11)//DC +#define OLED_DC_Set() GPIO_SetBits(GPIOD,GPIO_Pin_11) + +#define OLED_CS_Clr() GPIO_ResetBits(GPIOD,GPIO_Pin_12);GPIO_SetBits(GPIOB,GPIO_Pin_12); +#define OLED_CS_Set() GPIO_SetBits(GPIOD,GPIO_Pin_12) + + +#define OLED_CMD 0 //д +#define OLED_DATA 1 //д + +void OLED_ClearPoint(u8 x,u8 y); +void OLED_ColorTurn(u8 i); +void OLED_DisplayTurn(u8 i); +void OLED_WR_Byte(u8 dat,u8 mode); +void OLED_DisPlay_On(void); +void OLED_DisPlay_Off(void); +void OLED_Refresh(void); +void OLED_Clear(void); +void OLED_DrawPoint(u8 x,u8 y,u8 t); +void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2,u8 mode); +void OLED_DrawCircle(u8 x,u8 y,u8 r); +void OLED_DrawArc(int rx,int ry,int r, int j) ; +void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1,u8 mode); +void OLED_ShowChar6x8(u8 x,u8 y,u8 chr,u8 mode); +void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Maxlen,u8 size1,u8 mode); +u8 OLED_ShowNum(u8 x, u8 y, u32 num, u8 len, u8 Dec, u8 size1, u8 mode); +void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1,u8 mode); +void OLED_ScrollDisplay(u8 num,u8 space,u8 mode); +void OLED_ShowPicture(u8 x,u8 y,u8 sizex,u8 sizey,u8 BMP[],u8 mode); +void OLED_ProgressBar(u8 x,u8 y,u8 sizex,u8 sizey,u8 num,u8 mode); +void OLED_Init(void); +#endif + diff --git a/User/OLED/oledfont.h b/User/OLED/oledfont.h new file mode 100644 index 0000000..61b2051 --- /dev/null +++ b/User/OLED/oledfont.h @@ -0,0 +1,426 @@ +#ifndef __OLEDFONT_H +#define __OLEDFONT_H +const unsigned char asc2_0806[][6] = +{ +{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// sp +{0x00, 0x00, 0x00, 0x2f, 0x00, 0x00},// ! +{0x00, 0x00, 0x07, 0x00, 0x07, 0x00},// " +{0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14},// # +{0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12},// $ +{0x00, 0x62, 0x64, 0x08, 0x13, 0x23},// % +{0x00, 0x36, 0x49, 0x55, 0x22, 0x50},// & +{0x00, 0x00, 0x05, 0x03, 0x00, 0x00},// ' +{0x00, 0x00, 0x1c, 0x22, 0x41, 0x00},// ( +{0x00, 0x00, 0x41, 0x22, 0x1c, 0x00},// ) +{0x00, 0x14, 0x08, 0x3E, 0x08, 0x14},// * +{0x00, 0x08, 0x08, 0x3E, 0x08, 0x08},// + +{0x00, 0x00, 0x00, 0xA0, 0x60, 0x00},// , +{0x00, 0x08, 0x08, 0x08, 0x08, 0x08},// - +{0x00, 0x00, 0x60, 0x60, 0x00, 0x00},// . +{0x00, 0x20, 0x10, 0x08, 0x04, 0x02},// / +{0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E},// 0 +{0x00, 0x00, 0x42, 0x7F, 0x40, 0x00},// 1 +{0x00, 0x42, 0x61, 0x51, 0x49, 0x46},// 2 +{0x00, 0x21, 0x41, 0x45, 0x4B, 0x31},// 3 +{0x00, 0x18, 0x14, 0x12, 0x7F, 0x10},// 4 +{0x00, 0x27, 0x45, 0x45, 0x45, 0x39},// 5 +{0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30},// 6 +{0x00, 0x01, 0x71, 0x09, 0x05, 0x03},// 7 +{0x00, 0x36, 0x49, 0x49, 0x49, 0x36},// 8 +{0x00, 0x06, 0x49, 0x49, 0x29, 0x1E},// 9 +{0x00, 0x00, 0x36, 0x36, 0x00, 0x00},// : +{0x00, 0x00, 0x56, 0x36, 0x00, 0x00},// ; +{0x00, 0x08, 0x14, 0x22, 0x41, 0x00},// < +{0x00, 0x14, 0x14, 0x14, 0x14, 0x14},// = +{0x00, 0x00, 0x41, 0x22, 0x14, 0x08},// > +{0x00, 0x02, 0x01, 0x51, 0x09, 0x06},// ? +{0x00, 0x32, 0x49, 0x59, 0x51, 0x3E},// @ +{0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C},// A +{0x00, 0x7F, 0x49, 0x49, 0x49, 0x36},// B +{0x00, 0x3E, 0x41, 0x41, 0x41, 0x22},// C +{0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C},// D +{0x00, 0x7F, 0x49, 0x49, 0x49, 0x41},// E +{0x00, 0x7F, 0x09, 0x09, 0x09, 0x01},// F +{0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A},// G +{0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F},// H +{0x00, 0x00, 0x41, 0x7F, 0x41, 0x00},// I +{0x00, 0x20, 0x40, 0x41, 0x3F, 0x01},// J +{0x00, 0x7F, 0x08, 0x14, 0x22, 0x41},// K +{0x00, 0x7F, 0x40, 0x40, 0x40, 0x40},// L +{0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F},// M +{0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F},// N +{0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E},// O +{0x00, 0x7F, 0x09, 0x09, 0x09, 0x06},// P +{0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E},// Q +{0x00, 0x7F, 0x09, 0x19, 0x29, 0x46},// R +{0x00, 0x46, 0x49, 0x49, 0x49, 0x31},// S +{0x00, 0x01, 0x01, 0x7F, 0x01, 0x01},// T +{0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F},// U +{0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F},// V +{0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F},// W +{0x00, 0x63, 0x14, 0x08, 0x14, 0x63},// X +{0x00, 0x07, 0x08, 0x70, 0x08, 0x07},// Y +{0x00, 0x61, 0x51, 0x49, 0x45, 0x43},// Z +{0x00, 0x00, 0x7F, 0x41, 0x41, 0x00},// [ +{0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55},// 55 +{0x00, 0x00, 0x41, 0x41, 0x7F, 0x00},// ] +{0x00, 0x04, 0x02, 0x01, 0x02, 0x04},// ^ +{0x00, 0x40, 0x40, 0x40, 0x40, 0x40},// _ +{0x00, 0x00, 0x01, 0x02, 0x04, 0x00},// ' +{0x00, 0x20, 0x54, 0x54, 0x54, 0x78},// a +{0x00, 0x7F, 0x48, 0x44, 0x44, 0x38},// b +{0x00, 0x38, 0x44, 0x44, 0x44, 0x20},// c +{0x00, 0x38, 0x44, 0x44, 0x48, 0x7F},// d +{0x00, 0x38, 0x54, 0x54, 0x54, 0x18},// e +{0x00, 0x08, 0x7E, 0x09, 0x01, 0x02},// f +{0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C},// g +{0x00, 0x7F, 0x08, 0x04, 0x04, 0x78},// h +{0x00, 0x00, 0x44, 0x7D, 0x40, 0x00},// i +{0x00, 0x40, 0x80, 0x84, 0x7D, 0x00},// j +{0x00, 0x7F, 0x10, 0x28, 0x44, 0x00},// k +{0x00, 0x00, 0x41, 0x7F, 0x40, 0x00},// l +{0x00, 0x7C, 0x04, 0x18, 0x04, 0x78},// m +{0x00, 0x7C, 0x08, 0x04, 0x04, 0x78},// n +{0x00, 0x38, 0x44, 0x44, 0x44, 0x38},// o +{0x00, 0xFC, 0x24, 0x24, 0x24, 0x18},// p +{0x00, 0x18, 0x24, 0x24, 0x18, 0xFC},// q +{0x00, 0x7C, 0x08, 0x04, 0x04, 0x08},// r +{0x00, 0x48, 0x54, 0x54, 0x54, 0x20},// s +{0x00, 0x04, 0x3F, 0x44, 0x40, 0x20},// t +{0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C},// u +{0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C},// v +{0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C},// w +{0x00, 0x44, 0x28, 0x10, 0x28, 0x44},// x +{0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C},// y +{0x00, 0x44, 0x64, 0x54, 0x4C, 0x44},// z +{0x14, 0x14, 0x14, 0x14, 0x14, 0x14},// horiz lines +}; +//12*12 ASCIIַ +const unsigned char asc2_1206[95][12]={ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/ +{0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00},/*"!",1*/ +{0x00,0x0C,0x02,0x0C,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/ +{0x90,0xD0,0xBC,0xD0,0xBC,0x90,0x00,0x03,0x00,0x03,0x00,0x00},/*"#",3*/ +{0x18,0x24,0xFE,0x44,0x8C,0x00,0x03,0x02,0x07,0x02,0x01,0x00},/*"$",4*/ +{0x18,0x24,0xD8,0xB0,0x4C,0x80,0x00,0x03,0x00,0x01,0x02,0x01},/*"%",5*/ +{0xC0,0x38,0xE4,0x38,0xE0,0x00,0x01,0x02,0x02,0x01,0x02,0x02},/*"&",6*/ +{0x08,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/ +{0x00,0x00,0x00,0xF8,0x04,0x02,0x00,0x00,0x00,0x01,0x02,0x04},/*"(",8*/ +{0x00,0x02,0x04,0xF8,0x00,0x00,0x00,0x04,0x02,0x01,0x00,0x00},/*")",9*/ +{0x90,0x60,0xF8,0x60,0x90,0x00,0x00,0x00,0x01,0x00,0x00,0x00},/*"*",10*/ +{0x20,0x20,0xFC,0x20,0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00},/*"+",11*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x06,0x00,0x00,0x00,0x00},/*",",12*/ +{0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"-",13*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00},/*".",14*/ +{0x00,0x80,0x60,0x1C,0x02,0x00,0x04,0x03,0x00,0x00,0x00,0x00},/*"/",15*/ +{0xF8,0x04,0x04,0x04,0xF8,0x00,0x01,0x02,0x02,0x02,0x01,0x00},/*"0",16*/ +{0x00,0x08,0xFC,0x00,0x00,0x00,0x00,0x02,0x03,0x02,0x00,0x00},/*"1",17*/ +{0x18,0x84,0x44,0x24,0x18,0x00,0x03,0x02,0x02,0x02,0x02,0x00},/*"2",18*/ +{0x08,0x04,0x24,0x24,0xD8,0x00,0x01,0x02,0x02,0x02,0x01,0x00},/*"3",19*/ +{0x40,0xB0,0x88,0xFC,0x80,0x00,0x00,0x00,0x00,0x03,0x02,0x00},/*"4",20*/ +{0x3C,0x24,0x24,0x24,0xC4,0x00,0x01,0x02,0x02,0x02,0x01,0x00},/*"5",21*/ +{0xF8,0x24,0x24,0x2C,0xC0,0x00,0x01,0x02,0x02,0x02,0x01,0x00},/*"6",22*/ +{0x0C,0x04,0xE4,0x1C,0x04,0x00,0x00,0x00,0x03,0x00,0x00,0x00},/*"7",23*/ +{0xD8,0x24,0x24,0x24,0xD8,0x00,0x01,0x02,0x02,0x02,0x01,0x00},/*"8",24*/ +{0x38,0x44,0x44,0x44,0xF8,0x00,0x00,0x03,0x02,0x02,0x01,0x00},/*"9",25*/ +{0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00},/*":",26*/ +{0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00},/*";",27*/ +{0x00,0x20,0x50,0x88,0x04,0x02,0x00,0x00,0x00,0x00,0x01,0x02},/*"<",28*/ +{0x90,0x90,0x90,0x90,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"=",29*/ +{0x00,0x02,0x04,0x88,0x50,0x20,0x00,0x02,0x01,0x00,0x00,0x00},/*">",30*/ +{0x18,0x04,0xC4,0x24,0x18,0x00,0x00,0x00,0x02,0x00,0x00,0x00},/*"?",31*/ +{0xF8,0x04,0xE4,0x94,0xF8,0x00,0x01,0x02,0x02,0x02,0x02,0x00},/*"@",32*/ +{0x00,0xE0,0x9C,0xF0,0x80,0x00,0x02,0x03,0x00,0x00,0x03,0x02},/*"A",33*/ +{0x04,0xFC,0x24,0x24,0xD8,0x00,0x02,0x03,0x02,0x02,0x01,0x00},/*"B",34*/ +{0xF8,0x04,0x04,0x04,0x0C,0x00,0x01,0x02,0x02,0x02,0x01,0x00},/*"C",35*/ +{0x04,0xFC,0x04,0x04,0xF8,0x00,0x02,0x03,0x02,0x02,0x01,0x00},/*"D",36*/ +{0x04,0xFC,0x24,0x74,0x0C,0x00,0x02,0x03,0x02,0x02,0x03,0x00},/*"E",37*/ +{0x04,0xFC,0x24,0x74,0x0C,0x00,0x02,0x03,0x02,0x00,0x00,0x00},/*"F",38*/ +{0xF0,0x08,0x04,0x44,0xCC,0x40,0x00,0x01,0x02,0x02,0x01,0x00},/*"G",39*/ +{0x04,0xFC,0x20,0x20,0xFC,0x04,0x02,0x03,0x00,0x00,0x03,0x02},/*"H",40*/ +{0x04,0x04,0xFC,0x04,0x04,0x00,0x02,0x02,0x03,0x02,0x02,0x00},/*"I",41*/ +{0x00,0x04,0x04,0xFC,0x04,0x04,0x06,0x04,0x04,0x03,0x00,0x00},/*"J",42*/ +{0x04,0xFC,0x24,0xD0,0x0C,0x04,0x02,0x03,0x02,0x00,0x03,0x02},/*"K",43*/ +{0x04,0xFC,0x04,0x00,0x00,0x00,0x02,0x03,0x02,0x02,0x02,0x03},/*"L",44*/ +{0xFC,0x3C,0xC0,0x3C,0xFC,0x00,0x03,0x00,0x03,0x00,0x03,0x00},/*"M",45*/ +{0x04,0xFC,0x30,0xC4,0xFC,0x04,0x02,0x03,0x02,0x00,0x03,0x00},/*"N",46*/ +{0xF8,0x04,0x04,0x04,0xF8,0x00,0x01,0x02,0x02,0x02,0x01,0x00},/*"O",47*/ +{0x04,0xFC,0x24,0x24,0x18,0x00,0x02,0x03,0x02,0x00,0x00,0x00},/*"P",48*/ +{0xF8,0x84,0x84,0x04,0xF8,0x00,0x01,0x02,0x02,0x07,0x05,0x00},/*"Q",49*/ +{0x04,0xFC,0x24,0x64,0x98,0x00,0x02,0x03,0x02,0x00,0x03,0x02},/*"R",50*/ +{0x18,0x24,0x24,0x44,0x8C,0x00,0x03,0x02,0x02,0x02,0x01,0x00},/*"S",51*/ +{0x0C,0x04,0xFC,0x04,0x0C,0x00,0x00,0x02,0x03,0x02,0x00,0x00},/*"T",52*/ +{0x04,0xFC,0x00,0x00,0xFC,0x04,0x00,0x01,0x02,0x02,0x01,0x00},/*"U",53*/ +{0x04,0x7C,0x80,0xE0,0x1C,0x04,0x00,0x00,0x03,0x00,0x00,0x00},/*"V",54*/ +{0x1C,0xE0,0x3C,0xE0,0x1C,0x00,0x00,0x03,0x00,0x03,0x00,0x00},/*"W",55*/ +{0x04,0x9C,0x60,0x9C,0x04,0x00,0x02,0x03,0x00,0x03,0x02,0x00},/*"X",56*/ +{0x04,0x1C,0xE0,0x1C,0x04,0x00,0x00,0x02,0x03,0x02,0x00,0x00},/*"Y",57*/ +{0x0C,0x84,0x64,0x1C,0x04,0x00,0x02,0x03,0x02,0x02,0x03,0x00},/*"Z",58*/ +{0x00,0x00,0xFE,0x02,0x02,0x00,0x00,0x00,0x07,0x04,0x04,0x00},/*"[",59*/ +{0x00,0x0E,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x00},/*"\",60*/ +{0x00,0x02,0x02,0xFE,0x00,0x00,0x00,0x04,0x04,0x07,0x00,0x00},/*"]",61*/ +{0x00,0x04,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08},/*"_",63*/ +{0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/ +{0x00,0x40,0xA0,0xA0,0xC0,0x00,0x00,0x01,0x02,0x02,0x03,0x02},/*"a",65*/ +{0x04,0xFC,0x20,0x20,0xC0,0x00,0x00,0x03,0x02,0x02,0x01,0x00},/*"b",66*/ +{0x00,0xC0,0x20,0x20,0x60,0x00,0x00,0x01,0x02,0x02,0x02,0x00},/*"c",67*/ +{0x00,0xC0,0x20,0x24,0xFC,0x00,0x00,0x01,0x02,0x02,0x03,0x02},/*"d",68*/ +{0x00,0xC0,0xA0,0xA0,0xC0,0x00,0x00,0x01,0x02,0x02,0x02,0x00},/*"e",69*/ +{0x00,0x20,0xF8,0x24,0x24,0x04,0x00,0x02,0x03,0x02,0x02,0x00},/*"f",70*/ +{0x00,0x40,0xA0,0xA0,0x60,0x20,0x00,0x07,0x0A,0x0A,0x0A,0x04},/*"g",71*/ +{0x04,0xFC,0x20,0x20,0xC0,0x00,0x02,0x03,0x02,0x00,0x03,0x02},/*"h",72*/ +{0x00,0x20,0xE4,0x00,0x00,0x00,0x00,0x02,0x03,0x02,0x00,0x00},/*"i",73*/ +{0x00,0x00,0x20,0xE4,0x00,0x00,0x08,0x08,0x08,0x07,0x00,0x00},/*"j",74*/ +{0x04,0xFC,0x80,0xE0,0x20,0x20,0x02,0x03,0x02,0x00,0x03,0x02},/*"k",75*/ +{0x04,0x04,0xFC,0x00,0x00,0x00,0x02,0x02,0x03,0x02,0x02,0x00},/*"l",76*/ +{0xE0,0x20,0xE0,0x20,0xC0,0x00,0x03,0x00,0x03,0x00,0x03,0x00},/*"m",77*/ +{0x20,0xE0,0x20,0x20,0xC0,0x00,0x02,0x03,0x02,0x00,0x03,0x02},/*"n",78*/ +{0x00,0xC0,0x20,0x20,0xC0,0x00,0x00,0x01,0x02,0x02,0x01,0x00},/*"o",79*/ +{0x20,0xE0,0x20,0x20,0xC0,0x00,0x08,0x0F,0x0A,0x02,0x01,0x00},/*"p",80*/ +{0x00,0xC0,0x20,0x20,0xE0,0x00,0x00,0x01,0x02,0x0A,0x0F,0x08},/*"q",81*/ +{0x20,0xE0,0x40,0x20,0x20,0x00,0x02,0x03,0x02,0x00,0x00,0x00},/*"r",82*/ +{0x00,0x60,0xA0,0xA0,0x20,0x00,0x00,0x02,0x02,0x02,0x03,0x00},/*"s",83*/ +{0x00,0x20,0xF8,0x20,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x00},/*"t",84*/ +{0x20,0xE0,0x00,0x20,0xE0,0x00,0x00,0x01,0x02,0x02,0x03,0x02},/*"u",85*/ +{0x20,0xE0,0x20,0x80,0x60,0x20,0x00,0x00,0x03,0x01,0x00,0x00},/*"v",86*/ +{0x60,0x80,0xE0,0x80,0x60,0x00,0x00,0x03,0x00,0x03,0x00,0x00},/*"w",87*/ +{0x20,0x60,0x80,0x60,0x20,0x00,0x02,0x03,0x00,0x03,0x02,0x00},/*"x",88*/ +{0x20,0xE0,0x20,0x80,0x60,0x20,0x08,0x08,0x07,0x01,0x00,0x00},/*"y",89*/ +{0x00,0x20,0xA0,0x60,0x20,0x00,0x00,0x02,0x03,0x02,0x02,0x00},/*"z",90*/ +{0x00,0x00,0x20,0xDE,0x02,0x00,0x00,0x00,0x00,0x07,0x04,0x00},/*"{",91*/ +{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00},/*"|",92*/ +{0x00,0x02,0xDE,0x20,0x00,0x00,0x00,0x04,0x07,0x00,0x00,0x00},/*"}",93*/ +{0x02,0x01,0x02,0x04,0x04,0x02,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",94*/ +}; +//16*16 ASCIIַ +const unsigned char asc2_1608[][16]={ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/ +{0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00},/*"!",1*/ +{0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/ +{0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00},/*"#",3*/ +{0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00},/*"$",4*/ +{0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00},/*"%",5*/ +{0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10},/*"&",6*/ +{0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/ +{0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00},/*"(",8*/ +{0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00},/*")",9*/ +{0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00},/*"*",10*/ +{0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00},/*"+",11*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00},/*",",12*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01},/*"-",13*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00},/*".",14*/ +{0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00},/*"/",15*/ +{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00},/*"0",16*/ +{0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},/*"1",17*/ +{0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},/*"2",18*/ +{0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00},/*"3",19*/ +{0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00},/*"4",20*/ +{0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00},/*"5",21*/ +{0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00},/*"6",22*/ +{0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00},/*"7",23*/ +{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},/*"8",24*/ +{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00},/*"9",25*/ +{0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00},/*":",26*/ +{0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00},/*";",27*/ +{0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00},/*"<",28*/ +{0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00},/*"=",29*/ +{0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00},/*">",30*/ +{0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00},/*"?",31*/ +{0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00},/*"@",32*/ +{0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20},/*"A",33*/ +{0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00},/*"B",34*/ +{0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00},/*"C",35*/ +{0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00},/*"D",36*/ +{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00},/*"E",37*/ +{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00},/*"F",38*/ +{0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00},/*"G",39*/ +{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20},/*"H",40*/ +{0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},/*"I",41*/ +{0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00},/*"J",42*/ +{0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00},/*"K",43*/ +{0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00},/*"L",44*/ +{0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00},/*"M",45*/ +{0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00},/*"N",46*/ +{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00},/*"O",47*/ +{0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00},/*"P",48*/ +{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00},/*"Q",49*/ +{0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20},/*"R",50*/ +{0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00},/*"S",51*/ +{0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},/*"T",52*/ +{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},/*"U",53*/ +{0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00},/*"V",54*/ +{0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00},/*"W",55*/ +{0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20},/*"X",56*/ +{0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},/*"Y",57*/ +{0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00},/*"Z",58*/ +{0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00},/*"[",59*/ +{0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00},/*"\",60*/ +{0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00},/*"]",61*/ +{0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80},/*"_",63*/ +{0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/ +{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20},/*"a",65*/ +{0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00},/*"b",66*/ +{0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00},/*"c",67*/ +{0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20},/*"d",68*/ +{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00},/*"e",69*/ +{0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},/*"f",70*/ +{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00},/*"g",71*/ +{0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},/*"h",72*/ +{0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},/*"i",73*/ +{0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00},/*"j",74*/ +{0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00},/*"k",75*/ +{0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},/*"l",76*/ +{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F},/*"m",77*/ +{0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},/*"n",78*/ +{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},/*"o",79*/ +{0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00},/*"p",80*/ +{0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80},/*"q",81*/ +{0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00},/*"r",82*/ +{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00},/*"s",83*/ +{0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00},/*"t",84*/ +{0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20},/*"u",85*/ +{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00},/*"v",86*/ +{0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00},/*"w",87*/ +{0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00},/*"x",88*/ +{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00},/*"y",89*/ +{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00},/*"z",90*/ +{0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40},/*"{",91*/ +{0x08,0x04,0xFE,0x04,0x08,0xC0,0x00,0x00,0x00,0x00,0x03,0x10,0x20,0x7F,0x20,0x10},/*"|",92*/ +{0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00},/*"}",93*/ +{0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",94*/ +}; +//24*24 ASICIIַ +const unsigned char asc2_2412[][36]={ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/ +{0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x7F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00},/*"!",1*/ +{0x00,0x00,0x80,0x60,0x30,0x1C,0x8C,0x60,0x30,0x1C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/ +{0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x86,0xE6,0x9F,0x86,0x86,0x86,0x86,0xE6,0x9F,0x86,0x00,0x00,0x01,0x1F,0x01,0x01,0x01,0x01,0x01,0x1F,0x01,0x01,0x00},/*"#",3*/ +{0x00,0x00,0x80,0xC0,0x60,0x20,0xF8,0x20,0xE0,0xC0,0x00,0x00,0x00,0x00,0x03,0x07,0x0C,0x18,0xFF,0x70,0xE1,0x81,0x00,0x00,0x00,0x00,0x07,0x0F,0x10,0x10,0x7F,0x10,0x0F,0x07,0x00,0x00},/*"$",4*/ +{0x80,0x60,0x20,0x60,0x80,0x00,0x00,0x00,0xE0,0x20,0x00,0x00,0x0F,0x30,0x20,0x30,0x9F,0x70,0xDC,0x37,0x10,0x30,0xC0,0x00,0x00,0x00,0x10,0x0E,0x03,0x00,0x07,0x18,0x10,0x18,0x07,0x00},/*"%",5*/ +{0x00,0x00,0xC0,0x20,0x20,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0x1F,0x38,0xE8,0x87,0x03,0xC4,0x3C,0x04,0x00,0x00,0x07,0x0F,0x18,0x10,0x10,0x0B,0x07,0x0D,0x10,0x10,0x08,0x00},/*"&",6*/ +{0x00,0x80,0x8C,0x4C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0x30,0x08,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x18,0x20,0x40,0x00},/*"(",8*/ +{0x00,0x04,0x08,0x30,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x66,0x66,0x3C,0x18,0xFF,0x18,0x3C,0x66,0x66,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00},/*"*",10*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00},/*"+",11*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x8C,0x4C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"-",13*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x38,0x0C,0x00,0x00,0x00,0x00,0x00,0x80,0x70,0x1C,0x03,0x00,0x00,0x00,0x00,0x00,0x60,0x38,0x0E,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"/",15*/ +{0x00,0x00,0x80,0xC0,0x60,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0xFE,0xFF,0x01,0x00,0x00,0x00,0x00,0x01,0xFF,0xFE,0x00,0x00,0x01,0x07,0x0E,0x18,0x10,0x10,0x18,0x0E,0x07,0x01,0x00},/*"0",16*/ +{0x00,0x00,0x80,0x80,0x80,0xC0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00},/*"1",17*/ +{0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0x03,0x03,0x00,0x80,0x40,0x20,0x38,0x1F,0x07,0x00,0x00,0x00,0x1C,0x1A,0x19,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00},/*"2",18*/ +{0x00,0x80,0xC0,0x20,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x10,0x10,0x18,0x2F,0xE7,0x80,0x00,0x00,0x00,0x07,0x0F,0x10,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00},/*"3",19*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0xF0,0x00,0x00,0x00,0x00,0xC0,0xB0,0x88,0x86,0x81,0x80,0xFF,0xFF,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x1F,0x1F,0x10,0x10,0x00},/*"4",20*/ +{0x00,0x00,0xE0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x3F,0x10,0x08,0x08,0x08,0x18,0xF0,0xE0,0x00,0x00,0x00,0x07,0x0B,0x10,0x10,0x10,0x10,0x1C,0x0F,0x03,0x00,0x00},/*"5",21*/ +{0x00,0x00,0x80,0xC0,0x40,0x20,0x20,0x20,0xE0,0xC0,0x00,0x00,0x00,0xFC,0xFF,0x21,0x10,0x08,0x08,0x08,0x18,0xF0,0xE0,0x00,0x00,0x01,0x07,0x0C,0x18,0x10,0x10,0x10,0x08,0x0F,0x03,0x00},/*"6",22*/ +{0x00,0x00,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0x60,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0xE0,0x18,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00},/*"7",23*/ +{0x00,0x80,0xC0,0x60,0x20,0x20,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0x87,0xEF,0x2C,0x18,0x18,0x30,0x30,0x68,0xCF,0x83,0x00,0x00,0x07,0x0F,0x08,0x10,0x10,0x10,0x10,0x18,0x0F,0x07,0x00},/*"8",24*/ +{0x00,0x00,0xC0,0xC0,0x20,0x20,0x20,0x20,0xC0,0x80,0x00,0x00,0x00,0x1F,0x3F,0x60,0x40,0x40,0x40,0x20,0x10,0xFF,0xFE,0x00,0x00,0x00,0x0C,0x1C,0x10,0x10,0x10,0x08,0x0F,0x03,0x00,0x00},/*"9",25*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00},/*":",26*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x38,0x00,0x00,0x00,0x00,0x00},/*";",27*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x00,0x00,0x00,0x10,0x28,0x44,0x82,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x00},/*"<",28*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"=",29*/ +{0x00,0x00,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x82,0x44,0x28,0x10,0x00,0x00,0x00,0x10,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00},/*">",30*/ +{0x00,0xC0,0x20,0x20,0x10,0x10,0x10,0x10,0x30,0xE0,0xC0,0x00,0x00,0x03,0x03,0x00,0x00,0xF0,0x10,0x08,0x0C,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00},/*"?",31*/ +{0x00,0x00,0x00,0xC0,0x40,0x60,0x20,0x20,0x20,0x40,0xC0,0x00,0x00,0xFC,0xFF,0x01,0xF0,0x0E,0x03,0xC1,0xFE,0x03,0x80,0x7F,0x00,0x01,0x07,0x0E,0x08,0x11,0x11,0x10,0x11,0x09,0x04,0x02},/*"@",32*/ +{0x00,0x00,0x00,0x00,0x80,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x7C,0x43,0x40,0x47,0x7F,0xF8,0x80,0x00,0x00,0x10,0x18,0x1F,0x10,0x00,0x00,0x00,0x00,0x13,0x1F,0x1C,0x10},/*"A",33*/ +{0x20,0xE0,0xE0,0x20,0x20,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0xFF,0xFF,0x10,0x10,0x10,0x10,0x18,0x2F,0xE7,0x80,0x00,0x10,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x18,0x0F,0x07,0x00},/*"B",34*/ +{0x00,0x00,0x80,0xC0,0x40,0x20,0x20,0x20,0x20,0x60,0xE0,0x00,0x00,0xFC,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x07,0x0E,0x18,0x10,0x10,0x10,0x08,0x04,0x03,0x00},/*"C",35*/ +{0x20,0xE0,0xE0,0x20,0x20,0x20,0x20,0x40,0xC0,0x80,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xFE,0x00,0x10,0x1F,0x1F,0x10,0x10,0x10,0x18,0x08,0x0E,0x07,0x01,0x00},/*"D",36*/ +{0x20,0xE0,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0x80,0x00,0x00,0xFF,0xFF,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,0x00,0x00,0x10,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x06,0x00},/*"E",37*/ +{0x20,0xE0,0xE0,0x20,0x20,0x20,0x20,0x20,0x60,0x60,0x80,0x00,0x00,0xFF,0xFF,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,0x01,0x00,0x10,0x1F,0x1F,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"F",38*/ +{0x00,0x00,0x80,0xC0,0x60,0x20,0x20,0x20,0x40,0xE0,0x00,0x00,0x00,0xFC,0xFF,0x01,0x00,0x00,0x40,0x40,0xC0,0xC1,0x40,0x40,0x00,0x01,0x07,0x0E,0x18,0x10,0x10,0x10,0x0F,0x0F,0x00,0x00},/*"G",39*/ +{0x20,0xE0,0xE0,0x20,0x00,0x00,0x00,0x00,0x20,0xE0,0xE0,0x20,0x00,0xFF,0xFF,0x10,0x10,0x10,0x10,0x10,0x10,0xFF,0xFF,0x00,0x10,0x1F,0x1F,0x10,0x00,0x00,0x00,0x00,0x10,0x1F,0x1F,0x10},/*"H",40*/ +{0x00,0x00,0x20,0x20,0x20,0xE0,0xE0,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00},/*"I",41*/ +{0x00,0x00,0x00,0x00,0x20,0x20,0x20,0xE0,0xE0,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x60,0xE0,0x80,0x80,0x80,0xC0,0x7F,0x3F,0x00,0x00,0x00},/*"J",42*/ +{0x20,0xE0,0xE0,0x20,0x00,0x00,0x20,0xA0,0x60,0x20,0x20,0x00,0x00,0xFF,0xFF,0x30,0x18,0x7C,0xE3,0xC0,0x00,0x00,0x00,0x00,0x10,0x1F,0x1F,0x10,0x00,0x00,0x01,0x13,0x1F,0x1C,0x18,0x10},/*"K",43*/ +{0x20,0xE0,0xE0,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x06,0x00},/*"L",44*/ +{0x20,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0xE0,0xE0,0xE0,0x20,0x00,0xFF,0x01,0x3F,0xFE,0xC0,0xE0,0x1E,0x01,0xFF,0xFF,0x00,0x10,0x1F,0x10,0x00,0x03,0x1F,0x03,0x00,0x10,0x1F,0x1F,0x10},/*"M",45*/ +{0x20,0xE0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x20,0xE0,0x20,0x00,0xFF,0x00,0x03,0x07,0x1C,0x78,0xE0,0x80,0x00,0xFF,0x00,0x10,0x1F,0x10,0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x1F,0x00},/*"N",46*/ +{0x00,0x00,0x80,0xC0,0x60,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0xFE,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x00,0x01,0x07,0x0E,0x18,0x10,0x10,0x18,0x0C,0x07,0x01,0x00},/*"O",47*/ +{0x20,0xE0,0xE0,0x20,0x20,0x20,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0xFF,0xFF,0x20,0x20,0x20,0x20,0x20,0x30,0x1F,0x0F,0x00,0x10,0x1F,0x1F,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"P",48*/ +{0x00,0x00,0x80,0xC0,0x60,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0xFE,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x00,0x01,0x07,0x0E,0x11,0x11,0x13,0x3C,0x7C,0x67,0x21,0x00},/*"Q",49*/ +{0x20,0xE0,0xE0,0x20,0x20,0x20,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0xFF,0xFF,0x10,0x10,0x30,0xF0,0xD0,0x08,0x0F,0x07,0x00,0x10,0x1F,0x1F,0x10,0x00,0x00,0x00,0x03,0x0F,0x1C,0x10,0x10},/*"R",50*/ +{0x00,0x80,0xC0,0x60,0x20,0x20,0x20,0x20,0x40,0x40,0xE0,0x00,0x00,0x07,0x0F,0x0C,0x18,0x18,0x30,0x30,0x60,0xE0,0x81,0x00,0x00,0x1F,0x0C,0x08,0x10,0x10,0x10,0x10,0x18,0x0F,0x07,0x00},/*"S",51*/ +{0x80,0x60,0x20,0x20,0x20,0xE0,0xE0,0x20,0x20,0x20,0x60,0x80,0x01,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x1F,0x1F,0x10,0x00,0x00,0x00,0x00},/*"T",52*/ +{0x20,0xE0,0xE0,0x20,0x00,0x00,0x00,0x00,0x00,0x20,0xE0,0x20,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x07,0x0F,0x18,0x10,0x10,0x10,0x10,0x10,0x08,0x07,0x00},/*"U",53*/ +{0x20,0x60,0xE0,0xE0,0x20,0x00,0x00,0x00,0x20,0xE0,0x60,0x20,0x00,0x00,0x07,0x7F,0xF8,0x80,0x00,0x80,0x7C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x1F,0x1C,0x07,0x00,0x00,0x00,0x00},/*"V",54*/ +{0x20,0xE0,0xE0,0x20,0x00,0xE0,0xE0,0x20,0x00,0x20,0xE0,0x20,0x00,0x07,0xFF,0xF8,0xE0,0x1F,0xFF,0xFC,0xE0,0x1F,0x00,0x00,0x00,0x00,0x03,0x1F,0x03,0x00,0x01,0x1F,0x03,0x00,0x00,0x00},/*"W",55*/ +{0x00,0x20,0x60,0xE0,0xA0,0x00,0x00,0x20,0xE0,0x60,0x20,0x00,0x00,0x00,0x00,0x03,0x8F,0x7C,0xF8,0xC6,0x01,0x00,0x00,0x00,0x00,0x10,0x18,0x1E,0x13,0x00,0x01,0x17,0x1F,0x18,0x10,0x00},/*"X",56*/ +{0x20,0x60,0xE0,0xE0,0x20,0x00,0x00,0x00,0x20,0xE0,0x60,0x20,0x00,0x00,0x01,0x07,0x3E,0xF8,0xE0,0x18,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x1F,0x1F,0x10,0x10,0x00,0x00,0x00},/*"Y",57*/ +{0x00,0x80,0x60,0x20,0x20,0x20,0x20,0xA0,0xE0,0xE0,0x20,0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0x3E,0x0F,0x03,0x00,0x00,0x00,0x00,0x10,0x1C,0x1F,0x17,0x10,0x10,0x10,0x10,0x18,0x06,0x00},/*"Z",58*/ +{0x00,0x00,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x40,0x40,0x00},/*"[",59*/ +{0x00,0x00,0x10,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x1C,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x70,0x80,0x00},/*"\",60*/ +{0x00,0x00,0x04,0x04,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,0x00},/*"]",61*/ +{0x00,0x00,0x00,0x10,0x08,0x0C,0x04,0x0C,0x08,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80},/*"_",63*/ +{0x00,0x00,0x00,0x04,0x04,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0xD8,0x44,0x64,0x24,0x24,0xFC,0xF8,0x00,0x00,0x00,0x0F,0x1F,0x18,0x10,0x10,0x10,0x08,0x1F,0x1F,0x10,0x18},/*"a",65*/ +{0x00,0x20,0xE0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x18,0x08,0x04,0x04,0x0C,0xF8,0xF0,0x00,0x00,0x00,0x1F,0x0F,0x18,0x10,0x10,0x10,0x18,0x0F,0x03,0x00},/*"b",66*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xF8,0x18,0x04,0x04,0x04,0x3C,0x38,0x00,0x00,0x00,0x00,0x03,0x0F,0x0C,0x10,0x10,0x10,0x10,0x08,0x06,0x00,0x00},/*"c",67*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xE0,0xF0,0x00,0x00,0x00,0xE0,0xF8,0x1C,0x04,0x04,0x04,0x08,0xFF,0xFF,0x00,0x00,0x00,0x03,0x0F,0x18,0x10,0x10,0x10,0x08,0x1F,0x0F,0x08,0x00},/*"d",68*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xF8,0x48,0x44,0x44,0x44,0x4C,0x78,0x70,0x00,0x00,0x00,0x03,0x0F,0x0C,0x18,0x10,0x10,0x10,0x08,0x04,0x00},/*"e",69*/ +{0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0x20,0x20,0xE0,0xC0,0x00,0x00,0x04,0x04,0x04,0xFF,0xFF,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00,0x00},/*"f",70*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xF8,0x8C,0x04,0x04,0x8C,0xF8,0x74,0x04,0x0C,0x00,0x70,0x76,0xCF,0x8D,0x8D,0x8D,0x89,0xC8,0x78,0x70,0x00},/*"g",71*/ +{0x00,0x20,0xE0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x08,0x04,0x04,0x04,0xFC,0xF8,0x00,0x00,0x00,0x10,0x1F,0x1F,0x10,0x00,0x00,0x10,0x1F,0x1F,0x10,0x00},/*"h",72*/ +{0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00},/*"i",73*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x80,0x80,0xC0,0x7F,0x3F,0x00,0x00,0x00},/*"j",74*/ +{0x00,0x20,0xE0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x80,0xC0,0xF4,0x1C,0x04,0x04,0x00,0x00,0x00,0x10,0x1F,0x1F,0x11,0x00,0x03,0x1F,0x1C,0x10,0x10,0x00},/*"k",75*/ +{0x00,0x00,0x20,0x20,0x20,0xE0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00},/*"l",76*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xFC,0xFC,0x08,0x04,0xFC,0xFC,0x08,0x04,0xFC,0xFC,0x00,0x10,0x1F,0x1F,0x10,0x00,0x1F,0x1F,0x10,0x00,0x1F,0x1F,0x10},/*"m",77*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xFC,0xFC,0x08,0x08,0x04,0x04,0xFC,0xF8,0x00,0x00,0x00,0x10,0x1F,0x1F,0x10,0x00,0x00,0x10,0x1F,0x1F,0x10,0x00},/*"n",78*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xF0,0x18,0x0C,0x04,0x04,0x0C,0x18,0xF0,0xE0,0x00,0x00,0x03,0x0F,0x0C,0x10,0x10,0x10,0x10,0x0C,0x0F,0x03,0x00},/*"o",79*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xFC,0xFC,0x08,0x04,0x04,0x04,0x0C,0xF8,0xF0,0x00,0x00,0x80,0xFF,0xFF,0x88,0x90,0x10,0x10,0x1C,0x0F,0x03,0x00},/*"p",80*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xF8,0x1C,0x04,0x04,0x04,0x08,0xF8,0xFC,0x00,0x00,0x00,0x03,0x0F,0x18,0x10,0x10,0x90,0x88,0xFF,0xFF,0x80,0x00},/*"q",81*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0xFC,0xFC,0x10,0x08,0x04,0x04,0x0C,0x0C,0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00,0x00,0x00},/*"r",82*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x78,0xCC,0xC4,0x84,0x84,0x84,0x0C,0x1C,0x00,0x00,0x00,0x1E,0x18,0x10,0x10,0x10,0x11,0x19,0x0F,0x06,0x00},/*"s",83*/ +{0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0xFF,0xFF,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x1F,0x10,0x10,0x10,0x0C,0x00,0x00},/*"t",84*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xFC,0xFE,0x00,0x00,0x00,0x04,0xFC,0xFE,0x00,0x00,0x00,0x00,0x0F,0x1F,0x18,0x10,0x10,0x08,0x1F,0x0F,0x08,0x00},/*"u",85*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0C,0x3C,0xFC,0xC4,0x00,0x00,0xC4,0x3C,0x0C,0x04,0x00,0x00,0x00,0x00,0x01,0x0F,0x1E,0x0E,0x01,0x00,0x00,0x00},/*"v",86*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x3C,0xFC,0xC4,0x00,0xE4,0x7C,0xFC,0x84,0x80,0x7C,0x04,0x00,0x00,0x07,0x1F,0x07,0x00,0x00,0x07,0x1F,0x07,0x00,0x00},/*"w",87*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x1C,0x7C,0xE4,0xC0,0x34,0x1C,0x04,0x04,0x00,0x00,0x10,0x10,0x1C,0x16,0x01,0x13,0x1F,0x1C,0x18,0x10,0x00},/*"x",88*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0C,0x3C,0xFC,0xC4,0x00,0xC4,0x3C,0x04,0x04,0x00,0x00,0x00,0xC0,0x80,0xC1,0x37,0x0E,0x01,0x00,0x00,0x00,0x00},/*"y",89*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x04,0x04,0xC4,0xF4,0x7C,0x1C,0x04,0x00,0x00,0x00,0x00,0x10,0x1C,0x1F,0x17,0x11,0x10,0x10,0x18,0x0E,0x00},/*"z",90*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0C,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x28,0xEF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x60,0x40,0x00,0x00},/*"{",91*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00},/*"|",92*/ +{0x00,0x00,0x04,0x0C,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEF,0x28,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x60,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/ +{0x00,0x18,0x06,0x02,0x02,0x04,0x08,0x10,0x20,0x20,0x30,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",94*/ + + + +}; +const unsigned char Hzk1[][32]={ +{0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00,0x00,0x00,0x0F,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x0F,0x00,0x00,0x00},/*"",0*/ +{0x40,0x40,0x40,0x5F,0x55,0x55,0x55,0x75,0x55,0x55,0x55,0x5F,0x40,0x40,0x40,0x00,0x00,0x40,0x20,0x0F,0x09,0x49,0x89,0x79,0x09,0x09,0x09,0x0F,0x20,0x40,0x00,0x00},/*"",1*/ +{0x00,0xFE,0x02,0x42,0x4A,0xCA,0x4A,0x4A,0xCA,0x4A,0x4A,0x42,0x02,0xFE,0x00,0x00,0x00,0xFF,0x40,0x50,0x4C,0x43,0x40,0x40,0x4F,0x50,0x50,0x5C,0x40,0xFF,0x00,0x00},/*"԰",2*/ +{0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0xF8,0x00,0x00,0x00,0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x7F,0x88,0x88,0x88,0x88,0x9F,0x80,0xF0,0x00},/*"",3*/ +{0x80,0x82,0x82,0x82,0x82,0x82,0x82,0xE2,0xA2,0x92,0x8A,0x86,0x82,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"",4*/ +{0x10,0x10,0x10,0xFF,0x10,0x90,0x08,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x08,0x00,0x04,0x44,0x82,0x7F,0x01,0x80,0x80,0x40,0x43,0x2C,0x10,0x28,0x46,0x81,0x80,0x00},/*"",5*/ +{0x00,0x10,0x10,0x10,0x10,0xD0,0x30,0xFF,0x30,0xD0,0x12,0x1C,0x10,0x10,0x00,0x00,0x10,0x08,0x04,0x02,0x01,0x00,0x00,0xFF,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x00},/*"",6*/ +{0x04,0x04,0x04,0x84,0xE4,0x3C,0x27,0x24,0x24,0x24,0x24,0xE4,0x04,0x04,0x04,0x00,0x04,0x02,0x01,0x00,0xFF,0x09,0x09,0x09,0x09,0x49,0x89,0x7F,0x00,0x00,0x00,0x00},/*"",7*/ +{0x00,0xFE,0x22,0x5A,0x86,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,0x00,0xFF,0x04,0x08,0x07,0x00,0xFF,0x40,0x20,0x03,0x0C,0x14,0x22,0x41,0x40,0x00},/*"",8*/ +{0x00,0x80,0x40,0x20,0x18,0x06,0x80,0x00,0x07,0x18,0x20,0x40,0x80,0x00,0x00,0x00,0x01,0x00,0x20,0x70,0x28,0x26,0x21,0x20,0x20,0x24,0x38,0x60,0x00,0x01,0x01,0x00},/*"",9*/ +{0x00,0x10,0x12,0x92,0x92,0x92,0x92,0x92,0x92,0x12,0x12,0x02,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x10,0x10,0x10,0x10,0x3F,0x00,0x40,0x80,0x7F,0x00,0x00,0x00},/*"˾",10*/ + + + +}; +const unsigned char Hzk2[][72]={ +{0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFC,0x84,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"",0*/ + +}; +const unsigned char Hzk3[][128]={ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFF,0xFF,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0xFF,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"",0*/ + + +}; + +const unsigned char Hzk4[][512]={ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0xF0,0xF0,0x70,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFE,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0xFF,0xFF,0xFF,0xFF,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0xFF,0xFF,0xFF,0xFF,0x07,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0xFF,0xFF,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"",0*/ + +}; +#endif + diff --git a/User/POS_Connect/POS_Connect.c b/User/POS_Connect/POS_Connect.c new file mode 100644 index 0000000..7d43a13 --- /dev/null +++ b/User/POS_Connect/POS_Connect.c @@ -0,0 +1,3615 @@ +/*C***************************************************************************** + * NAME: .c + *------------------------------------------------------------------------------- + * RELEASE: + * REVISION: 1.0 + *------------------------------------------------------------------------------- + * PURPOSE: + * + *******************************************************************************/ + +/*_____ I N C L U D E S ______________________________________________________*/ + +#include "config.h" //ȫ + +/*_____ M A C R O S __________________________________________________________*/ +const char TsatURL[] = "AT+SOCKA=TCP,test.joyfueling.com,7011\r\n"; +/*_____ D E F I N I T I O N ___________________AT+ GPSDTTY=type_______________________________*/ +const char CMD_LinkMode[] = "AT+WKMOD=NET\r\n"; +const char CMD_UARTFL[] = "AT+UARTFL=4096\r\n"; +const char CMD_HEARTEN[] = "AT+HEARTEN=OFF\r\n"; +const char CMD_Save[] = "AT+S\r\n"; +const char CMD_ATRec[] = "AT+E=OFF\r\n"; +const char CMD_Model_Set[] = "usr.cn#"; +const char CMD_Model_Set_1[] = "+++"; +const char CMD_Model_Set_2[] = "a"; +const char CMD_Model_NET[] = "AT+ENTM\r\n"; +const char CMD_ICCID[] = "AT+ICCID?\r\n"; +const char CMD_IMEI[] = "AT+IMEI?\r\n"; +const char CMD_CSQ[] = "AT+CSQ?\r\n"; +char CMD_APN[50] = "AT+APN="; +const char NextStr[] = "\r\n\0"; + +/***********************USR-K3*************************/ +const char WlanTsatURL[] = "AT+SOCKB1=TCPC,test.joyfueling.com,7011\r\n"; +const char CMD_Reset[] = "AT+Z\r\n"; +const char CMD_DHCP[] = "AT+WANN=DHCP\r\n"; +const char CMD_GetIP[] = "AT+WANN\r\n"; +const char CMD_GetLinkState[] = "AT+SOCKLKB1\r\n"; +/***********************WIFI*************************/ +const char CMD_WifiWSSSID[] = "AT+WIFI=KFB-2.4G,KFB123456\r\n"; +const char CMD_WifiWSSSID_WIFIStation[] = "AT+WIFI=THX-HD4-2.4,KFB123456\r\n"; +const char CMD_WifiSOCKET[] = "AT+Socket=0,0,test.joyfueling.com,7011\r\n"; +const char CMD_WifiSOCKET_WIFIStation[] = "AT+Socket=0,0,192.168.14.100,7011\r\n"; +const char CMD_WifiRSSI[] = "AT+CWJAP?\r\n"; +const char CMD_WifiRST[] = "AT+RES\r\n"; +/*******************************L510ָ*****************************/ +const char CMD_L510_AT[] = "+++"; // رջ +const char CMD_L510_ATRec[] = "ATE0\r\n"; // رջ 192.168.50.206 +const char CMD_L510_IMEI[] = "AT+CGSN\r\n"; // ȡIMEI +const char CMD_L510_ICPIN[] = "AT+CPIN?\r\n"; // Ƿʶ𵽿 +const char CMD_L510_ICCID[] = "AT+ICCID\r\n"; // ȡIMEI +const char CMD_L510_RSSI[] = "AT+CSQ\r\n"; // ȡźǿ (1-31) +const char CMD_L510_Model_NET[] = "AT+CIPMODE=1\r\n"; // ͸ģʽ +const char CMD_L510_APN[] = "AT+QICSGP=1,1,\"CMNET\",\"\",\"\"\r\n"; +const char CMD_L510_NETOPEN[] = "AT+NETOPEN\r\n"; +const char CMD_L510_SOCKET[] = "AT+CIPOPEN=0,\"TCP\",\"test.joyfueling.com\",7011\r\n"; +const char CMD_L510_GetLinkState[] = "AT+CIPOPQUERY?\r\n"; +const char CMD_L510_RESET[] = "AT+RESET\r\n"; +const char CMD_L510_SetGPSMode[] = "AT+GETGPS=GNRMC,0\r\n"; +const char CMD_L510_GetGPS[] = "AT+MGPSC=1\r\n"; + +volatile u8 POS_Connect_TX_Buff[2000] = {0, 1, 2, 3, 4, 5, 6, 7}; // ݷͻ +volatile u8 POS_Connect_RX_Buff[2000]; +volatile u8 POS2MD_Buff[2000]; // posĻظתӵwifiӻ +volatile u8 POS_Connect_TX_Flag = 1; // б־ +typedef struct OperCodeStr +{ + char Country[64]; // ڹ + char Str[64]; // Ӫ + char ICCID[10]; // ICCIDǰ7λ + char APN[64]; // Ӫ̶ӦAPN +} OperCodeStrType; + +const OperCodeStrType Operators[] = + { + {"Ĭ", "default", "890000", "internet"}, + {"й", "ChinaMobile", "898600", "CMNET"}, + {"й", "ChinaMobile", "898602", "CMNET"}, + {"й", "ChinaMobile", "898604", "CMNET"}, + {"й", "ChinaTelecom", "898607", "CMNET"}, + {"й", "ChinaUnicom", "898601", "UNINET"}, + {"й", "ChinaUnicom", "898606", "UNINET"}, + {"й", "ChinaUnicom", "898609", "UNINET"}, + {"й", "ChinaTelecom", "898603", "CTNET"}, + {"й", "ChinaTelecom", "898611", "CTNET"}, + + {"ɳ", "STC", "8996601", "jawalnet.com.sa"}, + + {"", "STC", "8996504", "VIVA"}, + {"", "Ooredoo", "8996503", "Action.ooredoo.com"}, + {"", "zain", "899659", "HSPPS"}, + + {"̩", "AIS", "89660", "internet"}, + + {"", "Vietna", "898405", "Metfone"}, + {"", "Mobifone", "898401", "smart"}, + {"", "Viettel", "898404", "smart"}, + {"", "VINA", "898402", "smart"}, + + {"կ", "Metfone", "8985508", "Metfone"}, + {"կ", "Smart", "8985502", "smart"}, + {"կ", "Smart", "8985505", "smart"}, + {"կ", "Smart", "8985506", "smart"}, + + {"ϼ", "Bobi", "898800", "internet"}, + {"ϼ", "Grameenphone", "898801", "gpinternet"}, + {"ϼ", "Banglalink", "898803", "blweb"}, + + {"ӡ", "Airtel", "899100", "airtelgprs.com"}, + {"ӡ", "Airtel", "899110", "airtelgprs.com"}, + {"ӡ", "Airtel", "899131", "airtelgprs.com"}, + {"ӡ", "Airtel", "899140", "airtelgprs.com"}, + {"ӡ", "Airtel", "899145", "airtelgprs.com"}, + {"ӡ", "Airtel", "899149", "airtelgprs.com"}, + {"ӡ", "Airtel", "899151", "airtelgprs.com"}, + {"ӡ", "Airtel", "899152", "airtelgprs.com"}, + {"ӡ", "Airtel", "899153", "airtelgprs.com"}, + {"ӡ", "Airtel", "899154", "airtelgprs.com"}, + {"ӡ", "Airtel", "899155", "airtelgprs.com"}, + {"ӡ", "Airtel", "899156", "airtelgprs.com"}, + {"ӡ", "Airtel", "899190", "airtelgprs.com"}, + {"ӡ", "Airtel", "899192", "airtelgprs.com"}, + {"ӡ", "Airtel", "899193", "airtelgprs.com"}, + {"ӡ", "Airtel", "899194", "airtelgprs.com"}, + {"ӡ", "Airtel", "899195", "airtelgprs.com"}, + {"ӡ", "Airtel", "899196", "airtelgprs.com"}, + {"ӡ", "Airtel", "899197", "airtelgprs.com"}, + {"ӡ", "Airtel", "899198", "airtelgprs.com"}, + {"ӡ", "Airtel", "899102", "airtelgprs.com"}, + {"ӡ", "Airtel", "899103", "airtelgprs.com"}, + + {"ӡ", "Idea", "899189", "airtelgprs.com"}, + {"ӡ", "Idea", "8991799", "airtelgprs.com"}, + {"ӡ", "Idea", "8991845", "airtelgprs.com"}, + {"ӡ", "Idea", "8991846", "airtelgprs.com"}, + {"ӡ", "Idea", "8991848", "airtelgprs.com"}, + {"ӡ", "Idea", "8991849", "airtelgprs.com"}, + {"ӡ", "Idea", "8991850", "airtelgprs.com"}, + {"ӡ", "Idea", "8991852", "airtelgprs.com"}, + {"ӡ", "Idea", "8991853", "airtelgprs.com"}, + {"ӡ", "Idea", "899104", "airtelgprs.com"}, + {"ӡ", "Idea", "899107", "airtelgprs.com"}, + {"ӡ", "Idea", "899112", "airtelgprs.com"}, + {"ӡ", "Idea", "899114", "airtelgprs.com"}, + {"ӡ", "Idea", "899119", "airtelgprs.com"}, + {"ӡ", "Idea", "899122", "airtelgprs.com"}, + {"ӡ", "Idea", "899124", "airtelgprs.com"}, + {"ӡ", "Idea", "899144", "airtelgprs.com"}, + {"ӡ", "Idea", "899156", "airtelgprs.com"}, + {"ӡ", "Idea", "899170", "airtelgprs.com"}, + {"ӡ", "Idea", "899178", "airtelgprs.com"}, + {"ӡ", "Idea", "899182", "airtelgprs.com"}, + {"ӡ", "Idea", "899187", "airtelgprs.com"}, + + {"ӡ", "Jio", "8991840", "Jionet"}, + {"ӡ", "Jio", "8991854", "Jionet"}, + {"ӡ", "Jio", "8991855", "Jionet"}, + {"ӡ", "Jio", "8991856", "Jionet"}, + {"ӡ", "Jio", "8991857", "Jionet"}, + {"ӡ", "Jio", "8991858", "Jionet"}, + {"ӡ", "Jio", "8991859", "Jionet"}, + {"ӡ", "Jio", "8991860", "Jionet"}, + {"ӡ", "Jio", "8991861", "Jionet"}, + {"ӡ", "Jio", "8991862", "Jionet"}, + {"ӡ", "Jio", "8991863", "Jionet"}, + {"ӡ", "Jio", "8991864", "Jionet"}, + {"ӡ", "Jio", "8991865", "Jionet"}, + {"ӡ", "Jio", "8991866", "Jionet"}, + {"ӡ", "Jio", "8991867", "Jionet"}, + {"ӡ", "Jio", "8991868", "Jionet"}, + {"ӡ", "Jio", "8991869", "Jionet"}, + {"ӡ", "Jio", "8991870", "Jionet"}, + {"ӡ", "Jio", "8991871", "Jionet"}, + {"ӡ", "Jio", "8991872", "Jionet"}, + {"ӡ", "Jio", "8991873", "Jionet"}, + {"ӡ", "Jio", "8991874", "Jionet"}, + + {"϶", "MOVISTAR", "8959300", "internet.movistar.com.ec"}, + {"϶", "Claro", "8959301", "internet.claro.com.ec"}, + {"϶", "CNT", "8959302", "internet.cnt.net.ec"}, + +}; + +/*_____ D E C L A R A T I O N ____________________________internet.movistar.com.ec____________________*/ + +u16 crc16(u8 *puchMsg, u16 usDataLen); +const u8 auchCRCHi[] = { + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0 /**/, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40}; + +const u8 auchCRCLo[] = { + 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06 /**/, + 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, + 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, + 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, + 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, + 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, + 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, + 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, + 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, + 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, + 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, + 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, + 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, + 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, + 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, + 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, + 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, + 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, + 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, + 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, + 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, + 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, + 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, + 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, + 0x43, 0x83, 0x41, 0x81, 0x80, 0x40}; +u16 CRC_Check(u8 *puchMsg, u16 usDataLen) +{ + u8 uchCRCHi = 0xFF; + u8 uchCRCLo = 0xFF; + u16 uIndex; + while (usDataLen--) + { + uIndex = uchCRCHi ^ *puchMsg++; + uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex]; + uchCRCLo = auchCRCLo[uIndex]; + } + return (uchCRCLo << 8 | uchCRCHi); +} +u16 DartCRC16(u8 *puchMsg, u16 usDataLen) +{ + u8 uchCRCHi = 0x00; + u8 uchCRCLo = 0x00; + u16 uIndex; + while (usDataLen--) + { + uIndex = uchCRCHi ^ *puchMsg++; + uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex]; + uchCRCLo = auchCRCLo[uIndex]; + } + return (uchCRCLo << 8 | uchCRCHi); +} +u8 SUMCRC(u8 *puchMsg, u16 usDataLen) +{ + u8 sum = 0x00; + while (usDataLen--) + { + sum += *puchMsg++; + } + return (sum); +} +/**************************************************** +POS_Connect_IO_Configuration + ͨѶõIOʼ + +ֵ +****************************************************/ +void POS_Connect_IO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE); + + GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); + GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // ͨģʽ + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // + GPIO_Init(GPIOB, &GPIO_InitStructure); // ʼ +} +/**************************************************** +POS_Connect_NVPOS_Connect_Configuration + ͨѶõж + +ֵ +****************************************************/ +void POS_Connect_NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; // жýṹ + + NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream7_IRQn; // USART1_TX_DMA + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // USART?? + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ???? + NVIC_Init(&NVIC_InitStructure); //??NVIC_InitStruct???????????NVIC???USART1 +} + +/**************************************************** +POS_Connect_NVPOS_Connect_Configuration + ͨѶõĴ + +ֵ +****************************************************/ +void POS_Connect_USART_Configuration(u32 BaudRate) +{ + USART_InitTypeDef USART_InitStructure; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + USART_InitStructure.USART_BaudRate = BaudRate; // Baud;//????? + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + USART_Init(USART1, &USART_InitStructure); + USART_Cmd(USART1, ENABLE); + + USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); + USART_ClearFlag(USART1, USART_FLAG_IDLE); + + USART_DMACmd(USART1, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE); +} +/************************************************* + DMA_Configuration + DMAʼ + +ֵ +**************************************************/ +void POS_Connect_DMA_Configuration(void) +{ + DMA_InitTypeDef DMA_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); + /*******************TX*********************/ + DMA_DeInit(DMA2_Stream7); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + // DMA_InitStructure.DMA_BufferSize = UART_DMA_SEND_LEN; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)POS_Connect_TX_Buff; + + DMA_Init(DMA2_Stream7, &DMA_InitStructure); + DMA_ITConfig(DMA2_Stream7, DMA_IT_TC, ENABLE); + + /*******************RX*********************/ + DMA_DeInit(DMA2_Stream5); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = 2000; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)POS_Connect_RX_Buff; + + DMA_Init(DMA2_Stream5, &DMA_InitStructure); + DMA_Cmd(DMA2_Stream5, ENABLE); +} +// F***************************************************************************** +//* NAME: POS_Connect_DMATX_IRQHandler +//* PURPOSE: ͨѶDMAж +//* PARAMS: +//* return: +//****************************************************************************** +void POS_Connect_DMATX_IRQHandler(void) +{ + u16 i = 0; + DMA_ClearFlag(DMA2_Stream7, DMA_IT_TCIF7); + POS_Connect_TX_DMAStop(); // رDMA +} +// F***************************************************************************** +//* NAME: POS_Connect_DMARX_IRQHandler +//* PURPOSE: DMAжϣGas ModBus +//* PARAMS: +//* return: +//****************************************************************************** + +void POS_Connect_DMARX_IRQHandler(void) +{ + u8 i = 0; + if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //????????? + { + USART_ClearFlag(USART1, USART_IT_IDLE); + POS_Connect_RX_DMAStop(); // رDMA + DMA_ClearFlag(DMA2_Stream5, DMA_IT_TCIF5); + TXHData.POS_Info.POS_ConnectRXTask_Flag = 1; // ʹܽ + i = USART1->SR; + i = USART1->DR; + TXHData.PCMail_RX_Len = 2000 - DMA2_Stream5->NDTR; + POS_Connect_RX_DMALenSet(2000); + POS_Connect_RX_DMAStart(); // DMA()ѡͶʱ + } +} +// F***************************************************************************** +//* NAME: POS_Connect_u64ToBCD +//* PURPOSE: u64תBCD +//* PARAMS: pDataҪתݣLen +//* return: BCD +//****************************************************************************** +u64 POS_Connect_u64ToBCD(u64 Dat) +{ + u8 i = 0; + u64 T64 = 0, Temp = 0; + u8 *pData; + pData = (u8 *)&T64; + for (i = 0; i < 8; i++) + { + Temp = Dat % 100; + *(pData + i) = ((Temp / 10) << 4) + ((Temp % 10) & 0x0F); + Dat /= 100; + } + + return T64; +} +// ʼ +void InitQueue(MessageQueue_Type *Queue) +{ + Queue->Front = 0; + Queue->Rear = 0; +} + +// Ӳ +void EnQueue(MessageQueue_Type *Queue, u8 Content, u8 Priority) +{ + Message_Type *Message; + int i = Queue->Rear; // Ӷβʼ + // ȼ + while (i != Queue->Front && Priority > Queue->Messages[(i - 1 + QUEUE_SIZE) % QUEUE_SIZE].Priority) + { + Queue->Messages[i] = Queue->Messages[(i - 1 + QUEUE_SIZE) % QUEUE_SIZE]; // һλ + i = (i - 1 + QUEUE_SIZE) % QUEUE_SIZE; + } + Queue->Messages[i].Content = Content; + Queue->Messages[i].Priority = Priority; + Queue->Rear = (Queue->Rear + 1) % QUEUE_SIZE; // βָ +} + +// Ӳ +Message_Type *DeQueue(MessageQueue_Type *Queue) +{ + Message_Type *Message; + if (Queue->Front != Queue->Rear) + { + Message = &Queue->Messages[Queue->Front]; + Queue->Front = (Queue->Front + 1) % QUEUE_SIZE; + return Message; + } + else + { + Message->Content = 0; + return Message; + } +} +// ѯDzǰضϢ +u8 FindMessage(MessageQueue_Type *Queue, u8 Content) +{ + u8 i = 0; + for (i = 0; i < QUEUE_SIZE; i++) + { + if (Queue->Messages[i].Content == Content) + { + return Queue->Messages[i].Priority; + } + } + return 0; +} +void POS_Network_APN_Set(void) +{ + char CMD[50] = "AT+APN="; + u32 i = 0; + u16 Temp = 0; + u32 numElements = 0; + u32 strllen = 0; + if ((TXHData.POS_Info.ConnectType != POS_Connect_Typ_Station)) + { + BEEP = 1; + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < strlen(CMD_Model_Set_2); i++) + POS_Connect_TX_Buff[i] = CMD_Model_Set_2[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + delay_ms(500); + + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < strlen(CMD_Model_NET); i++) + POS_Connect_TX_Buff[i] = CMD_Model_NET[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + delay_ms(1000); + + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < strlen(CMD_Model_Set_1); i++) + POS_Connect_TX_Buff[i] = CMD_Model_Set_1[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + delay_ms(1000); + + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < strlen(CMD_Model_Set_2); i++) + POS_Connect_TX_Buff[i] = CMD_Model_Set_2[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + delay_ms(1000); + { + strcat(CMD, (const char *)TXHData.POSData.WirelessData.APN); + strcat(CMD, NextStr); + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < strlen((char *)&CMD); i++) + POS_Connect_TX_Buff[i] = CMD[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + }; + delay_ms(1000); + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < sizeof(CMD_Save); i++) + POS_Connect_TX_Buff[i] = CMD_Save[i]; + POS_Connect_TX_DMALenSet(i - 1); // ÷DMA + POS_Connect_TX_DMAStart(); + delay_ms(100); + BEEP = 0; + } +} +void POS_WIFIReconnect(void) +{ + u32 i = 0, j = 0; + u16 Temp = 0; + u32 numElements = 0; + u32 strllen = 0; + u16 StartLen = 0, EndLen = 0; + + for (i = 0; i < 100; i++) + POS_Connect_TX_Buff[i] = 0; + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < 8; i++) + POS_Connect_TX_Buff[i] = CMD_WifiWSSSID[i]; + for (i = 0; i < strlen((const char *)TXHData.POSData.WirelessData.WiFIName); i++) + POS_Connect_TX_Buff[8 + i] = TXHData.POSData.WirelessData.WiFIName[i]; + POS_Connect_TX_Buff[8 + i] = ','; + j = 8 + i + 1; + for (i = 0; i < strlen((const char *)TXHData.POSData.WirelessData.WiFIPassWord); i++) + POS_Connect_TX_Buff[j + i] = TXHData.POSData.WirelessData.WiFIPassWord[i]; + strcat(POS_Connect_TX_Buff, "\r\n\0"); + POS_Connect_TX_DMALenSet(strlen((const char *)POS_Connect_TX_Buff)); // ÷DMA + POS_Connect_TX_DMAStart(); + while (!TXHData.POS_Info.POS_ConnectRXTask_Flag) + { + delay_ms(1); + i++; + if (i > 100) + break; + } + if (POS_URL == SWF_ON) // Է + { + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < strlen(CMD_WifiSOCKET); i++) + POS_Connect_TX_Buff[i] = CMD_WifiSOCKET[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + while (!TXHData.POS_Info.POS_ConnectRXTask_Flag) + { + delay_ms(1); + i++; + if (i > 100) + break; + } + } + else + { + for (i = 0; i < 100; i++) + POS_Connect_TX_Buff[i] = 0; + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < 14; i++) + POS_Connect_TX_Buff[i] = CMD_WifiSOCKET[i]; + // const char CMD_WifiSOCKET[]="AT+Socket=0,0,test.joyfueling.com,7011\r\n"; + StartLen = strlen((const char *)TXHData.POSData.WirelessData.CMD_SOCKA); + if (StartLen) + { + for (i = 0; i < StartLen; i++) + POS_Connect_TX_Buff[14 + i] = TXHData.POSData.WirelessData.CMD_SOCKA[i]; + strcat(POS_Connect_TX_Buff, "\r\n\0"); + } + POS_Connect_TX_DMALenSet(strlen((const char *)POS_Connect_TX_Buff)); // ÷DMA + POS_Connect_TX_DMAStart(); + } + + while (!TXHData.POS_Info.POS_ConnectRXTask_Flag) + { + delay_ms(1); + i++; + if (i > 100) + break; + } +} +void POS_Connect_Init(void) +{ + u32 i = 0; + u8 Temp = 0; + POS_Connect_IO_Configuration(); + POS_Connect_DMA_Configuration(); + POS_Connect_USART_Configuration(115200); + POS_Connect_NVIC_Configuration(); + RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); // RNG ʱ + RNG_Cmd(ENABLE); // ʹ RNG + delay_ms(1000); + // InitQueue(&TXHData.POS_TX_MessageQueue); + // ϴԶռȣҲᱻƳУָȼܵ2ܲᱻִ + // EnQueue(&TXHData.POS_TX_MessageQueue,POSConnect_SynchronizationTime,Message_Priority_3); + // EnQueue(&TXHData.POS_TX_MessageQueue,POSConnect_FuelData,Message_Priority_1); + TXHData.POS_Info.POS_CMD_Next = POSConnect_SynchronizationTime; + TXHData.POS_Info.Link_Flag = 0; + TXHData.ReSendDataTimer.Init = 0; // ʼ־ + TXHData.ReSendDataTimer.Flag = 0; // ʱ־ + TXHData.ReSendDataTimer.ON_OFF = 0; // + TXHData.ReSendDataTimer.Cycle = 0; // Ϊѭģʽʱ + TXHData.ReSendDataTimer.TimerCountMax = 1000 * 1; // 1 + + TXHData.POSCutTimer.Init = 0; // ʼ־ + TXHData.POSCutTimer.Flag = 1; // ʱ־ + TXHData.POSCutTimer.ON_OFF = 1; // + TXHData.POSCutTimer.Cycle = 1; // Ϊѭģʽʱssssssssss/dddd + TXHData.POSCutTimer.TimerCountMax = 8000; // 8 + + TXHData.HeartbeatTimer.Init = 0; // ʼ־ + TXHData.HeartbeatTimer.Flag = 0; // ʱ־ + TXHData.HeartbeatTimer.ON_OFF = 1; // + TXHData.HeartbeatTimer.Cycle = 1; // Ϊѭģʽʱ + TXHData.HeartbeatTimer.TimerCountMax = 1000 * 1; // 1 + + TXHData.DelayDetectionTimer.Init = 0; // ʼ־ + TXHData.DelayDetectionTimer.Flag = 0; // ʱ־ + TXHData.DelayDetectionTimer.ON_OFF = 0; // + TXHData.DelayDetectionTimer.Cycle = 0; // Ϊѭģʽʱ + TXHData.DelayDetectionTimer.TimerCountMax = 1000; // 10 + + TXHData.POS_RS232Timer.Init = 0; // ʼ־ + TXHData.POS_RS232Timer.Flag = 1; // ʱ־ + TXHData.POS_RS232Timer.ON_OFF = 1; // + TXHData.POS_RS232Timer.Cycle = 1; // Ϊѭģʽʱcc/ + TXHData.POS_RS232Timer.TimerCountMax = 500; // 0.5 + + TXHData.POSReLinkTimer.Init = 0; // ʼ־ + TXHData.POSReLinkTimer.Flag = 0; // ʱ־ + TXHData.POSReLinkTimer.ON_OFF = 1; // + TXHData.POSReLinkTimer.Cycle = 1; // Ϊѭģʽʱcc/ + TXHData.POSReLinkTimer.TimerCountMax = 1000 * 70; // 0.5 + for (i = 0; i < 4; i++) + { + TXHData.MDRestartTimer[i].Init = 0; // ʼ־ + TXHData.MDRestartTimer[i].Flag = 0; // ʱ־ + TXHData.MDRestartTimer[i].ON_OFF = 1; // + TXHData.MDRestartTimer[i].Cycle = 0; // Ϊѭģʽʱ + TXHData.MDRestartTimer[i].TimerCountMax = 11000; // 10 + } + TXHData.POS_Info.WiFiRSSI = 0; + + if (TXHData.POSData.POSConnectTyye.Flag.ConnectMode > 0) + TXHData.POS_Info.ConnectType = TXHData.POSData.POSConnectTyye.Flag.ConnectMode - 1; + if (TXHData.POSData.POSConnectTyye.Flag.NetworkSet > 0) + TXHData.POS_Info.NetType = TXHData.POSData.POSConnectTyye.Flag.NetworkSet - 1; + if (TXHData.POS_Info.ConnectType == POS_Connect_Typ_Station) // վ + { + POSConnect_Station; + TXHData.POSNetSetState.Flag.WorkMode = 1; + } + else + { + POSConnect_Cloud; + } + + switch (TXHData.POS_Info.NetType) + { + case POS_Net_Typ_WAN: + TXHData.POSReLinkTimer.TimerCountMax = 1000 * 30; + POS_LinkA_Out = 0; + break; + case POS_Net_Typ_WiFi: + TXHData.POSReLinkTimer.TimerCountMax = 1000 * 60; + break; + case POS_Net_Typ_4G_GM5: + TXHData.POSReLinkTimer.TimerCountMax = 1000 * 60; + break; + case POS_Net_Typ_4G_L510: + TXHData.POSReLinkTimer.TimerCountMax = 1000 * 60; + POS_LinkA_Out = 0; + TXHData.HeartbeatTimer.TimerCountMax = 1000 * 15; + break; + } + STM32CPU.v.id[0] = *(u32 *)0x1fff7a10; + STM32CPU.v.id[1] = *(u32 *)(0x1fff7a10 + 4); + STM32CPU.v.id[2] = *(u32 *)(0x1fff7a10 + 8); + for (i = 0; i < 20; i++) + TXHData.POSData.WirelessData.IMEI[i] = 0; + sprintf(&TXHData.POSData.WirelessData.IMEI[0], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%", + STM32CPU.v.byte[0], STM32CPU.v.byte[2], STM32CPU.v.byte[4], STM32CPU.v.byte[5], STM32CPU.v.byte[6], + STM32CPU.v.byte[7], STM32CPU.v.byte[8], STM32CPU.v.byte[9], STM32CPU.v.byte[10], STM32CPU.v.byte[11]); + if (FMItemWrite(CF_POSData, 0)) + BEEP = 0; +} +void FToHA(u8 *Buff, float Temp) // תַʽHEXǵַ +{ + u8 HexToAsc[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}; + u8 i = 0; + u8 *N; + N = (u8 *)(&Temp); + for (i = 0; i < 4; i++) + { + *(Buff + i * 2) = HexToAsc[*(N + 3 - i) >> 4]; + *(Buff + i * 2 + 1) = HexToAsc[*(N + 3 - i) & 0x0f]; + } +} + +u8 FindCharFStr(u8 *Str, char Cha, u8 Num) +{ + u8 i = 0, len = 0; + for (; *Str; ++Str) + { + len++; + if (Cha == *Str) + i++; + if (i == Num) + return len; + } + return 0; +} +u8 Encrypt_Data(u8 Data, u8 Type, u8 Bit) +{ + u16 Temp = 0; + + if (Bit > 0x7) + Bit = 7; + Temp = (Data << 8) | Data; + if (Type == 0) + { + Temp = Temp >> Bit; + return (Temp & 0xff); + } + else if (Type == 1) + { + Temp = Temp << Bit; + Temp >>= 8; + return (Temp & 0xff); + } +} +u8 Decode_Data(u8 Data, u8 Type, u8 Bit) +{ + u16 Temp = 0; + + if (Bit > 7) + Bit = 7; + + Temp = (Data << 8) | Data; + if (Type == 0) + { + Temp = Temp << Bit; + Temp >>= 8; + return (Temp & 0xff); + } + else if (Type == 1) + { + Temp = Temp >> Bit; + return (Temp & 0xff); + } +} + +// F***************************************************************************** +//* NAME: POS_ConnectTask +//* PURPOSE: ͨѶݴ +//* PARAMS: +//* return: +//****************************************************************************** +volatile u32 POS_RX_RNGData = 0; +volatile u16 FrameNow = 0; +volatile u8 FrameTimeout = 0; +void POS_ConnectRXTask(void) +{ + u16 POS_ConnectRX_CMD = 0; // ָ + u16 POS_ConnectRX_Len = 0; // + u8 Temp8 = 0, Package = 0; + u8 POS_ConnectRX_AuthorizeNum_Temp = 0; + u16 POS_ConnectRX_Check = 0; // У + volatile u8 TimeLenOffset = 0, Encrypt_Flag1 = 0, Encrypt_Flag2 = 0; + volatile u16 MD_Port_Num = 0, DeviceNumber = 0, MD_Port_Num_Top = 0, DeviceNumber_Top = 0, FrameTop = 0, Offset = 0, len = 0, WifiLenOffset = 0; + u16 i = 0, j = 0, CRCTemp = 0, Temp16 = 0; + u32 Temp32 = 0; + if (TXHData.POSNetSetState.Flag.WorkMode == 1) // ͸ģʽ + { + while (TXHData.PCMail_RX_Len > 10) + { + Package++; // ڼճʶ + if (TXHData.POS_Info.NetType == POS_Net_Typ_WiFi && TXHData.POS_Info.ConnectType != POS_Connect_Typ_Station) + WifiLenOffset = 7; + if (POS_Connect_RX_Buff[WifiLenOffset + TimeLenOffset] == 0xFA) + { + TXHData.PosCTIME.Year = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 1]; + TXHData.PosCTIME.Month = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 2]; + TXHData.PosCTIME.Day = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 3]; + TXHData.PosCTIME.Hour = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 4]; + TXHData.PosCTIME.Min = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 5]; + TXHData.PosCTIME.Sec = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 6]; + if (TXHData.PosCTIME.Sec > TXHData.CTIME.Sec) + Temp8 = MD_Connect_BCDTou64(TXHData.PosCTIME.Sec) - MD_Connect_BCDTou64(TXHData.CTIME.Sec); + else + Temp8 = MD_Connect_BCDTou64(TXHData.CTIME.Sec) - MD_Connect_BCDTou64(TXHData.PosCTIME.Sec); + if ((Temp8 >= 5 && TXHData.PosCTIME.Sec < 0x54 && TXHData.PosCTIME.Sec > 0x6) && (TXHData.PosCTIME.Year >= 0x24 && TXHData.PosCTIME.Year <= 0x50)) + { + TXHData.CTIME = TXHData.PosCTIME; + DS1307_Write(); + } + TimeLenOffset = 6; + } + POS_ConnectRX_Len = (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 1] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 2]; // ȡ + Temp32 = (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 3] << 24) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 4] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 5] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 6]; + if (Temp32 != POS_RX_RNGData && POS_ConnectRX_Len < 2000 && POS_ConnectRX_Len > 0) // 벻ظ + // if(1)//벻ظ + { + POS_RX_RNGData = Temp32; + if (TXHData.PCMail_RX_Len > (WifiLenOffset + POS_ConnectRX_Len + 2 + 1)) + { + TXHData.PCMail_RX_Len = TXHData.PCMail_RX_Len - (POS_ConnectRX_Len + 2); + } + else + { + TXHData.PCMail_RX_Len = 0; + } + Temp16 = CRC_Check(&POS_Connect_RX_Buff[WifiLenOffset], POS_ConnectRX_Len); + if (Temp16 == ((POS_Connect_RX_Buff[WifiLenOffset + POS_ConnectRX_Len] << 8) | POS_Connect_RX_Buff[WifiLenOffset + POS_ConnectRX_Len + 1])) + // if(1)//벻ظ + { + if (TXHData.UDisk_Flag) + Log_Task(&POS_Connect_RX_Buff[WifiLenOffset], POS_ConnectRX_Len + 2, 4, Info_Receive); + Encrypt_Flag1 = (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 4] & 0x0f) % 2; + Encrypt_Flag2 = (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 6] & 0x0f) / 2; + + for (i = 0; i < POS_ConnectRX_Len - TimeLenOffset - 7; i++) + POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 7 + i] = Decode_Data(POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 7 + i], Encrypt_Flag1, Encrypt_Flag2); + + // if(TXHData.UDisk_Flag) + // Log_Task(&POS_Connect_RX_Buff[(WifiLenOffset) + 0],POS_ConnectRX_Len + 2,4,Info_Receive); + POS_ConnectRX_CMD = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 7]; + TXHData.POS_Info.Link_Flag = 1; + TXHData.POSCutTimer.TimerCount = 0; + TXHData.POSCutTimer.Flag = 0; + TXHData.POSReLinkTimer.Flag = 0; + TXHData.POSReLinkTimer.TimerCount = 0; + TXHData.DelayDetection = TXHData.DelayDetectionTimer.TimerCount; + TXHData.DelayDetectionTimer.Init = 1; + if (TXHData.POS_Info.NetType == POS_Net_Typ_WAN || TXHData.POS_Info.NetType == POS_Net_Typ_4G_L510) + POS_LinkA_Out = 1; + Offset = 0; + switch (POS_ConnectRX_CMD) + { + case POSConnect_FuelData: + { + if (TXHData.PREXDATA_WaitUpNummber) + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_PREXDATAUp; + } + for (MD_Port_Num = 0; MD_Port_Num < TXHData.MD_Port_Num_Top; MD_Port_Num++) + { + switch (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType) + { + case PosBlueSky: + case PosLY: + case PosJP: + case PosDart: + case PosYGao: + case PosHongYang: + case PosLanFeng: + case PosSSLan: + case PosBlueSkyPlus: + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].SlaveNeedReply = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]; + switch (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]) + { + case 0: + { + } + break; + case 1: + { + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay = 0; + } + break; + case 2: + { + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateRecords = 0; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].OrderNumber = 0; + FMItemWrite(CF_MD_Port_Data, MD_Port_Num); + for (i = 0; i < 20; i++) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].CardNumber[i] = 0; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].CarLicensePlate[i] = 0; + } + break; + } + Offset++; + } + } + break; + case PosYWY: + case PosPLC: + case PosPrice1_4: + { + switch (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]) + { + case 0: + { + } + break; + case 1: + { + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay = 0; + } + break; + case 2: + { + } + break; + } + Offset++; + } + break; + case PosRFID: + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].SlaveNeedReply = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]; + switch (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]) + { + case 0: + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].RFIDState == 0x10) // + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].RFIDState = 0; + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next != RFID_MDConnectCmdFindACK && TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next != RFID_MDConnectCmdLossACK) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteFullingInfo; + } + Offset++; + } + break; + case 1: // ͨ + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteCardInfo; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay = 0; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].RFIDState = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]; + for (i = 0; i < 15; i++) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].RFIDUserName[i] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset + i + 1]; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].CarLicensePlate[i] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset + i + 16]; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].BalanceDecimal = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset + 26]; + for (i = 0; i < 5; i++) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Balance[i] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset + i + 27]; + Offset += 32; + } + break; + case 2: // + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteCardInfo; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay = 0; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].RFIDState = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]; + Offset++; + } + break; + case 4: // Ч + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteCardInfo; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay = 0; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].RFIDState = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]; + Offset++; + } + break; + case 8: //  + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteCardInfo; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay = 0; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].RFIDState = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]; + Offset++; + } + break; + case 0x10: // ʵʱ + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next != RFID_MDConnectCmdFindACK && TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next != RFID_MDConnectCmdLossACK) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteFullingInfo; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay = 0; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].RFIDState = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].BalanceDecimal = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset + 1]; + for (i = 0; i < 5; i++) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Balance[i] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset + i + 2]; + Offset += 7; + } + break; + case 0x20: // + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteCardInfo; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay = 0; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].RFIDState = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]; + for (i = 0; i < 4; i++) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Balance[i] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset + i + 1]; + Offset += 5; + } + break; + case 0x40: // Ȩȡ + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteCardInfo; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay = 0; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.LockState = 0; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].RFIDState = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]; + Offset++; + } + break; + case 235: // + case 236: // + case 237: // + case 238: // + case 239: // + case 240: // + case 241: // + case 242: // + case 243: // + case 244: // + case 245: // + case 246: // + case 247: // + case 248: // + case 249: // + case 250: // + case 251: // + case 252: // + case 253: // + case 254: // + case 255: // + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = RFID_MDConnectCmdWriteCardInfo; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay = 0; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].RFIDState = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]; + Offset++; + } + break; + } + } + } + break; + } + } + if (TXHData.MD_Multiplex_Port_Data.DeviceNumber > 0) + { + for (MD_Port_Num = 0; MD_Port_Num < TXHData.MD_Multiplex_Port_Data.DeviceNumber - 1; MD_Port_Num++) + { /*豸ͣ00;04ӡ;06Һλ;05*/ + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].SlaveNeedReply = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]; + switch (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + Offset]) + { + case 0: + { + } + break; + case 1: + { + TXHData.MD_Multiplex_Port_Data.State[MD_Port_Num].Flag.UpdateDisplay = 0; + } + break; + case 2: + { + TXHData.MD_Multiplex_Port_Data.State[MD_Port_Num].Flag.UpdateRecords = 0; + } + break; + } + Offset++; + } + } + } + } + break; + case POSConnect_Authorize: + { + if (POS_ConnectRX_Len >= 0x1B) // жһ³ + { + for (MD_Port_Num = 0; MD_Port_Num < TXHData.MD_Port_Num_Top; MD_Port_Num++) + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.AuthorizeState == 0 && TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.Start_Flag == 0 && TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunControlState != Control_BoxAuto) + { + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber == MD_Connect_BCDTou64(POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + POS_ConnectRX_AuthorizeNum_Temp * 13])) + { + if ((TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Call == 1 || TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunControlState == Control_NoGun) && TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].WaitPREXDATA_flag == 0) + { + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].NowAuthorizeType = NowAuthorizeType_Online; + // TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].WiFiPortNum + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresteType = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9]; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresetValue = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10] << 24) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 11] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 12] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 13]); + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].OrderNumber = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 17] << 24) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 18] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 19] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 20]); + // TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState. Flag.AuthorizeState = 1; + FMItemWrite(CF_MD_Port_Data, MD_Port_Num); + TXHData.MD_Port_Info[MD_Port_Num].pGunCapture = TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next_End = 0; + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresetValue) + { + switch (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType) // Э顢Ԥֵ + { + case PosBlueSky: + { + switch (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresteType) + { + case Preset_Sale: + { + if (TXHData.MD_Port_Data[MD_Port_Num].PortData.Device_Type == Display_664) + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresetValue == 0x900000) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = C_MDConnectCmdStart; + else + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = C_MDConnectCmdWritePrsetSale; + } + else + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresetValue == 0x90000000) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = C_MDConnectCmdStart; + else + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = C_MDConnectCmdWritePrsetSale; + } + } + break; + case Preset_Volume: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = C_MDConnectCmdWritePrsetVolume; + } + break; + } + } + break; + case PosLY: + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Handshake == TXHData.MD_Port_Info[MD_Port_Num].Handshake_Top) + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Price = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 14] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 15] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 16]); + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresteType = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9]; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].LYGunNeedCMD = LY_MDConnectCmdAuthorize; + // TXHData.MD_Port_Info[i].pGunNow = TXHData.MD_Port_Data[i].GunData[j].GunNummber; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + } + break; + case PosJP: + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Handshake == TXHData.MD_Port_Info[MD_Port_Num].Handshake_Top) + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Price = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 14] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 15] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 16]); + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresteType = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9]; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].LYGunNeedCMD = LY_MDConnectCmdAuthorize; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + // TXHData.MD_Port_Info[i].pGunNow = TXHData.MD_Port_Data[i].GunData[j].GunNummber; + } + } + break; + case PosYGao: + { + if (TXHData.MD_Port_Data[MD_Port_Num].PortData.Device_Type == Display_664) + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresetValue == 0x900000) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = YG_MDConnectCmdStart; + else + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = YG_MDConnectCmdWritePrset; + } + else + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresetValue == 0x90000000) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = YG_MDConnectCmdStart; + else + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = YG_MDConnectCmdWritePrset; + } + } + break; + case PosHongYang: + { + switch (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresteType) + { + case Preset_Sale: + { + if (TXHData.MD_Port_Data[MD_Port_Num].PortData.Device_Type == Display_664) + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresetValue == 0x900000) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = HY_MDConnectCmdStart; + else + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = HY_MDConnectCmdWritePrsetSale; + } + else + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresetValue == 0x90000000) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = HY_MDConnectCmdStart; + else + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = HY_MDConnectCmdWritePrsetSale; + } + } + break; + case Preset_Volume: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = HY_MDConnectCmdWritePrsetVolume; + } + break; + } + } + break; + case PosSSLan: + { + i = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].FatherNum; // ȡ豸 + TXHData.MD_Port_Info[MD_Port_Num].pGunCapture = i; + if (TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].Handshake == TXHData.MD_Port_Info[MD_Port_Num].Handshake_Top) + { + TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].SonNow = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].SonNum; // ȡ豸ڸ豸еλúţΪǰ豸еĸ豸ʶ + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Price = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 14] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 15] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 16]); + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresteType = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9]; + TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].MB_CMD_Need = LY_MDConnectCmdAuthorize; + TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + } + break; + case PosBlueSkyPlus: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = LTP_GunCMDAuthorize; + } + break; + } + } + } + // POS_ConnectRX_AuthorizeNum_Temp ++; + // if(POS_ConnectRX_AuthorizeNum_Temp >= POS_ConnectRX_AuthorizeNum) + break; + } + } + } + if (DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber) + break; + } + } + } + break; + case POSConnect_Preset: + { + if (POS_ConnectRX_Len >= 0x1B) // жһ³ + { + for (MD_Port_Num = 0; MD_Port_Num < TXHData.MD_Port_Num_Top; MD_Port_Num++) + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.Start_Flag == 0 && TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].WaitPREXDATA_flag == 0) + { + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber == MD_Connect_BCDTou64(POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8 + POS_ConnectRX_AuthorizeNum_Temp * 13])) + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresteType = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9]; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresetValue = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10] << 24) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 11] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 12] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 13]); + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].OrderNumber = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 17] << 24) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 18] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 19] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 20]); + // TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState. Flag.AuthorizeState = 1; + FMItemWrite(CF_MD_Port_Data, MD_Port_Num); + TXHData.MD_Port_Info[MD_Port_Num].pGunCapture = TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next_End = 1; + switch (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType) + { + case PosBlueSky: + { + switch (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresteType) + { + case Preset_Sale: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = C_MDConnectCmdWritePrsetSale; + } + break; + case Preset_Volume: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = C_MDConnectCmdWritePrsetVolume; + } + break; + } + } + break; + case PosYGao: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = YG_MDConnectCmdWritePrset; + } + break; + case PosHongYang: + { + switch (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].PresteType) + { + case Preset_Sale: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = HY_MDConnectCmdWritePrsetSale; + } + break; + case Preset_Volume: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = HY_MDConnectCmdWritePrsetVolume; + } + break; + } + } + break; + case PosBlueSkyPlus: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = LTP_GunCMDWritePrset; + } + break; + } + break; + } + } + } + if (DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber) + break; + } + } + } + break; + case POSConnect_DisAuthorize: + { + for (MD_Port_Num = 0; MD_Port_Num < TXHData.MD_Port_Num_Top; MD_Port_Num++) + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber == MD_Connect_BCDTou64(POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8])) + { + { + TXHData.MD_Port_Info[MD_Port_Num].pGunCapture = TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber; + switch (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType) + { + case PosBlueSky: + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].WaitPREXDATA_flag == 0) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = C_MDConnectCmdStop; + } + break; + case PosLY: + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Handshake == TXHData.MD_Port_Info[MD_Port_Num].Handshake_Top && (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].WaitPREXDATA_flag == 0)) + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].LYGunNeedCMD = LY_MDConnectCmdDisauthorize; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + } + break; + case PosJP: + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Handshake == TXHData.MD_Port_Info[MD_Port_Num].Handshake_Top && (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].WaitPREXDATA_flag == 0)) + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].LYGunNeedCMD = LY_MDConnectCmdDisauthorize; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + } + break; + case PosYGao: + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].WaitPREXDATA_flag == 0) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = YG_MDConnectCmdStop; + } + break; + case PosHongYang: + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].WaitPREXDATA_flag == 0) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = HY_MDConnectCmdStop; + } + break; + case PosSSLan: + { + i = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].FatherNum; // ȡ豸 + TXHData.MD_Port_Info[MD_Port_Num].pGunCapture = i; + if (TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].Handshake == TXHData.MD_Port_Info[MD_Port_Num].Handshake_Top) + { + TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].SonNow = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].SonNum; // ȡ豸ڸ豸еλúţΪǰ豸еĸ豸ʶ + TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].MB_CMD_Need = LY_MDConnectCmdDisauthorize; + TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + } + break; + case PosBlueSkyPlus: + { + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].WaitPREXDATA_flag == 0) + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = LTP_GunCMDStop; + } + break; + } + } + break; + } + } + if (DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber) + break; + } + } + break; + case POSConnect_ChangePrice: + { + for (MD_Port_Num = 0; MD_Port_Num < TXHData.MD_Port_Num_Top; MD_Port_Num++) + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber == MD_Connect_BCDTou64(POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8])) + { + { + TXHData.MD_Port_Info[MD_Port_Num].pGunCapture = TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber; + if (TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Handshake == TXHData.MD_Port_Info[MD_Port_Num].Handshake_Top) + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Price = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 11]); + // if(TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Price >= 0x7532) + // { + // // TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Price = 0x1234; + // if (CoreDebug->DHCSR & 1) + // { //check C_DEBUGEN == 1 -> Debugger Connected + // __breakpoint(0); // halt program execution here + // } + // } + switch (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType) + { + case PosBlueSky: + { + // TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].LYGunNeedCMD = C_MDConnectCmdWritePrice; + // TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = C_MDConnectASKControlPower; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = C_MDConnectCmdWritePrice; + } + break; + case PosLY: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].LYGunNeedCMD = LY_MDConnectCmdWritePrice; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + break; + case PosJP: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].LYGunNeedCMD = LY_MDConnectCmdWritePrice; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + break; + case PosDart: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = DART_MDConnectCmdWritePrice; + } + case PosYGao: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = YG_MDConnectCmdWritePrice; + } + break; + case PosHongYang: + { + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = HY_MDConnectCmdWritePrice; + } + break; + case PosSSLan: + { + i = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].FatherNum; // ȡ豸 + TXHData.MD_Port_Info[MD_Port_Num].pGunCapture = i; + if (TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].Handshake == TXHData.MD_Port_Info[MD_Port_Num].Handshake_Top) + { + TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].SonNow = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].SonNum; // ȡ豸ڸ豸еλúţΪǰ豸еĸ豸ʶ + TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].MB_CMD_Need = LY_MDConnectCmdWritePrice; + TXHData.MD_Port_Info[MD_Port_Num].FatherDevice[i].MB_CMD_Next = LY_MDConnectCmdChoiceGun; + } + } + break; + case PosBlueSkyPlus: + { + TXHData.MD_Port_Info[MD_Port_Num].pGunCapture = DeviceNumber; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].MB_CMD_Next = LTP_GunCMDWriteParameter; + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].ParameterNumber = 0x01; + } + break; + } + } + } + break; + } + } + if (DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber) + break; + } + } + break; + case POSConnect_Config: + { + Offset = (WifiLenOffset + TimeLenOffset) + 8; + if (POS_Connect_RX_Buff[Offset] < 5 && POS_Connect_RX_Buff[Offset] > 0) + { + MD_Port_Num = POS_Connect_RX_Buff[Offset] - 1; + Offset++; + TXHData.MD_Port_Data[MD_Port_Num].PortData.BaudRate = MD_Connect_BCDTou64((POS_Connect_RX_Buff[Offset] << 16) | (POS_Connect_RX_Buff[Offset + 1] << 8) | POS_Connect_RX_Buff[Offset + 2]); + Offset += 3; + TXHData.MD_Port_Data[MD_Port_Num].PortData.StopBits = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset += 1; + TXHData.MD_Port_Data[MD_Port_Num].PortData.Parity_Even = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset += 1; + TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset += 1; + TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset += 1; + TXHData.MD_Port_Data[MD_Port_Num].PortData.MBCountTime = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset += 1; + TXHData.MD_Port_Data[MD_Port_Num].PortData.Device_Type = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset += 1; + if (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosRFID) + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset += 1; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunAddr = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset += 1; + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].RFIDBinding != MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]) && TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].RFIDBinding > 0) // ֮ǰ󶨹һǹҪǰǹϢ + { + for (i = 0; i < TXHData.MD_Port_Num_Top; i++) + { + for (j = 0; j < TXHData.MD_Port_Data[i].PortData.DeviceNumber; j++) + { + if (TXHData.MD_Port_Data[i].GunData[j].GunNummber == TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].RFIDBinding) + { + TXHData.MD_Port_Info[i].GunInfo[j].AssociatedDevices.Number = 0; + TXHData.MD_Port_Info[i].GunInfo[j].AssociatedDevices.Port = 0; + TXHData.MD_Port_Info[i].GunInfo[j].AssociatedDevices.location = 0; + } + } + } + } + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].RFIDBinding = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset += 1; + } + } + else + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset += 1; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunAddr = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset += 1; + } + if ((POS_Connect_RX_Buff[Offset] & 0x0f) < 4) + TXHData.MD_Port_Data[MD_Port_Num].PortData.GunDec.Dec.OilCNT = POS_Connect_RX_Buff[Offset] & 0x0f; + Offset += 1; + if ((POS_Connect_RX_Buff[Offset] >> 4) < 4) + TXHData.MD_Port_Data[MD_Port_Num].PortData.GunDec.Dec.MoneyCNT = (POS_Connect_RX_Buff[Offset] >> 4) & 0x0f; + if ((POS_Connect_RX_Buff[Offset] & 0x0f) < 4) + TXHData.MD_Port_Data[MD_Port_Num].PortData.GunDec.Dec.Price = POS_Connect_RX_Buff[Offset] & 0x0f; + Offset += 1; + if ((POS_ConnectRX_Len) > (26 + DeviceNumber * 2)) + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunControlState = POS_Connect_RX_Buff[Offset]; + Offset += 1; + } + } + } + for (i = TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; i < 16; i++) + TXHData.MD_Port_Data[MD_Port_Num].GunData[i].RFIDBinding = TXHData.MD_Port_Data[MD_Port_Num].GunData[i].GunAddr = TXHData.MD_Port_Data[MD_Port_Num].GunData[i].GunNummber = 0; + + FMItemWrite(CF_MD_Port_Data, MD_Port_Num); + MD_Port_Init(MD_Port_Num); + TXHData.MDRestartTimer[MD_Port_Num].ON_OFF = 1; + // EnQueue(&TXHData.POS_TX_MessageQueue,POS_ConnectRX_CMD,Message_Priority_2); + } + else if (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8] == 5 && TXHData.HardwareVersion < 32) // 24-31Ǵ壬32-38С,Сûе˿ + { + Offset = (WifiLenOffset + TimeLenOffset) + 9; + TXHData.MD_Multiplex_Port_Data.DeviceNumber = POS_Connect_RX_Buff[Offset]; + if (TXHData.MD_Multiplex_Port_Data.DeviceNumber > 4) + TXHData.MD_Multiplex_Port_Data.DeviceNumber = 4; // 4һGPSģ + Offset++; + for (MD_Port_Num = 0; MD_Port_Num < TXHData.MD_Multiplex_Port_Data.DeviceNumber; MD_Port_Num++) + { + TXHData.MD_Multiplex_Port_Data.PortData[MD_Port_Num].DeviceNumber = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset++; + TXHData.MD_Multiplex_Port_Data.PortData[MD_Port_Num].POSType = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset++; + TXHData.MD_Multiplex_Port_Data.PortData[MD_Port_Num].BaudRate = MD_Connect_BCDTou64((POS_Connect_RX_Buff[Offset] << 16) | (POS_Connect_RX_Buff[Offset + 1] << 8) | POS_Connect_RX_Buff[Offset + 2]); + Offset += 3; + TXHData.MD_Multiplex_Port_Data.PortData[MD_Port_Num].StopBits = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset++; + TXHData.MD_Multiplex_Port_Data.PortData[MD_Port_Num].Parity_Even = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset++; + TXHData.MD_Multiplex_Port_Data.PortData[MD_Port_Num].MBCountTime = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Offset]); + Offset++; + Temp16 = (POS_Connect_RX_Buff[Offset] << 8) | POS_Connect_RX_Buff[Offset + 1]; + Offset += 2; + Offset += Temp16; + } + if (TXHData.HardwareVersion >= 26) // 汾26֮GPSģ + { + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[TXHData.MD_Multiplex_Port_Data.DeviceNumber].Init = 0; // ʼ־ + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[TXHData.MD_Multiplex_Port_Data.DeviceNumber].Flag = 0; // ʱ־ + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[TXHData.MD_Multiplex_Port_Data.DeviceNumber].ON_OFF = 1; // + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[TXHData.MD_Multiplex_Port_Data.DeviceNumber].Cycle = 1; // Ϊѭģʽʱ + TXHData.MD_Multiplex_Port_Info.MultiplexDevicerTimer[TXHData.MD_Multiplex_Port_Data.DeviceNumber].TimerCountMax = 10 * 1000; // 10001s + TXHData.MD_Multiplex_Port_Data.PortData[TXHData.MD_Multiplex_Port_Data.DeviceNumber].MBCountTime = 10 * 100; + TXHData.MD_Multiplex_Port_Data.PortData[TXHData.MD_Multiplex_Port_Data.DeviceNumber].POSType = Multiplex_GPS; + TXHData.MD_Multiplex_Port_Data.PortData[TXHData.MD_Multiplex_Port_Data.DeviceNumber].BaudRate = 9600; + TXHData.MD_Multiplex_Port_Data.PortData[TXHData.MD_Multiplex_Port_Data.DeviceNumber].StopBits = 1; + + TXHData.MD_Multiplex_Port_Data.DeviceNumber += 1; // GPSģһλ + } + + FMItemWrite(CF_MD_Multiplex_Port_Data, 0); + Multiplex_Port_Init(); + } + } + break; + case POSConnect_SynchronizationTime: + { + TXHData.CTIME.Year = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8]; // + TXHData.CTIME.Month = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9]; // + TXHData.CTIME.Day = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10]; // + TXHData.CTIME.Hour = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 11]; // ʱ + TXHData.CTIME.Min = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 12]; // + TXHData.CTIME.Sec = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 13]; // + DS1307_Write(); + DS1307_Read(); + if (TXHData.CTIME.Sec == 0xff) + { + DS1307_Init(); + TXHData.CTIME.Year = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8]; // + TXHData.CTIME.Month = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9]; // + TXHData.CTIME.Day = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10]; // + TXHData.CTIME.Hour = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 11]; // ʱ + TXHData.CTIME.Min = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 12]; // + TXHData.CTIME.Sec = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 13]; // + DS1307_Write(); + DS1307_Read(); + } + // if(TXHData.POS_TX_MessageQueue.Messages[TXHData.POS_TX_MessageQueue.Front].Content == POSConnect_SynchronizationTime) + { + // DeQueue(&TXHData.POS_TX_MessageQueue);//ãղʱͬһֱ + + { + // TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + TXHData.POS_Info.POS_CMD_Next = POSConnect_BoxVersion; + // EnQueue(&TXHData.POS_TX_MessageQueue,POSConnect_FuelData,Message_Priority_1); + } + } + } + break; + case POSConnect_TankAPCDownload: + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + TXHData.CTIME.Year = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8]; // + TXHData.CTIME.Month = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9]; // + TXHData.CTIME.Day = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10]; // + TXHData.CTIME.Hour = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 11]; // ʱ + TXHData.CTIME.Min = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 12]; // + TXHData.CTIME.Sec = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 13]; // + DS1307_Write(); + TXHData.RNGData = RNG_GetRandomNumber(); + // TXHData.RNGData = 0x12345678; + Encrypt_Flag1 = ((TXHData.RNGData >> 16) & 0x0f) % 2; + Encrypt_Flag2 = (TXHData.RNGData & 0x0f) / 2; + } + break; + case POSConnect_BoxVersion: + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_BoxVersion; + TXHData.ROM_UpData_Port = 0; + } + break; + case POSConnect_BoxROMownload: + { + for (MD_Port_Num = 0; MD_Port_Num < 4; MD_Port_Num++) + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.GunUP_Flag == 1) + break; + if (DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber) + break; + } + if (MD_Port_Num >= 4) + { + FrameTimeout = 0; + BEEP = BEEP_ON; + if (TXHData.ATDB45Type >= At45DB321) + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_BoxROMownload; + // EnQueue(&TXHData.POS_TX_MessageQueue,POSConnect_BoxROMownload,Message_Priority_2); + FrameTop = (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9]; // ܶ + FrameNow = (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 11]; // ǰ + for (i = 0; i < 512; i++) + TXHData.Frame[i] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 12 + i]; + if (AT45DBItemWrite(CA_Frame, FrameNow - 1 + RomUpDataAddr_New)) + { + TXHData.ROM_UpData_Port = 0; + TXHData.ROM_UpData_ProgressBar = FrameNow * 100 / FrameTop; + TXHData.DisplayOn = 1; + FrameNow++; + if (FrameNow > FrameTop) + { + // TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + TXHData.ROM_UpData.ROM_UpData_State.Flag.Update_Flag = 1; + TXHData.ROM_UpData.ROM_UpData_State.Flag.RightRun_Flag = 3; + TXHData.ROM_UpData.FrameTop = FrameTop; + FMItemWrite(CF_ROM_UpData, 0); + } + } + } + BEEP = BEEP_OFF; + } + else + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + TXHData.ROM_UpData.ROM_UpData_State.Flag.DisableUpdate = 1; + } + } + break; + case POSConnect_WhiteList: + { + FrameTimeout = 0; + TXHData.POSData.WhiteListVersion = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8]; + FrameTop = (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10]; // ܶ + FrameNow = (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 11] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 12]; // ǰ + if (FrameTop * FrameNow && (FrameTop < 20)) + { + if (POS_ConnectRX_Len > 16) + DeviceNumber_Top = (POS_ConnectRX_Len - 16) / 6; + else + DeviceNumber_Top = 0; + for (i = 0; i < DeviceNumber_Top; i++) + for (j = 0; j < 6; j++) + TXHData.WhiteList.CardNum[(FrameNow - 1) * 10 + i][j] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 13 + i * 6 + j]; + TXHData.DisplayOn = 1; + FrameNow++; + if (FrameNow > FrameTop) + { + if (FrameTop >= 1) + TXHData.WhiteList.WhiteListTop = (FrameTop - 1) * 10 + DeviceNumber_Top; + else + TXHData.WhiteList.WhiteListTop = 0; + for (i = TXHData.WhiteList.WhiteListTop; i < 200; i++) // ʣİ + for (j = 0; j < 6; j++) + TXHData.WhiteList.CardNum[i][j] = 0; + FMItemWrite(CF_WhiteList, 0); + FMItemWrite(CF_POSData, 0); + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + } + else + TXHData.POS_Info.POS_CMD_Next = POSConnect_WhiteList; + } + } + break; + case POSConnect_DeviceVersion: + { + TXHData.ROM_UpData_Port = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8]; + TXHData.POS_Info.POS_CMD_Next = POSConnect_DeviceVersion; + } + break; + case POSConnect_DeviceROMownload: + { + for (MD_Port_Num = 0; MD_Port_Num < 4; MD_Port_Num++) + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.GunUP_Flag == 1) + break; + if (DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber) + break; + } + if (MD_Port_Num >= 4) + { + FrameTimeout = 0; + BEEP = BEEP_ON; + if (TXHData.ATDB45Type >= At45DB321 && POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8] <= 4) + { + TXHData.ROM_UpData_Port = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8]; + MD_Port_Num = TXHData.ROM_UpData_Port - 1; + for (i = 0; i < 16; i++) + TXHData.MD_Port_Data[MD_Port_Num].GunData[i].ROM_UpData_State.Flag.Update_Flag = 0; + TXHData.POS_Info.POS_CMD_Next = POSConnect_DeviceROMownload; + for (i = 0; i < 10; i++) + TXHData.MD_Port_Data[MD_Port_Num].PortData.ROM_UpData_Version[i] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9 + i]; + FrameTop = (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 19] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 20]; // ܶ + FrameNow = (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 21] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 22]; // ǰ + for (i = 0; i < 512; i++) + TXHData.Frame[i] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 23 + i]; + if (AT45DBItemWrite(CA_DeviceFrame, FrameNow - 1 + MD_Port_Num * 1024)) + { + TXHData.ROM_UpData_ProgressBar = FrameNow * 100 / FrameTop; + TXHData.DisplayOn = 1; + FrameNow++; + if (FrameNow > FrameTop) + { + for (i = 0; i < 16; i++) + TXHData.MD_Port_Data[MD_Port_Num].GunData[i].ROM_UpData_State.Flag.Update_Flag = 1; + // TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + TXHData.MD_Port_Data[MD_Port_Num].PortData.ROM_UpData.ROM_UpData_State.Flag.Update_Flag = 1; + TXHData.MD_Port_Data[MD_Port_Num].PortData.ROM_UpData.ROM_UpData_State.Flag.RightRun_Flag = 1; + TXHData.MD_Port_Data[MD_Port_Num].PortData.ROM_UpData.FrameTop = FrameTop; + FMItemWrite(CF_MD_Port_Data, MD_Port_Num); + } + else if (FrameNow == 1) + { + for (i = 0; i < 16; i++) + TXHData.MD_Port_Data[MD_Port_Num].GunData[i].ROM_UpData_State.Flag.Update_Flag = 0; + TXHData.MD_Port_Data[MD_Port_Num].PortData.ROM_UpData.ROM_UpData_State.Flag.Update_Flag = 0; + FMItemWrite(CF_MD_Port_Data, MD_Port_Num); + } + } + } + BEEP = BEEP_OFF; + } + else + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + TXHData.ROM_UpData.ROM_UpData_State.Flag.DisableUpdate = 1; + } + } + break; + case POSConnect_PREXDATAUp: + { + Temp16 = (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9]; + if (TXHData.PREXDATA_Upload.PREXDATA_NowFrame == Temp16 && TXHData.PREXDATA_Upload.PREXDATA_NowWaitUpNummber == TXHData.PREXDATA_WaitUpNummber) // ֡ϴȴظڼû¼ + { + if (TXHData.PREXDATA_WaitUpNummber > TXHData.PREXDATA_Upload.PREXDATA_NowFrameLen) + TXHData.PREXDATA_WaitUpNummber -= TXHData.PREXDATA_Upload.PREXDATA_NowFrameLen; + else + { + TXHData.PREXDATA_WaitUpNummber = 0; + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + } + + TXHData.PREXDATA_Upload.PREXDATA_NowFrame = 0; + TXHData.PREXDATA_Upload.PREXDATA_NowFrameLen = 0; + FMItemWrite(CF_PREXDATA_Upload, 0); + FMItemWrite(CF_PREXDATA_WaitUpNummber, 0); + TXHData.DisplayOn = 1; + } + } + break; + case POSConnect_PrintfInfo: + { + for (i = 0; i < 20; i++) + for (j = 0; j < 32; j++) + TXHData.PrintInfo.PrintBuff[i][j] = 0x20; + TXHData.POS_Info.POS_CMD_Next = POSConnect_PrintfInfo; + FrameTop = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8]; + len = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9]; + if (FrameTop > 20) + FrameTop = 20; + if (len > 32) + len = 32; + for (i = 0; i < FrameTop; i++) + for (j = 0; j < len; j++) + TXHData.PrintInfo.PrintBuff[i][j] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10 + i * len + j]; + FMItemWrite(CF_PrintInfo, 0); + } + break; + case POSConnect_Print: + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_Print; + TXHData.PrintRecord.GunNumber = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 8]; + TXHData.PrintRecord.FData.MoneyCNT = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9] << 24) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 11] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 12]); + TXHData.PrintRecord.FData.OilCNT = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 13] << 24) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 14] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 15] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 16]); + TXHData.PrintRecord.Price = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 17] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 18] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 19]); + TXHData.PrintRecord.RTIME.Year = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 20]; // + TXHData.PrintRecord.RTIME.Month = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 21]; // + TXHData.PrintRecord.RTIME.Day = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 22]; // + TXHData.PrintRecord.RTIME.Hour = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 23]; // ʱ + TXHData.PrintRecord.RTIME.Min = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 24]; // + TXHData.PrintRecord.RTIME.Sec = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 25]; // + if (POS_ConnectRX_Len > 32) + TXHData.PrintRecord.OrderNumber = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 26] << 24) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 27] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 28] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 29]); + TXHData.MD_Multiplex_Port_Info.PrintType = PT_Record; + } + break; + case POSConnect_WritePriceTag: + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + for (MD_Port_Num = 0; MD_Port_Num < 4; MD_Port_Num++) + { + if (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosPrice1_4) + { + if (TXHData.MD_Port_Info[MD_Port_Num].PriceTagData.State.Flag.Online == 1) + { + DeviceNumber = (POS_ConnectRX_Len - 14) / 5; + for (i = 0; i < DeviceNumber; i++) + { + TXHData.MD_Port_Info[MD_Port_Num].PriceTagData.Price[i] = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9 + i * 5] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10 + i * 5] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 11 + i * 5]); + TXHData.MD_Port_Info[MD_Port_Num].PriceTagData.Decimal[i] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 12 + i * 5]; + } + TXHData.MD_Port_Info[MD_Port_Num].GunInfo[0].MB_CMD_Next = Price_MDConnectCmdWriteDecimal; + } + break; + } + } + if (MD_Port_Num == 4) + { + for (MD_Port_Num = 0; MD_Port_Num < 5; MD_Port_Num++) + { + if (TXHData.MD_Multiplex_Port_Data.PortData[MD_Port_Num].POSType == Multiplex_Price) + { + TXHData.MD_Multiplex_Port_Info.DevicerCapture = MD_Port_Num; + if (TXHData.MD_Multiplex_Port_Data.State[MD_Port_Num].Flag.Online == 1) + { + DeviceNumber = (POS_ConnectRX_Len - 14) / 5; + for (i = 0; i < DeviceNumber; i++) + { + TXHData.MD_Multiplex_Port_Info.PriceTagData.Price[i] = ((POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 9 + i * 5] << 16) | (POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 10 + i * 5] << 8) | POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 11 + i * 5]); + TXHData.MD_Multiplex_Port_Info.PriceTagData.Decimal[i] = POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + 12 + i * 5]; + } + TXHData.MD_Multiplex_Port_Info.MB_CMD_Next[MD_Port_Num] = Price_MDConnectCmdWriteDecimal; + } + break; + } + } + } + } + break; + default: + for (i = 0; i < 50; i++) + POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + i] = 0; + break; + } + } + else + { + for (i = 0; i < 50; i++) + POS_Connect_RX_Buff[(WifiLenOffset + TimeLenOffset) + i] = 0; + TXHData.PCMail_RX_Len = 0; + break; + } + } + else + { + TXHData.PCMail_RX_Len = 0; + break; + } + if (TXHData.PCMail_RX_Len) + { + TimeLenOffset = 0; + for (i = 0; i < TXHData.PCMail_RX_Len; i++) + { + POS_Connect_RX_Buff[(WifiLenOffset) + i] = POS_Connect_RX_Buff[WifiLenOffset + POS_ConnectRX_Len + 2 + i]; + } + } + } + for (i = TXHData.PCMail_RX_Len; i < 40; i++) + { + POS_Connect_RX_Buff[i] = 0; + } + } + else // ָģʽ + { + switch (TXHData.POS_Info.NetType) + { + case POS_Net_Typ_4G_GM5: + { + { + switch (TXHData.POSNetSetState.Flag.POSNetCMDNext) + { + case GM5_ENTM: + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_Model_Set_1; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + break; + case GM5_Model_Set_1: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "a"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_Model_Set_2; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case GM5_Model_Set_2: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "ok"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_Rec; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case GM5_Rec: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_HEARTEN; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case GM5_HEARTEN: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_UARTFL; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case GM5_UARTFL: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_LinkMode; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case GM5_APN: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_LinkMode; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case GM5_LinkMode: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + if (TXHData.HardwareVersion > 24) // µӲ汾⿪ʼеģʹоƬIMEI + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_GetICCID; + } + else + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_GetIMEI; + } + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case GM5_GetIMEI: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "IMEI:"); + if (Temp16) + { + for (i = 0; i < 20; i++) + TXHData.POSData.WirelessData.IMEI[i] = 0; + for (i = 0; i < 15; i++) + TXHData.POSData.WirelessData.IMEI[5 + i] = POS_Connect_RX_Buff[Temp16 + 4 + i]; + FMItemWrite(CF_POSData, 0); + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_GetICCID; + } + } + break; + case GM5_GetICCID: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "ICCID:"); + if (Temp16) + { + for (i = 0; i < 20; i++) + TXHData.ICCID[i] = 0; + for (i = 0; i < 20; i++) + TXHData.ICCID[i] = POS_Connect_RX_Buff[Temp16 + 5 + i]; + // FMItemWrite(CF_,0); + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_SOCKET; + } + } + break; + case GM5_SOCKET: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_CSQ; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case GM5_CSQ: + { + if (TXHData.POS_Info.WiFiRSSI) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_Save; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + Temp16 = mystrstr(POS_Connect_RX_Buff, "CSQ:"); + if (Temp16) + { + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + TXHData.POS_Info.WiFiRSSI = MD_Connect_BCDTou64(((POS_Connect_RX_Buff[Temp16 + 4] - 0x30) << 4) | (POS_Connect_RX_Buff[Temp16 + 5] - 0x30)); + Temp16 = mystrstr(POS_Connect_RX_Buff, ","); + if (Temp16) + { + if (POS_Connect_RX_Buff[Temp16 + 1] >= 0x30) + TXHData.POS_Info.WiFiChannel = MD_Connect_BCDTou64(((POS_Connect_RX_Buff[Temp16] - 0x30) << 4) | (POS_Connect_RX_Buff[Temp16 + 1] - 0x30)); + else + TXHData.POS_Info.WiFiChannel = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Temp16] - 0x30); + } + } + } + break; + case GM5_Save: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.WorkMode = 1; + TXHData.HeartbeatTimer.TimerCountMax = 1000; + } + } + break; + case GM5_RESET: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_ENTM; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + } + } + }; + break; + case POS_Net_Typ_4G_L510: + { + { + switch (TXHData.POSNetSetState.Flag.POSNetCMDNext) + { + case L510_ATRec: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + // for(i = 0;i < 20;i ++) + // TXHData.POSData.WirelessData.IMEI[i] = 0; + // TXHData.HeartbeatTimer.TimerCount = 0; + // TXHData.HeartbeatTimer.Flag = 1; + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_IMEI; + } + } + break; + case L510_IMEI: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "\""); + if (Temp16) + { + // for(i = 0;i < 20;i ++) + // TXHData.POSData.WirelessData.IMEI[i] = 0; + // for(i = 0;i < 15;i ++) + // TXHData.POSData.WirelessData.IMEI[5 + i] = POS_Connect_RX_Buff[Temp16 + i]; + // FMItemWrite(CF_POSData,0); + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_ICPIN; + } + } + break; + case L510_SetGPSMode: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_ICPIN; + } + } + break; + case L510_ICPIN: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "READY"); + + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_ICCID; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case L510_ICCID: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "ICCID:"); + if (Temp16) + { + for (i = 0; i < 20; i++) + TXHData.ICCID[i] = 0; + for (i = 0; i < 15; i++) + TXHData.ICCID[5 + i] = POS_Connect_RX_Buff[Temp16 + 5 + i]; + // FMItemWrite(CF_,0); + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_RSSI; + } + } + break; + case L510_RSSI: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "CSQ:"); + if (Temp16) + { + if (TXHData.POS_Info.WiFiRSSI) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_Model_NET; + } + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + TXHData.POS_Info.WiFiRSSI = MD_Connect_BCDTou64(((POS_Connect_RX_Buff[Temp16 + 4] - 0x30) << 4) | (POS_Connect_RX_Buff[Temp16 + 5] - 0x30)); + } + } + break; + case L510_Model_NET: + { + // Temp16 = mystrstr(POS_Connect_RX_Buff,"OK"); + // if(Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_NETOPEN; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case L510_APN: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_NETOPEN; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case L510_NETOPEN: + { + // Temp16 = mystrstr(POS_Connect_RX_Buff,"OK"); + // if(Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_SOCKET; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case L510_SOCKET: + { + TXHData.POSNetSetState.Flag.WorkMode = 1; + TXHData.HeartbeatTimer.TimerCountMax = 1000; + } + break; + case L510_AT: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_RESET; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case L510_RESET: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_ATRec; + // TXHData.HeartbeatTimer.TimerCount = 0; + // TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + } + } + }; + break; + case POS_Net_Typ_WiFi: + { + { + switch (TXHData.POSNetSetState.Flag.POSNetCMDNext) + { + case WIFI_ATRec: + { + // Temp16 = mystrstr(POS_Connect_RX_Buff,"OK"); + // if(Temp16) + { + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + TXHData.POSNetSetState.Flag.POSNetCMDNext = WIFI_WifiWSSSID; + } + } + break; + case WIFI_WifiWSSSID: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + TXHData.POSNetSetState.Flag.POSNetCMDNext = WIFI_WifiRSSI; + } + } + break; + case WIFI_WifiRSSI: + { + // Temp16 = mystrstr(POS_Connect_RX_Buff,"atus:"); + // if(Temp16) + { + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + TXHData.POS_Info.WiFiRSSI = MD_Connect_BCDTou64(((POS_Connect_RX_Buff[Temp16 + 5] - 0x30) << 4) | (POS_Connect_RX_Buff[Temp16 + 6] - 0x30)); + Temp16 = mystrstr(POS_Connect_RX_Buff, ","); + if (Temp16) + { + if (POS_Connect_RX_Buff[Temp16 + 1] >= 0x30) + TXHData.POS_Info.WiFiChannel = MD_Connect_BCDTou64(((POS_Connect_RX_Buff[Temp16] - 0x30) << 4) | (POS_Connect_RX_Buff[Temp16 + 1] - 0x30)); + else + TXHData.POS_Info.WiFiChannel = MD_Connect_BCDTou64(POS_Connect_RX_Buff[Temp16] - 0x30); + } + TXHData.POSNetSetState.Flag.POSNetCMDNext = WIFI_WifiSOCKET; + } + } + break; + case WIFI_WifiSOCKET: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + // TXHData.HeartbeatTimer.TimerCount = 0; + // TXHData.HeartbeatTimer.Flag = 1; + // STM32CPU.v.id[0] = *(u32*)0x1fff7a10; + // STM32CPU.v.id[1] = *(u32*)(0x1fff7a10 + 4); + // STM32CPU.v.id[2] = *(u32*)(0x1fff7a10 + 8); + // for(i = 0;i < 20;i ++) + // TXHData.POSData.WirelessData.IMEI[i] = 0; + // // for(i = 0;i < 12;i ++) + // // TXHData.POSData.WirelessData.IMEI[i+8] = STM32CPU.v.byte[i]; + // sprintf(&TXHData.POSData.WirelessData.IMEI[0],"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%", + // STM32CPU.v.byte[0],STM32CPU.v.byte[2],STM32CPU.v.byte[4],STM32CPU.v.byte[5],STM32CPU.v.byte[6], + // STM32CPU.v.byte[7],STM32CPU.v.byte[8],STM32CPU.v.byte[9],STM32CPU.v.byte[10],STM32CPU.v.byte[11]); + // if(FMItemWrite(CF_POSData,0)) + // BEEP = 0; + TXHData.POSNetSetState.Flag.WorkMode = 1; + TXHData.HeartbeatTimer.TimerCountMax = 1000; + } + } + break; + case WIFI_WifiRST: + { + // Temp16 = mystrstr(POS_Connect_RX_Buff,"OK"); + // if(Temp16) + { + TXHData.POSNetSetState.Flag.WorkMode = 0; + TXHData.POSNetSetState.Flag.POSNetCMDNext = WIFI_ATRec; + // TXHData.POSNetSetState.Flag.POSNetSetNeedFlag = 0; + TXHData.POSReLinkTimer.Flag = 0; + TXHData.POSReLinkTimer.TimerCount = 0; + } + } + break; + } + } + }; + break; + case POS_Net_Typ_WAN: + { + { + switch (TXHData.POSNetSetState.Flag.POSNetCMDNext) + { + case USRK3_ENTM: + { + // Temp16 = mystrstr(POS_Connect_RX_Buff,"OK"); + // if(Temp16) + // { + // STM32CPU.v.id[0] = *(u32*)0x1fff7a10; + // STM32CPU.v.id[1] = *(u32*)(0x1fff7a10 + 4); + // STM32CPU.v.id[2] = *(u32*)(0x1fff7a10 + 8); + // for(i = 0;i < 20;i ++) + // TXHData.POSData.WirelessData.IMEI[i] = 0; + // // for(i = 0;i < 12;i ++) + // // TXHData.POSData.WirelessData.IMEI[i+8] = STM32CPU.v.byte[i]; + // sprintf(&TXHData.POSData.WirelessData.IMEI[0],"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%", + // STM32CPU.v.byte[0],STM32CPU.v.byte[2],STM32CPU.v.byte[4],STM32CPU.v.byte[5],STM32CPU.v.byte[6], + // STM32CPU.v.byte[7],STM32CPU.v.byte[8],STM32CPU.v.byte[9],STM32CPU.v.byte[10],STM32CPU.v.byte[11]); + // if(FMItemWrite(CF_POSData,0)) + // BEEP = 0; + // TXHData.POSNetSetState.Flag.WorkMode = 1; + // TXHData.HeartbeatTimer.TimerCountMax = 1000; + // } + // else + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_Model_Set_1; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case USRK3_Model_Set_1: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "a"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_Model_Set_2; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case USRK3_Model_Set_2: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "ok"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_Rec; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case USRK3_Rec: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_DHCP; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case USRK3_DHCP: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_GetIP; + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + } + } + break; + case USRK3_GetIP: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "DHCP,"); + if (Temp16) + { + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + for (i = 0; i < 20; i++) + TXHData.POS_Info.IP[i] = POS_Connect_RX_Buff[Temp16 + 4 + i]; + Temp16 = mystrstr(TXHData.POS_Info.IP, ","); + if (Temp16) + { + for (i = 0; i < 2; i++) + TXHData.POS_Info.IP[i + Temp16 - 1] = 0; + } + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_SOCKET; + TXHData.DisplayOn = 1; + } + } + break; + case USRK3_SOCKET: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_GetLinkState; + } + } + break; + case USRK3_GetLinkState: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + TXHData.HeartbeatTimer.TimerCount = 0; + TXHData.HeartbeatTimer.Flag = 1; + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_RST; + } + } + break; + case USRK3_RST: + { + Temp16 = mystrstr(POS_Connect_RX_Buff, "OK"); + if (Temp16) + { + // STM32CPU.v.id[0] = *(u32*)0x1fff7a10; + // STM32CPU.v.id[1] = *(u32*)(0x1fff7a10 + 4); + // STM32CPU.v.id[2] = *(u32*)(0x1fff7a10 + 8); + // for(i = 0;i < 20;i ++) + // TXHData.POSData.WirelessData.IMEI[i] = 0; + // // for(i = 0;i < 12;i ++) + // // TXHData.POSData.WirelessData.IMEI[i+8] = STM32CPU.v.byte[i]; + // sprintf(&TXHData.POSData.WirelessData.IMEI[0],"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%", + // STM32CPU.v.byte[0],STM32CPU.v.byte[2],STM32CPU.v.byte[4],STM32CPU.v.byte[5],STM32CPU.v.byte[6], + // STM32CPU.v.byte[7],STM32CPU.v.byte[8],STM32CPU.v.byte[9],STM32CPU.v.byte[10],STM32CPU.v.byte[11]); + // if(FMItemWrite(CF_POSData,0)) + // BEEP = 0; + TXHData.POSNetSetState.Flag.WorkMode = 1; + TXHData.HeartbeatTimer.TimerCountMax = 1000; + } + } + break; + } + }; + break; + } + break; + } + TXHData.PCMail_RX_Len = 0; + for (i = 0; i < 100; i++) + POS_Connect_RX_Buff[i] = 0; + } +} +u16 POS_ConnectTXTask(u8 POS_Connect_Typ, u8 GunNum, u8 POS_Connect_Com) // ݷ +{ + u16 i = 0, k = 0, j = 0; + u8 Encrypt_Flag1 = 0; + u8 Encrypt_Flag2 = 0; + u64 Temp = 0; + u16 len = 0, lenTemp = 0, TxLenOffset = 0; + u64 CRCTemp = 0; + u8 *PBuff; + u8 Char_Buff[30]; + u16 MD_Port_Num = 0, DeviceNumber = 0; + + for (i = 0; i < 100; i++) + POS_Connect_TX_Buff[i] = 0; + if (TXHData.POSReLinkTimer.Flag && TXHData.POS_Info.ConnectType != POS_Connect_Typ_Station) // վ) + { + TXHData.POSReLinkTimer.Flag = 0; + TXHData.POSNetSetState.Flag.WorkMode = 0; + switch (TXHData.POS_Info.NetType) + { + case POS_Net_Typ_WAN: + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_ENTM; + break; + case POS_Net_Typ_WiFi: + TXHData.POSNetSetState.Flag.POSNetCMDNext = WIFI_WifiRST; + break; + case POS_Net_Typ_4G_GM5: + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_ENTM; + break; + case POS_Net_Typ_4G_L510: + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_AT; + ; + break; + } + } + if (TXHData.POSNetSetState.Flag.WorkMode == 1) // ͸ģʽ + { + if (TXHData.POSCutTimer.Flag == 1) + { + if (TXHData.POS_Info.Link_Flag == 1) + { + for (MD_Port_Num = 0; MD_Port_Num < 4; MD_Port_Num++) + { + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.Online == 1) + { + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay = 1; + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateRecords == 1) // أͻ豸Ҫ־ + { + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateRecords = 0; + TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].CTOTAL = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].CTOTAL; + TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].FData = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].FData; + TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].GunNumber = TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber; + TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].Price = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Price; + TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].RTIME = TXHData.CTIME; + TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].OrderNumber = TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].OrderNumber; + TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].OrderNumber = 0; + for (i = 0; i < 6; i++) + TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].CardNum[i] = TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].AssociatedDevices.location].CardNumber[i]; + for (i = 0; i < 6; i++) + TXHData.MD_Port_Info[TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].AssociatedDevices.Port].GunInfo[TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].AssociatedDevices.location].CardNumber[i] = 0; + + AT45DBItemWrite(CA_PREXDATA, TXHData.PREXDATA_WaitUpNummber / 5); + FMItemWrite(CF_PREXDATA_TTC, 0); + if (TXHData.PREXDATA_WaitUpNummber < TXHData.OfflineAuthorizeNumberMax) + TXHData.PREXDATA_WaitUpNummber++; + FMItemWrite(CF_PREXDATA_WaitUpNummber, 0); + } + } + } + FMItemWrite(CF_MD_Port_Data, MD_Port_Num); + } + if (TXHData.POS_Info.NetType == POS_Net_Typ_WAN || TXHData.POS_Info.NetType == POS_Net_Typ_4G_L510) + POS_LinkA_Out = 0; + TXHData.POS_Info.Link_Flag = 0; + TXHData.POS_Info.POS_CMD_Next = POSConnect_SynchronizationTime; + // EnQueue(&TXHData.POS_TX_MessageQueue,POSConnect_SynchronizationTime,Message_Priority_3);//ͬʱ + } + } + if (POS_Connect_TX_Flag == 1) + { + while (Encrypt_Flag2 == 0) + { // ʹԭʼ + TXHData.RNGData = RNG_GetRandomNumber(); + // TXHData.RNGData = 0x12345678; + Encrypt_Flag1 = ((TXHData.RNGData >> 16) & 0x0f) % 2; + Encrypt_Flag2 = (TXHData.RNGData & 0x0f) / 2; + } + if (TXHData.POS_Info.NetType == POS_Net_Typ_WiFi && TXHData.POS_Info.ConnectType != POS_Connect_Typ_Station) + { + TxLenOffset = 7; + POS_Connect_TX_Buff[0] = 0x55; + POS_Connect_TX_Buff[1] = 0xFD; + POS_Connect_TX_Buff[2] = 0xAA; + POS_Connect_TX_Buff[3] = 0x00; + POS_Connect_TX_Buff[4] = 0x00; + POS_Connect_TX_Buff[5] = 0x61; + POS_Connect_TX_Buff[6] = 0x00; + } + POS_Connect_TX_Buff[TxLenOffset + 0] = 0xfa; // ֡ͷ + POS_Connect_TX_Buff[TxLenOffset + 1] = TXHData.CTIME.Year; + POS_Connect_TX_Buff[TxLenOffset + 2] = TXHData.CTIME.Month; + POS_Connect_TX_Buff[TxLenOffset + 3] = TXHData.CTIME.Day; + POS_Connect_TX_Buff[TxLenOffset + 4] = TXHData.CTIME.Hour; + POS_Connect_TX_Buff[TxLenOffset + 5] = TXHData.CTIME.Min; + POS_Connect_TX_Buff[TxLenOffset + 6] = TXHData.CTIME.Sec; + for (i = 0; i < 4; i++) + POS_Connect_TX_Buff[TxLenOffset + 9 + i] = TXHData.RNGData >> (8 * (3 - i)); + + if (TXHData.POS_Info.ConnectType == POS_Connect_Typ_Station) // վ + { + POS_Connect_TX_Buff[TxLenOffset + 13] = POS_Connect_Com; + len = TxLenOffset + 8 + 6; + } + else // + { + if (POS_LinkA || (TXHData.BoardType == 0) || TXHData.POS_Info.NetType == POS_Net_Typ_WAN || TXHData.POS_Info.NetType == POS_Net_Typ_4G_L510) + { + for (i = 0; i < 20; i++) + POS_Connect_TX_Buff[TxLenOffset + 13 + i] = TXHData.POSData.WirelessData.IMEI[i]; + for (i = 0; i < 10; i++) + POS_Connect_TX_Buff[TxLenOffset + 33 + i] = TXHData.GPSData.Buff[i]; + POS_Connect_TX_Buff[TxLenOffset + 43] = POS_Connect_Com; + len = TxLenOffset + 38 + 6; + } + else + { + TXHData.POSCutTimer.Flag = 1; + return 0; + } + } + if (len) + { + TXHData.DelayDetectionTimer.ON_OFF = 1; + TXHData.POS_TX_CMDNow = POS_Connect_Com; + switch (POS_Connect_Com) + { + case POSConnect_SynchronizationTime: + case POSConnect_Config: + case POSConnect_ChangePrice: + case POSConnect_DisAuthorize: + case POSConnect_Authorize: + { + } + break; + case POSConnect_BoxVersion: + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + for (i = 0; i < 10; i++) + POS_Connect_TX_Buff[len + i] = BoxVersion[i]; + len += 10; + POS_Connect_TX_Buff[len] = TXHData.POSData.WhiteListVersion; + len++; + } + break; + case POSConnect_FuelData: + { + if (TXHData.ROM_UpData.ROM_UpData_State.Flag.Update_Flag == 1) + { + __set_FAULTMASK(1); + NVIC_SystemReset(); + } + for (MD_Port_Num = 0; MD_Port_Num < TXHData.MD_Port_Num_Top; MD_Port_Num++) + { + if (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosJP || TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosBlueSky || + TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosLY || TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosDart || + TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosYGao || TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosHongYang || + TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosLanFeng || TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosSSLan || + TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosBlueSkyPlus) + { + POS_Connect_TX_Buff[len] = 0x01; // 豸 ǹs + len += 3; // Ԥֽλ + lenTemp = len; // ¼ݿʼλáݿ鳤ȳ + + POS_Connect_TX_Buff[len] = 2; // ݳ + len += 1; + POS_Connect_TX_Buff[len] = 29; // ݳ + len += 1; + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + POS_Connect_TX_Buff[len] = TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.State; + len += 1; + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay == 1 || TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateRecords == 1 || TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.Start_Flag == 1) + { + for (i = 0; i < 4; i++) + POS_Connect_TX_Buff[i + len] = TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].OrderNumber >> ((3 - i) * 8); + len += 4; + for (i = 0; i < 4; i++) + POS_Connect_TX_Buff[i + len] = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].FData.OilCNT >> ((3 - i) * 8); + len += 4; + for (i = 0; i < 4; i++) + POS_Connect_TX_Buff[i + len] = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].FData.MoneyCNT >> ((3 - i) * 8); + len += 4; + for (i = 0; i < 3; i++) + POS_Connect_TX_Buff[i + len] = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Price >> ((2 - i) * 8); + len += 3; + for (i = 0; i < 6; i++) + POS_Connect_TX_Buff[i + len] = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].CTOTAL.TotalLit >> ((5 - i) * 8); + len += 6; + for (i = 0; i < 6; i++) + POS_Connect_TX_Buff[i + len] = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].CTOTAL.TotalMoney >> ((5 - i) * 8); + len += 6; + } + } + POS_Connect_TX_Buff[lenTemp - 2] = (len - lenTemp) >> 8; + POS_Connect_TX_Buff[lenTemp - 1] = (len - lenTemp) & 0xff; + } + else if (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosYWY) + { + POS_Connect_TX_Buff[len] = 0x02; + len += 3; + lenTemp = len; + for (DeviceNumber = 0; DeviceNumber < TXHData.TankNumTop; DeviceNumber++) + { + POS_Connect_TX_Buff[len] = DeviceNumber + 1; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.TankState[MD_Port_Num][DeviceNumber].State; + len += 1; + for (i = 0; i < 16; i++) + POS_Connect_TX_Buff[i + len] = TXHData.TankData[MD_Port_Num][DeviceNumber].Buff[i]; + len += 16; + } + POS_Connect_TX_Buff[lenTemp - 2] = (len - lenTemp) << 8; + POS_Connect_TX_Buff[lenTemp - 1] = (len - lenTemp) & 0xff; + } + else if (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosPLC) + { + POS_Connect_TX_Buff[len] = 0x07; + len += 1; + POS_Connect_TX_Buff[len] = 1; + len += 1; + POS_Connect_TX_Buff[len] = 59; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.CNGPLCState.State; + len += 1; + for (i = 0; i < 58; i++) + POS_Connect_TX_Buff[i + len] = TXHData.CNGPLCData.Buff[i]; + len += 58; + } + else if (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosRFID) + { + POS_Connect_TX_Buff[len] = 0x03; + len += 3; + lenTemp = len; + POS_Connect_TX_Buff[len] = 2; // ݳ + len += 1; + POS_Connect_TX_Buff[len] = 17; // ݳ + len += 1; + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[MD_Port_Num].PortData.DeviceNumber; DeviceNumber++) + { + POS_Connect_TX_Buff[len] = TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunNummber; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.State; + len += 1; + if (TXHData.MD_Port_Data[MD_Port_Num].GunData[DeviceNumber].GunState.Flag.UpdateDisplay == 1) + { + for (i = 0; i < 10; i++) + POS_Connect_TX_Buff[i + len] = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].CardNumber[i]; + len += 10; + for (i = 0; i < 2; i++) + POS_Connect_TX_Buff[i + len] = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].CardPSWD[i]; + len += 2; + for (i = 0; i < 3; i++) + POS_Connect_TX_Buff[i + len] = TXHData.MD_Port_Info[MD_Port_Num].GunInfo[DeviceNumber].Mileage >> ((2 - i) * 8); + len += 3; + } + } + POS_Connect_TX_Buff[lenTemp - 2] = (len - lenTemp) << 8; + POS_Connect_TX_Buff[lenTemp - 1] = (len - lenTemp) & 0xff; + } + else if (TXHData.MD_Port_Data[MD_Port_Num].PortData.POSType == PosPrice1_4) + { + POS_Connect_TX_Buff[len] = PosPrice1_4; + len += 3; + lenTemp = len; + POS_Connect_TX_Buff[len] = 1; // ݳ + len += 1; + POS_Connect_TX_Buff[len] = 1 + TXHData.MD_Port_Info[MD_Port_Num].PriceTagData.PriceNumber * 3; // ݳ + len += 1; + POS_Connect_TX_Buff[len] = TXHData.MD_Port_Info[MD_Port_Num].PriceTagData.State.State; + len += 1; + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Info[MD_Port_Num].PriceTagData.PriceNumber; DeviceNumber++) + { + if (TXHData.MD_Port_Info[MD_Port_Num].PriceTagData.State.Flag.UpdateDisplay == 1) + { + for (i = 0; i < 3; i++) + POS_Connect_TX_Buff[i + len] = TXHData.MD_Port_Info[MD_Port_Num].PriceTagData.Price[DeviceNumber] >> ((2 - i) * 8); + len += 3; + } + } + POS_Connect_TX_Buff[lenTemp - 2] = (len - lenTemp) << 8; + POS_Connect_TX_Buff[lenTemp - 1] = (len - lenTemp) & 0xff; + } + } + if (TXHData.MD_Multiplex_Port_Data.DeviceNumber > 0) + { + for (MD_Port_Num = 0; MD_Port_Num < TXHData.MD_Multiplex_Port_Data.DeviceNumber - 1; MD_Port_Num++) + { /*豸ͣ00;04ӡ;06Һλ;05*/ + if (TXHData.MD_Multiplex_Port_Data.PortData[MD_Port_Num].POSType == Multiplex_Print) + { + POS_Connect_TX_Buff[len] = Multiplex_Print; + len += 1; + POS_Connect_TX_Buff[len] = 1; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.MD_Multiplex_Port_Info.State[MD_Port_Num].State; + len += 1; + } + if (TXHData.MD_Multiplex_Port_Data.PortData[MD_Port_Num].POSType == Multiplex_YWY) + { + POS_Connect_TX_Buff[len] = Multiplex_YWY; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.TankNumTop; + len += 1; + POS_Connect_TX_Buff[len] = 18; + len += 1; + for (DeviceNumber = 0; DeviceNumber < TXHData.TankNumTop; DeviceNumber++) + { + POS_Connect_TX_Buff[len] = DeviceNumber + 1; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.TankState[4][DeviceNumber].State; + len += 1; + for (i = 0; i < 16; i++) + POS_Connect_TX_Buff[i + len] = TXHData.TankData[4][DeviceNumber].Buff[i]; + len += 16; + } + } + else if (TXHData.MD_Multiplex_Port_Data.PortData[MD_Port_Num].POSType == Multiplex_Price) + { + POS_Connect_TX_Buff[len] = Multiplex_Price; + len += 3; + lenTemp = len; + POS_Connect_TX_Buff[len] = 1; // ݳ + len += 1; + POS_Connect_TX_Buff[len] = 1 + TXHData.MD_Multiplex_Port_Info.PriceTagData.PriceNumber * 3; // ݳ + len += 1; + POS_Connect_TX_Buff[len] = TXHData.MD_Multiplex_Port_Data.State[MD_Port_Num].State; + len += 1; + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Multiplex_Port_Info.PriceTagData.PriceNumber; DeviceNumber++) + { + if (TXHData.MD_Multiplex_Port_Data.State[MD_Port_Num].Flag.UpdateDisplay == 1) + { + for (i = 0; i < 3; i++) + POS_Connect_TX_Buff[i + len] = TXHData.MD_Multiplex_Port_Info.PriceTagData.Price[DeviceNumber] >> ((2 - i) * 8); + len += 3; + } + } + POS_Connect_TX_Buff[lenTemp - 2] = (len - lenTemp) << 8; + POS_Connect_TX_Buff[lenTemp - 1] = (len - lenTemp) & 0xff; + } + } + } + } + break; + case POSConnect_BoxROMownload: + { + FrameTimeout++; + if (FrameTimeout < 5 && TXHData.ROM_UpData.ROM_UpData_State.Flag.Update_Flag == 0) + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_BoxROMownload; + } + else + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + if (TXHData.ROM_UpData.ROM_UpData_State.Flag.Update_Flag == 0) + TXHData.ROM_UpData_ProgressBar = 0xFF; // ʧ + } + POS_Connect_TX_Buff[len] = (FrameNow >> 8) & 0xff; + POS_Connect_TX_Buff[len + 1] = FrameNow & 0xff; + len += 2; + } + break; + case POSConnect_WhiteList: + { + FrameTimeout++; + if (FrameTimeout < 5) + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_WhiteList; + } + else + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + } + POS_Connect_TX_Buff[len] = (FrameNow >> 8) & 0xff; + POS_Connect_TX_Buff[len + 1] = FrameNow & 0xff; + len += 2; + } + break; + case POSConnect_DeviceVersion: + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + POS_Connect_TX_Buff[len] = TXHData.ROM_UpData_Port; + len++; + for (DeviceNumber = 0; DeviceNumber < TXHData.MD_Port_Data[TXHData.ROM_UpData_Port - 1].PortData.DeviceNumber; DeviceNumber++) + { + if (TXHData.MD_Port_Info[TXHData.ROM_UpData_Port - 1].GunInfo[DeviceNumber].GunVersion.VersionFindFlag == 1) + { + POS_Connect_TX_Buff[len] = TXHData.MD_Port_Data[TXHData.ROM_UpData_Port - 1].GunData[DeviceNumber].GunNummber; + len += 1; + for (i = 0; i < 10; i++) + POS_Connect_TX_Buff[len + i] = TXHData.MD_Port_Info[TXHData.ROM_UpData_Port - 1].GunInfo[DeviceNumber].GunVersion.Version[i]; + len += 10; + } + } + } + break; + case POSConnect_DeviceROMownload: + { + FrameTimeout++; + if (FrameTimeout < 5 && TXHData.MD_Port_Data[TXHData.ROM_UpData_Port - 1].PortData.ROM_UpData.ROM_UpData_State.Flag.Update_Flag == 0) + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_DeviceROMownload; + // EnQueue(&TXHData.POS_TX_MessageQueue,POSConnect_BoxROMownload,Message_Priority_2); + } + else + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + if (TXHData.MD_Port_Data[TXHData.ROM_UpData_Port - 1].PortData.ROM_UpData.ROM_UpData_State.Flag.Update_Flag == 0) + TXHData.ROM_UpData_ProgressBar = 0xFF; // ʧ + } + POS_Connect_TX_Buff[len] = TXHData.ROM_UpData_Port; + POS_Connect_TX_Buff[len + 1] = (FrameNow >> 8) & 0xff; + POS_Connect_TX_Buff[len + 2] = FrameNow & 0xff; + len += 3; + } + break; + case POSConnect_PREXDATAUp: + { + // EnQueue(&TXHData.POS_TX_MessageQueue,POSConnect_PREXDATAUp,Message_Priority_3); + TXHData.DisplayOn = 1; + POS_Connect_TX_Buff[len] = (TXHData.PREXDATA_WaitUpNummber / 10) >> 8; // ֡ + len += 1; + POS_Connect_TX_Buff[len] = TXHData.PREXDATA_WaitUpNummber / 10; // ֡ + len += 1; + if (TXHData.PREXDATA_WaitUpNummber > 10) + Temp = 10; + else + Temp = TXHData.PREXDATA_WaitUpNummber; + TXHData.PREXDATA_Upload.PREXDATA_NowWaitUpNummber = TXHData.PREXDATA_WaitUpNummber; + TXHData.PREXDATA_Upload.PREXDATA_NowFrame = TXHData.PREXDATA_WaitUpNummber / 10; + TXHData.PREXDATA_Upload.PREXDATA_NowFrameLen = Temp; + FMItemWrite(CF_PREXDATA_Upload, 0); + POS_Connect_TX_Buff[len] = Temp; // δ + len += 1; + POS_Connect_TX_Buff[len] = 40; + len += 1; + for (i = 0; i < Temp; i++) + { + if (TXHData.PREXDATA_WaitUpNummber > 0) + AT45DBItemRead(CA_PREXDATA, (TXHData.PREXDATA_WaitUpNummber - 1 - i) / 5); + POS_Connect_TX_Buff[len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].GunNumber; + len += 1; + for (k = 0; k < 4; k++) + POS_Connect_TX_Buff[k + len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].FData.OilCNT >> ((3 - k) * 8); + len += 4; + for (k = 0; k < 4; k++) + POS_Connect_TX_Buff[k + len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].FData.MoneyCNT >> ((3 - k) * 8); + len += 4; + for (k = 0; k < 3; k++) + POS_Connect_TX_Buff[k + len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].Price >> ((2 - k) * 8); + len += 3; + for (k = 0; k < 6; k++) + POS_Connect_TX_Buff[k + len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].CTOTAL.TotalLit >> ((5 - k) * 8); + len += 6; + for (k = 0; k < 6; k++) + POS_Connect_TX_Buff[k + len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].CTOTAL.TotalMoney >> ((5 - k) * 8); + len += 6; + POS_Connect_TX_Buff[len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].RTIME.Year; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].RTIME.Month; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].RTIME.Day; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].RTIME.Hour; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].RTIME.Min; + len += 1; + POS_Connect_TX_Buff[len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].RTIME.Sec; + len += 1; + for (k = 0; k < 4; k++) + POS_Connect_TX_Buff[k + len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].OrderNumber >> ((3 - k) * 8); + len += 4; + for (k = 0; k < 6; k++) + POS_Connect_TX_Buff[k + len] = TXHData.PREXDATA[(TXHData.PREXDATA_WaitUpNummber - 1 - i) % 5].CardNum[k]; + len += 6; + } + } + break; + case POSConnect_PrintfInfo: + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + POS_Connect_TX_Buff[len] = 0x59; + len += 1; + } + break; + case POSConnect_Print: + { + TXHData.POS_Info.POS_CMD_Next = POSConnect_FuelData; + POS_Connect_TX_Buff[len] = 0x59; + len += 1; + } + break; + } + POS_Connect_TX_Buff[TxLenOffset + 7] = ((len - TxLenOffset) >> 8) & 0xff; + POS_Connect_TX_Buff[TxLenOffset + 8] = (len - TxLenOffset) & 0xff; + + // if(TXHData.UDisk_Flag) + // Log_Task(&POS_Connect_TX_Buff[TxLenOffset],len - TxLenOffset,4,Info_Issue); + + for (i = 0; i < len - TxLenOffset; i++) + POS_Connect_TX_Buff[TxLenOffset + 13 + i] = Encrypt_Data(POS_Connect_TX_Buff[TxLenOffset + 13 + i], Encrypt_Flag1, Encrypt_Flag2); + + if (TXHData.UDisk_Flag) + Log_Task(&POS_Connect_TX_Buff[TxLenOffset], len - TxLenOffset, 4, Info_Issue); + CRCTemp = CRC_Check(&POS_Connect_TX_Buff[TxLenOffset], len - TxLenOffset); // У + POS_Connect_TX_Buff[len] = (CRCTemp >> 8) & 0xff; + len++; + POS_Connect_TX_Buff[len] = CRCTemp & 0xff; + len++; + if (TXHData.POS_Info.NetType == POS_Net_Typ_WiFi && TXHData.POS_Info.ConnectType != POS_Connect_Typ_Station) + { + POS_Connect_TX_Buff[3] = ((len - 5) >> 8) & 0xff; + POS_Connect_TX_Buff[4] = (len - 5) & 0xff; + POS_Connect_TX_Buff[len] = SUMCRC(&POS_Connect_TX_Buff[5], len - 5); + len++; + } + POS_Connect_TX_DMALenSet(len); + POS_Connect_TX_DMAStart(); + return len; + } + } + } + else if (TXHData.POSNetSetState.Flag.WorkMode == 0) // ָģʽ + { + switch (TXHData.POS_Info.NetType) + { + case POS_Net_Typ_4G_GM5: + { + { + switch (TXHData.POSNetSetState.Flag.POSNetCMDNext) + { + case GM5_ENTM: + { + for (i = 0; i < strlen(CMD_Model_NET); i++) + POS_Connect_TX_Buff[i] = CMD_Model_NET[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_Model_Set_1; + TXHData.HeartbeatTimer.TimerCountMax = 1000; + } + break; + case GM5_Model_Set_1: + { + for (i = 0; i < strlen(CMD_Model_Set_1); i++) + POS_Connect_TX_Buff[i] = CMD_Model_Set_1[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case GM5_Model_Set_2: + { + for (i = 0; i < strlen(CMD_Model_Set_2); i++) + POS_Connect_TX_Buff[i] = CMD_Model_Set_2[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case GM5_Rec: + { + for (i = 0; i < strlen(CMD_ATRec); i++) + POS_Connect_TX_Buff[i] = CMD_ATRec[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case GM5_HEARTEN: + { + for (i = 0; i < strlen(CMD_HEARTEN); i++) + POS_Connect_TX_Buff[i] = CMD_HEARTEN[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case GM5_UARTFL: + { + for (i = 0; i < strlen(CMD_UARTFL); i++) + POS_Connect_TX_Buff[i] = CMD_UARTFL[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case GM5_APN: + { + for (i = 0; i < strlen(CMD_APN); i++) + POS_Connect_TX_Buff[i] = CMD_APN[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case GM5_LinkMode: + { + for (i = 0; i < strlen(CMD_LinkMode); i++) + POS_Connect_TX_Buff[i] = CMD_LinkMode[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case GM5_GetIMEI: + { + for (i = 0; i < strlen(CMD_IMEI); i++) + POS_Connect_TX_Buff[i] = CMD_IMEI[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case GM5_GetICCID: + { + for (i = 0; i < strlen(CMD_ICCID); i++) + POS_Connect_TX_Buff[i] = CMD_ICCID[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case GM5_SOCKET: + { + if (TXHData.POS_Info.ConnectType == POS_Connect_Typ_Cloud_Tast) // Է + { + for (i = 0; i < strlen(TsatURL); i++) + POS_Connect_TX_Buff[i] = TsatURL[i]; + } + else + { + for (i = 0; i < 13; i++) + POS_Connect_TX_Buff[i] = TsatURL[i]; + //"AT+SOCKA=TCP,test.joyfueling.com,7011\r\n"; + Temp = strlen((const char *)TXHData.POSData.WirelessData.CMD_SOCKA); + if (Temp) + { + for (i = 0; i < Temp; i++) + POS_Connect_TX_Buff[13 + i] = TXHData.POSData.WirelessData.CMD_SOCKA[i]; + strcat(POS_Connect_TX_Buff, "\r\n\0"); + } + + i = strlen((char *)&POS_Connect_TX_Buff); + } + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case GM5_CSQ: + { + for (i = 0; i < strlen(CMD_CSQ); i++) + POS_Connect_TX_Buff[i] = CMD_CSQ[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case GM5_Save: + { + for (i = 0; i < strlen(CMD_Save); i++) + POS_Connect_TX_Buff[i] = CMD_Save[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + TXHData.HeartbeatTimer.TimerCountMax = 1000 * 10; + } + break; + case GM5_RESET: + { + for (i = 0; i < strlen(CMD_Reset); i++) + POS_Connect_TX_Buff[i] = CMD_Reset[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + TXHData.HeartbeatTimer.TimerCountMax = 1000 * 10; + } + break; + } + } + }; + break; + case POS_Net_Typ_4G_L510: + { + { + switch (TXHData.POSNetSetState.Flag.POSNetCMDNext) + { + case L510_ATRec: + { + for (i = 0; i < strlen(CMD_L510_ATRec); i++) + POS_Connect_TX_Buff[i] = CMD_L510_ATRec[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + TXHData.HeartbeatTimer.TimerCountMax = 3000; + } + break; + case L510_IMEI: + { + for (i = 0; i < strlen(CMD_L510_IMEI); i++) + POS_Connect_TX_Buff[i] = CMD_L510_IMEI[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case L510_SetGPSMode: + { + for (i = 0; i < strlen(CMD_L510_SetGPSMode); i++) + POS_Connect_TX_Buff[i] = CMD_L510_SetGPSMode[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case L510_ICPIN: + { + for (i = 0; i < strlen(CMD_L510_ICPIN); i++) + POS_Connect_TX_Buff[i] = CMD_L510_ICPIN[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + // TXHData.HeartbeatTimer.TimerCountMax = 3000; + } + break; + case L510_ICCID: + { + for (i = 0; i < strlen(CMD_L510_ICCID); i++) + POS_Connect_TX_Buff[i] = CMD_L510_ICCID[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case L510_RSSI: + { + for (i = 0; i < strlen(CMD_L510_RSSI); i++) + POS_Connect_TX_Buff[i] = CMD_L510_RSSI[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case L510_Model_NET: + { + for (i = 0; i < strlen(CMD_L510_Model_NET); i++) + POS_Connect_TX_Buff[i] = CMD_L510_Model_NET[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case L510_APN: + { + for (i = 0; i < strlen(CMD_L510_APN); i++) + POS_Connect_TX_Buff[i] = CMD_L510_APN[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case L510_NETOPEN: + { + for (i = 0; i < strlen(CMD_L510_NETOPEN); i++) + POS_Connect_TX_Buff[i] = CMD_L510_NETOPEN[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case L510_SOCKET: + { + if (TXHData.POS_Info.ConnectType == POS_Connect_Typ_Cloud_Tast) // Է + { + for (i = 0; i < strlen(CMD_L510_SOCKET); i++) + POS_Connect_TX_Buff[i] = CMD_L510_SOCKET[i]; + } + else + { + for (i = 0; i < 20; i++) + POS_Connect_TX_Buff[i] = CMD_L510_SOCKET[i]; + //"AT+SOCKA=TCP,test.joyfueling.com,7011\r\n"; + Temp = strlen((const char *)TXHData.POSData.WirelessData.CMD_SOCKA); + k = mystrstr(TXHData.POSData.WirelessData.CMD_SOCKA, ","); + if (Temp) + { + for (i = 0; i < k - 1; i++) + POS_Connect_TX_Buff[20 + i] = TXHData.POSData.WirelessData.CMD_SOCKA[i]; + POS_Connect_TX_Buff[20 + k - 1] = '\"'; + for (i = k; i < Temp + 1; i++) + POS_Connect_TX_Buff[20 + i] = TXHData.POSData.WirelessData.CMD_SOCKA[i - 1]; + strcat(POS_Connect_TX_Buff, "\r\n\0"); + } + + i = strlen((char *)&POS_Connect_TX_Buff); + } + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case L510_GetLinkState: + { + for (i = 0; i < strlen(CMD_L510_GetLinkState); i++) + POS_Connect_TX_Buff[i] = CMD_L510_GetLinkState[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case L510_AT: + { + if (TXHData.HeartbeatTimer.TimerCountMax == 1001) + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_RESET; + else + TXHData.HeartbeatTimer.TimerCountMax = 1001; + for (i = 0; i < strlen(CMD_L510_AT); i++) + POS_Connect_TX_Buff[i] = CMD_L510_AT[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + /// TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_RESET; + } + break; + case L510_RESET: + { + for (i = 0; i < strlen(CMD_L510_RESET); i++) + POS_Connect_TX_Buff[i] = CMD_L510_RESET[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + TXHData.HeartbeatTimer.TimerCountMax = 1000 * 15; + } + break; + } + } + }; + break; + case POS_Net_Typ_WiFi: + { + { + switch (TXHData.POSNetSetState.Flag.POSNetCMDNext) + { + case WIFI_ATRec: + { + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < strlen(CMD_ATRec); i++) + POS_Connect_TX_Buff[i] = CMD_ATRec[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + // TXHData.HeartbeatTimer.TimerCountMax = 1000*10; + } + break; + case WIFI_WifiWSSSID: + { + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < 100; i++) + POS_Connect_TX_Buff[i] = 0; + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + { + // if(TXHData.POS_Info.ConnectType == POS_Connect_Typ_WifiStation) + // { + // TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + // for(i = 0;i < strlen(CMD_WifiWSSSID_WIFIStation);i ++) + // POS_Connect_TX_Buff[i] = CMD_WifiWSSSID_WIFIStation[i]; + // POS_Connect_TX_DMALenSet(i); //÷DMA + // POS_Connect_TX_DMAStart(); + // } + // else + { + for (i = 0; i < 8; i++) + POS_Connect_TX_Buff[i] = CMD_WifiWSSSID[i]; + for (i = 0; i < strlen((const char *)TXHData.POSData.WirelessData.WiFIName); i++) + POS_Connect_TX_Buff[8 + i] = TXHData.POSData.WirelessData.WiFIName[i]; + POS_Connect_TX_Buff[8 + i] = ','; + j = 8 + i + 1; + for (i = 0; i < strlen((const char *)TXHData.POSData.WirelessData.WiFIPassWord); i++) + POS_Connect_TX_Buff[j + i] = TXHData.POSData.WirelessData.WiFIPassWord[i]; + strcat(POS_Connect_TX_Buff, "\r\n\0"); + POS_Connect_TX_DMALenSet(strlen((const char *)POS_Connect_TX_Buff)); // ÷DMA + POS_Connect_TX_DMAStart(); + } + } + TXHData.HeartbeatTimer.TimerCountMax = 1000 * 10; + } + break; + case WIFI_WifiRSSI: + { + for (i = 0; i < strlen(CMD_WifiRSSI); i++) + POS_Connect_TX_Buff[i] = CMD_WifiRSSI[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + TXHData.POSNetSetState.Flag.POSNetCMDNext = WIFI_WifiSOCKET; + TXHData.HeartbeatTimer.TimerCountMax = 1000 * 2; + } + break; + case WIFI_WifiSOCKET: + { + switch (TXHData.POS_Info.ConnectType) + { + case POS_Connect_Typ_Cloud_Tast: + { + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < strlen(CMD_WifiSOCKET); i++) + POS_Connect_TX_Buff[i] = CMD_WifiSOCKET[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case POS_Connect_Typ_Cloud: + { + for (i = 0; i < 100; i++) + POS_Connect_TX_Buff[i] = 0; + TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + for (i = 0; i < 14; i++) + POS_Connect_TX_Buff[i] = CMD_WifiSOCKET[i]; + // const char CMD_WifiSOCKET[]="AT+Socket=0,0,test.joyfueling.com,7011\r\n"; + j = strlen((const char *)TXHData.POSData.WirelessData.CMD_SOCKA); + if (j) + { + for (i = 0; i < j; i++) + POS_Connect_TX_Buff[14 + i] = TXHData.POSData.WirelessData.CMD_SOCKA[i]; + strcat(POS_Connect_TX_Buff, "\r\n\0"); + } + POS_Connect_TX_DMALenSet(strlen((const char *)POS_Connect_TX_Buff)); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + // case POS_Connect_Typ_WifiStation: + // { + // TXHData.POS_Info.POS_ConnectRXTask_Flag = 0; + // for(i = 0;i < strlen(CMD_WifiSOCKET_WIFIStation);i ++) + // POS_Connect_TX_Buff[i] = CMD_WifiSOCKET_WIFIStation[i]; + // POS_Connect_TX_DMALenSet(i); //÷DMA + // POS_Connect_TX_DMAStart(); + // }break; + } + TXHData.HeartbeatTimer.TimerCountMax = 1000 * 10; + } + break; + case WIFI_WifiRST: + { + for (i = 0; i < strlen(CMD_WifiRST); i++) + POS_Connect_TX_Buff[i] = CMD_WifiRST[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + TXHData.HeartbeatTimer.TimerCountMax = 1000 * 10; + } + break; + } + } + }; + break; + case POS_Net_Typ_WAN: + { + { + switch (TXHData.POSNetSetState.Flag.POSNetCMDNext) + { + case USRK3_ENTM: + { + for (i = 0; i < strlen(CMD_Model_NET); i++) + POS_Connect_TX_Buff[i] = CMD_Model_NET[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_Model_Set_1; + TXHData.HeartbeatTimer.TimerCountMax = 1000; + } + break; + case USRK3_Model_Set_1: + { + for (i = 0; i < strlen(CMD_Model_Set_1); i++) + POS_Connect_TX_Buff[i] = CMD_Model_Set_1[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case USRK3_Model_Set_2: + { + for (i = 0; i < strlen(CMD_Model_Set_2); i++) + POS_Connect_TX_Buff[i] = CMD_Model_Set_2[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case USRK3_Rec: + { + for (i = 0; i < strlen(CMD_ATRec); i++) + POS_Connect_TX_Buff[i] = CMD_ATRec[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case USRK3_DHCP: + { + for (i = 0; i < strlen(CMD_DHCP); i++) + POS_Connect_TX_Buff[i] = CMD_DHCP[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case USRK3_GetIP: + { + for (i = 0; i < strlen(CMD_GetIP); i++) + POS_Connect_TX_Buff[i] = CMD_GetIP[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case USRK3_SOCKET: + { + if (TXHData.POS_Info.ConnectType == POS_Connect_Typ_Cloud_Tast) // Է + { + for (i = 0; i < strlen(WlanTsatURL); i++) + POS_Connect_TX_Buff[i] = WlanTsatURL[i]; + } + else + { + for (i = 0; i < 15; i++) + POS_Connect_TX_Buff[i] = WlanTsatURL[i]; + //"AT+SOCKB1=TCPC,test.joyfueling.com,7011\r\n" + j = strlen((const char *)TXHData.POSData.WirelessData.CMD_SOCKA); + if (j) + { + for (i = 0; i < j; i++) + POS_Connect_TX_Buff[15 + i] = TXHData.POSData.WirelessData.CMD_SOCKA[i]; + strcat(POS_Connect_TX_Buff, "\r\n\0"); + } + + i = strlen((char *)&POS_Connect_TX_Buff); + } + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case USRK3_GetLinkState: + { + for (i = 0; i < strlen(CMD_GetLinkState); i++) + POS_Connect_TX_Buff[i] = CMD_GetLinkState[i]; + POS_Connect_TX_DMALenSet(i); // ÷DMA + POS_Connect_TX_DMAStart(); + } + break; + case USRK3_RST: + { + for (i = 0; i < sizeof(CMD_Reset); i++) + POS_Connect_TX_Buff[i] = CMD_Reset[i]; + POS_Connect_TX_DMALenSet(i - 1); // ÷DMA + POS_Connect_TX_DMAStart(); + TXHData.HeartbeatTimer.TimerCountMax = 1000 * 10; + } + break; + } + } + }; + break; + } + } + return 0; +} diff --git a/User/POS_Connect/POS_Connect.h b/User/POS_Connect/POS_Connect.h new file mode 100644 index 0000000..a7379fb --- /dev/null +++ b/User/POS_Connect/POS_Connect.h @@ -0,0 +1,137 @@ +#ifndef __POS_Connect_H_ +#define __POS_Connect_H_ +/*H****************************************************************************** +* NAME: POS_Connect.h +*********************************************************************************/ + +#define POSConnect_Cloud GPIO_ResetBits(GPIOB,GPIO_Pin_5); +#define POSConnect_Station GPIO_SetBits(GPIOB,GPIO_Pin_5); + +#define POS_NET GPIOAin(0) +#define POS_LinkB GPIOAin(1) +#define POS_LinkA GPIOAin(2) + +/*********************Эָ************************/ +#define POSConnect_Authorize 0xA1 // +#define POSConnect_ChangePrice 0xA2 // +#define POSConnect_Config 0xA3 // +#define POSConnect_DisAuthorize 0xA4 // +#define POSConnect_Preset 0xA5 // +#define POSConnect_Heartbeat 0x0A // +#define POSConnect_SynchronizationTime 0x0B // +#define POSConnect_TankAPCDownload 0x0C // +#define POSConnect_BoxROMownload 0x0D // +#define POSConnect_BoxVersion 0x0E // +#define POSConnect_PREXDATAUp 0x1F // +#define POSConnect_FuelData 0x10 // +#define POSConnect_DeviceVersion 0x11 // +#define POSConnect_DeviceROMownload 0x12 // +#define POSConnect_PrintfInfo 0x14 // +#define POSConnect_Print 0x15 // +#define POSConnect_WhiteList 0x16 // +#define POSConnect_WritePriceTag 0x18 // + +//Ӳ +#define POS_ConnectUsart USART1 +#define POS_Connect_DMA DMA1 + +#define POS_Connect_TX_DMALenSet(x) (DMA2_Stream7->NDTR = x) //÷DMA +#define POS_Connect_TX_DMAStart() DMA_Cmd(DMA2_Stream7,ENABLE) //DMA +#define POS_Connect_TX_DMAStop() DMA_Cmd(DMA2_Stream7,DISABLE) //DMA + +#define POS_Connect_RX_DMALenSet(x) (DMA2_Stream5->NDTR = x) //DMA +#define POS_Connect_RX_DMAStart() DMA_Cmd(DMA2_Stream5,ENABLE) //DMA +#define POS_Connect_RX_DMAStop() DMA_Cmd(DMA2_Stream5,DISABLE) //DMA + +// +#define C_POS_Connect_TX_Buff 100 //ͻС +#define C_POS_Connect_RX_Buff 100 //ջС + +typedef enum +{ + USRK3_ENTM, + USRK3_Model_Set_1, + USRK3_Model_Set_2, + USRK3_Rec, + USRK3_DHCP, + USRK3_GetIP, + USRK3_SOCKET, + USRK3_GetLinkState, + USRK3_RST, + +}USRK3_Item; +typedef enum +{ + WIFI_ATRec, + WIFI_WifiWSSSID, + WIFI_WifiRSSI, + WIFI_WifiSOCKET, + WIFI_WifiRST, + WIFI_WMODE, +}WIFICMD_Item; +typedef enum +{ + GM5_ENTM, + GM5_Model_Set_1, + GM5_Model_Set_2, + GM5_Rec, + GM5_HEARTEN, + GM5_UARTFL, + GM5_APN, + GM5_LinkMode, + GM5_GetIMEI, + GM5_GetICCID, + GM5_SOCKET, + GM5_CSQ, + GM5_Save, + GM5_RESET, + +}GM5_Item; +typedef enum +{ + L510_ATRec, + L510_IMEI, + L510_SetGPSMode, + L510_ICPIN, + L510_ICCID, + L510_RSSI, + L510_Model_NET, + L510_APN, + L510_NETOPEN, + L510_SOCKET, + L510_GetLinkState, + L510_AT, + L510_RESET, + L510_GetGPS, +}L510CMD_Item; +//****************************************************************************** +//*-------------- ----------------------------------------------------- +//****************************************************************************** +extern volatile u8 POS_Connect_TX_Flag; //б־ +extern const char TsatURL[]; +extern volatile u8 MD_Set_Flag_pGun; +extern volatile u8 MD_POS_Flag_pGun; +extern volatile u8 POS2MD_Buff[2000];//posĻظתӵwifiӻ +//****************************************************************************** +//*-------------- ----------------------------------------------------- +//****************************************************************************** +extern void POS_Connect_Init(void); //POS_Connectʼ +extern void POS_Network_Init(void); +extern void POS_Connect_DMARX_IRQHandler(void); //POS_Connect̽жϷ +extern void POS_Connect_DMATX_IRQHandler(void); //DMAжϷ +extern u64 POS_Connect_u64ToBCD(u64 Dat); //תBCD +extern u64 POS_Connect_BCDTou64(u64 Dat); //BCDת +extern void POS_ConnectRXTask(void); //ݽ +extern u16 POS_ConnectTXTask(u8 POS_Connect_Typ,u8 GunNum,u8 POS_Connect_Com);//ݷ +extern u8 Encrypt_Data(u8 Data,u8 Type,u8 Bit); +extern u8 Decode_Data(u8 Data,u8 Type,u8 Bit); +extern u16 DartCRC16(u8 *puchMsg, u16 usDataLen) ; +extern u8 SUMCRC(u8 *puchMsg, u16 usDataLen) ; +extern void InitQueue(MessageQueue_Type *Queue) ; +extern void EnQueue(MessageQueue_Type *Queue, u8 Content,u8 Priority); +extern Message_Type *DeQueue(MessageQueue_Type *Queue) ; +//ѯDzǰضϢ +extern u8 FindMessage(MessageQueue_Type *Queue,u8 Content); +extern u16 CRC_Check(u8 *puchMsg, u16 usDataLen) ; +void POS_Network_APN_Set(void); +#endif //#ifndef diff --git a/User/Printf/Printf.c b/User/Printf/Printf.c new file mode 100644 index 0000000..1ad82c1 --- /dev/null +++ b/User/Printf/Printf.c @@ -0,0 +1,176 @@ +#include "config.h" //ȫ + +/*_____ D E C L A R A T I O N ________________________________________________*/ +void Print_Num(u8 GunNum,u8 Lin,u64 Num,u8 Dec) +{ + volatile u8 i,j,D; + for(i = 22;i < 32;i ++) + TXHData.PrintInfo.PrintBuff[Lin][i] = 0x20; + for(i = 0;i< 16;i++) + { + if((Num>>(i*4)) == 0) + break; + } + if(i <= Dec && Dec > 0) + { + if(i == 0 ) + i+=Dec; + i ++; + + TXHData.PrintInfo.PrintBuff[Lin][30-i] = '0'; + } + if(Dec) + { + D = 1; + TXHData.PrintInfo.PrintBuff[Lin][30- Dec] = '.'; + } + for(j = 0;j < Dec; j++) + TXHData.PrintInfo.PrintBuff[Lin][30- j] = 0x30 + (((Num>>j*4)) & 0x00000000000f); + + for(j = Dec+D;j < i + D; j++) + TXHData.PrintInfo.PrintBuff[Lin][30- (j+1-D)] = 0x30 + (((Num>>(j-D)*4)) & 0x00000000000f); +} + +//******************************************************************************************************** +//** ƣprint_init() +//** ܣӲʼ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t print_init(uint8_t *pData) +{ + *pData++ = ESC; + *pData = 0x40; + return 2; +} + +//******************************************************************************************************** +//** ƣprintSetChinese() +//** ܣĴӡ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t printChinese(uint8_t *pData) +{ + *pData++ = 0X1C; + *pData++ = '&'; + return 2; +} +//******************************************************************************************************** +//** ƣprintCR() +//** ܣӡǰ,һ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t printCR(uint8_t *pData) +{ + *pData = PCR; + return 1; +} + +//******************************************************************************************************** +//** ƣprintLF() +//** ܣֽ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t printLF(uint8_t *pData) +{ + *pData = LF; + return 1; +} + +//******************************************************************************************************** +//** ƣLFnRow() +//** ܣִУεֽ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t LFnRow(uint8_t *pData,uint8_t row) +{ + *pData++ = ESC; + *pData++ = J; + *pData = row; + return 3; +} +//******************************************************************************************************** +//** ƣsetPageLen() +//** ܣҳ +//** ڲҳ (ʾҳ) +//** ڲֽ +//*********************************************************************************************************/ +uint8_t setPageLen(uint8_t *pData,uint8_t pageLen) +{ + + *pData++ = ESC; + *pData++ = 0x43; + *pData = pageLen; + + return 3; +} + +//******************************************************************************************************** +//** ƣsetLeftSpace(uint8 spaceNumber) +//** ܣࡣ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t setLeftSpace(uint8_t *pData,uint8_t spaceNumber) +{ + *pData++ = ESC; + *pData++ = 0x6c; + *pData = spaceNumber; + + return 3; +} +//******************************************************************************************************** +//** ƣsetRightSpace(uint8 spaceNumber) +//** ܣҼࡣ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t setRightSpace(uint8_t *pData,uint8_t spaceNumber) +{ + *pData++ = ESC; + *pData++ = 0x51; + *pData = spaceNumber; + + return 3; +} +//******************************************************************************************************** +//** ƣsetWordSpace(uint8 wordSpace) +//** ܣּࡣ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t setWordSpace(uint8_t *pData, uint8_t wordSpace) +{ + *pData++ = ESC; + *pData++ = 0x70; + *pData = wordSpace; + + return 3; +} + +//******************************************************************************************************** +//** ƣsetRowSpace(uint8 rowSpace) +//** ܣּࡣ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t setRowSpace(uint8_t *pData, uint8_t rowSpace) +{ + *pData++ = ESC; + *pData++ = 0x31; + *pData = rowSpace; + return 3; +} +//F***************************************************************************** +//* NAME: +//* PURPOSE: +//* PARAMS: +//* return: +//****************************************************************************** + + + diff --git a/User/Printf/Printf.h b/User/Printf/Printf.h new file mode 100644 index 0000000..43b9977 --- /dev/null +++ b/User/Printf/Printf.h @@ -0,0 +1,75 @@ +#ifndef __Printf_H_ +#define __Printf_H_ +//Ӳ +#define PrintfUsart USART3 +#define Printf_DMA DMA1 + +#define Printf_TX_DMAAddrSet(x) (DMA1_Channel2->CMAR = x) //÷ͻַ +#define Printf_TX_DMALenSet(x) (DMA1_Channel2->CNDTR = x) //÷DMA +#define Printf_TX_DMAStart() DMA_Cmd(DMA1_Channel2,ENABLE) //DMA +#define Printf_TX_DMAStop() DMA_Cmd(DMA1_Channel2,DISABLE) //DMA +#define Printf_TX_DMAy_Channelx DMA1_Channel2 //PrintfʹõDMAͨ + + +#define USART3_Print GPIO_ResetBits(GPIOA,GPIO_Pin_4);//485ʹ + + +//============================================================================= +//ַ +#define LF 0x0a //ӡ +#define ESC 0X1B +#define J 0x4A +#define DLE 0X10 +#define EOT 0X04 +#define PCR 0X0D + +#define C_PrintPageLen 10 //ҳ +#define C_multiple 2 //Ŵ +#define C_leftSpace 1 // +#define C_rightSpace 0 // +#define C_wordSpace 1 //ּ +#define C_rowSpace 4 //м + +typedef enum +{ + noSend, + sending, +}printProStae_TypeDef; + +//****************************************************************************** +//*-------------- ----------------------------------------------------- +//****************************************************************************** + +//****************************************************************************** +//*-------------- ----------------------------------------------------- +//****************************************************************************** +extern void printUsartIsr(void); +extern void printTxDmaInt(void); +extern void printSend(u8 *pData, u8 len); +extern void Print_Num(u8 GunNum,u8 Lin,u64 Num,u8 Dec); +extern uint8_t print_init(uint8_t *pdata); +extern uint8_t printChinese(uint8_t *pData); +extern uint8_t printLF(uint8_t *pdata); +extern uint8_t printCR(uint8_t *pData); +extern uint8_t LFnRow(uint8_t *pData,uint8_t row); +extern uint8_t setPageLen(uint8_t *pData,uint8_t pageLen); +extern uint8_t setLeftSpace(uint8_t *pData,uint8_t spaceNumber); +extern uint8_t setRightSpace(uint8_t *pData,uint8_t spaceNumber); +extern uint8_t setWordSpace(uint8_t *pData, uint8_t wordSpace); +extern uint8_t setRowSpace(uint8_t *pData, uint8_t rowSpace); + + +typedef enum +{ + PT_Null, + PT_LastRecord, + PT_Record, + +}PrintItem; + +extern void Printf_DMATX_IRQHandler(void); + +extern void Printf_Init(void); +extern void PrintfTask(void); +void Printf_UpData(u8 GunNum, PrintItem Type); +#endif //#ifndef diff --git a/User/Printf/print.c b/User/Printf/print.c new file mode 100644 index 0000000..45ffe8b --- /dev/null +++ b/User/Printf/print.c @@ -0,0 +1,219 @@ +/*C***************************************************************************** +* NAME: print.c +*------------------------------------------------------------------------------- +* RELEASE: +* REVISION: 1.0 +*------------------------------------------------------------------------------- +* PURPOSE: +* +*******************************************************************************/ +/*_____ I N C L U D E S ______________________________________________________*/ + +#include "main_def.h" //ȫ + +uint8_t printBuf[gunNumber][C_printBuf]; +uint32_t printQueue[gunNumber][C_printQueue]; + +volatile printProStae_TypeDef printState = noSend; + + + +//****************************************************************************** +// printUsartIsr(void) ӡж +//****************************************************************************** +void printUsartIsr(void) +{ + //TCж + if((printUsart->SR & USART_FLAG_TC) != 0) + { + // printUsart->CR1 &= ~USART_Mode_Tx; + printUsart->CR1 &= ~USART_FLAG_TC; //ֹTCж + printUsart->SR &= ~USART_FLAG_TC; //TCжϱ־ + printState = noSend; + } + //RXж + else if((printUsart->SR & USART_FLAG_RXNE) != 0) + { + printUsart->CR1 &= ~USART_FLAG_RXNE; ///ֹж + printUsart->SR &= ~USART_FLAG_RXNE; ///ж + } +} + +//****************************************************************************** +// printTxDmaInt ӡDMAж +//****************************************************************************** +void printTxDmaInt(void) +{ + printT_DMAy_Channelx->CCR &= ~0x01; //ʹDMA + printT_DMAy_Channelx->CCR &= ~DMA_IT_TC; //ֹDMAж + print_DMA->IFCR |= 0X01 << ((printTxDmaChNb - 1)<< 2); ///DMAж + printUsart->CR1 |= USART_FLAG_TC; //ʹTCж + printUsart->CR3 &= ~(0X01 << 7); //ÿڷʹ +} + +//****************************************************************************** +//printSend +//****************************************************************************** +void printSend(uint8_t *pData, uint8_t len) +{ + printState = sending; + printUsart->CR1 &= ~USART_Mode_Rx; + printUsart->CR1 |= USART_Mode_Tx; + ///ʼĬֵ + //DMAݷ + printT_DMAy_Channelx->CMAR = (u32)pData; ///ʼԴĴַ + printT_DMAy_Channelx->CPAR = (u32)(&(printUsart->DR)); ///ʼĿļĴַ + printT_DMAy_Channelx->CNDTR = len; ///ʼݸ + //ʹܴDMA + print_DMA->IFCR |= 0X01 << ((printTxDmaChNb - 1) << 2); + printT_DMAy_Channelx->CCR |= DMA_IT_TC; ///ʹDMATCж + printT_DMAy_Channelx->CCR |= 0x01; ///ʹDMA + printUsart->SR &= ~USART_FLAG_TC ; ///TCжϱ־ + printUsart->CR1 &= ~USART_FLAG_TC ; ///ֹTCж + printUsart->CR3 &= ~(0x01 << 6); + printUsart->CR3 |= 0X01 << 7; //ôڴDMA +} + +//******************************************************************************************************** +//** ƣprint_init() +//** ܣӲʼ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t print_init(uint8_t *pData) +{ + *pData++ = ESC; + *pData = 0x40; + return 2; +} + +//******************************************************************************************************** +//** ƣprintSetChinese() +//** ܣĴӡ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t printChinese(uint8_t *pData) +{ + *pData++ = 0X1C; + *pData++ = '&'; + return 2; +} +//******************************************************************************************************** +//** ƣprintCR() +//** ܣӡǰ,һ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t printCR(uint8_t *pData) +{ + *pData = PCR; + return 1; +} + +//******************************************************************************************************** +//** ƣprintLF() +//** ܣֽ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t printLF(uint8_t *pData) +{ + *pData = LF; + return 1; +} + +//******************************************************************************************************** +//** ƣLFnRow() +//** ܣִУεֽ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t LFnRow(uint8_t *pData,uint8_t row) +{ + *pData++ = ESC; + *pData++ = J; + *pData = row; + return 3; +} +//******************************************************************************************************** +//** ƣsetPageLen() +//** ܣҳ +//** ڲҳ (ʾҳ) +//** ڲֽ +//*********************************************************************************************************/ +uint8_t setPageLen(uint8_t *pData,uint8_t pageLen) +{ + + *pData++ = ESC; + *pData++ = 0x43; + *pData = pageLen; + + return 3; +} + +//******************************************************************************************************** +//** ƣsetLeftSpace(uint8 spaceNumber) +//** ܣࡣ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t setLeftSpace(uint8_t *pData,uint8_t spaceNumber) +{ + *pData++ = ESC; + *pData++ = 0x6c; + *pData = spaceNumber; + + return 3; +} +//******************************************************************************************************** +//** ƣsetRightSpace(uint8 spaceNumber) +//** ܣҼࡣ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t setRightSpace(uint8_t *pData,uint8_t spaceNumber) +{ + *pData++ = ESC; + *pData++ = 0x51; + *pData = spaceNumber; + + return 3; +} +//******************************************************************************************************** +//** ƣsetWordSpace(uint8 wordSpace) +//** ܣּࡣ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t setWordSpace(uint8_t *pData, uint8_t wordSpace) +{ + *pData++ = ESC; + *pData++ = 0x70; + *pData = wordSpace; + + return 3; +} + +//******************************************************************************************************** +//** ƣsetRowSpace(uint8 rowSpace) +//** ܣּࡣ +//** ڲ +//** ڲֽ +//*********************************************************************************************************/ +uint8_t setRowSpace(uint8_t *pData, uint8_t rowSpace) +{ + *pData++ = ESC; + *pData++ = 0x31; + *pData = rowSpace; + return 3; +} +//F***************************************************************************** +//* NAME: +//* PURPOSE: +//* PARAMS: +//* return: +//****************************************************************************** + + + diff --git a/User/Printf/print.h b/User/Printf/print.h new file mode 100644 index 0000000..3179e23 --- /dev/null +++ b/User/Printf/print.h @@ -0,0 +1,71 @@ +#ifndef __PRINT_H_ +#define __PRINT_H_ +/*H****************************************************************************** +* NAME: time_count.h +*********************************************************************************/ +//Ӳ +#define printUsart USART3 +#define print_DMA DMA1 +#define printR_DMAy_Channelx DMA1_Channel3 +#define printT_DMAy_Channelx DMA1_Channel2 +#define printRxDmaChNb 3 +#define printTxDmaChNb 2 +// +#define C_printBuf 100 + +#define C_printQueue 80 //ӡϢ + + +//============================================================================= +//ַ +#define LF 0x0a //ӡ + +#define ESC 0X1B + +#define J 0x4A + +#define DLE 0X10 + +#define EOT 0X04 + +#define PCR 0X0D + + + +typedef enum +{ +noSend, +sending, +}printProStae_TypeDef; + + + + +//****************************************************************************** +//*-------------- ----------------------------------------------------- +//****************************************************************************** +extern uint8_t printBuf[gunNumber][C_printBuf]; +extern uint32_t printQueue[gunNumber][C_printQueue]; +extern volatile printProStae_TypeDef printState; + + + +//****************************************************************************** +//*-------------- ----------------------------------------------------- +//****************************************************************************** +extern void printUsartIsr(void); +extern void printTxDmaInt(void); +extern void printSend(u8 *pData, u8 len); + +extern uint8_t print_init(uint8_t *pdata); +extern uint8_t printChinese(uint8_t *pData); +extern uint8_t printLF(uint8_t *pdata); +extern uint8_t printCR(uint8_t *pData); +extern uint8_t LFnRow(uint8_t *pData,uint8_t row); +extern uint8_t setPageLen(uint8_t *pData,uint8_t pageLen); +extern uint8_t setLeftSpace(uint8_t *pData,uint8_t spaceNumber); +extern uint8_t setRightSpace(uint8_t *pData,uint8_t spaceNumber); +extern uint8_t setWordSpace(uint8_t *pData, uint8_t wordSpace); +extern uint8_t setRowSpace(uint8_t *pData, uint8_t rowSpace); + +#endif //#ifndef diff --git a/User/Pulse_InPut/Pluse_InPut.c b/User/Pulse_InPut/Pluse_InPut.c new file mode 100644 index 0000000..1c4b999 --- /dev/null +++ b/User/Pulse_InPut/Pluse_InPut.c @@ -0,0 +1,160 @@ +#include "config.h" + +/**************************************************** +Pluse_InPut_IO_Configuration + Pluse_InPutõIOʼ + +ֵ +****************************************************/ +void Pluse_InPut_IO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; //GOIPýṹ + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD| RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG, ENABLE); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; + GPIO_Init(GPIOE, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(GPIOG, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(GPIOD, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + GPIO_ResetBits(GPIOA,GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2); + GPIO_SetBits(GPIOD,GPIO_Pin_14 | GPIO_Pin_15); + GPIO_SetBits(GPIOE,GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13); + GPIO_ResetBits(GPIOE,GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7); + GPIO_SetBits(GPIOG,GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7); + GPIO_SetBits(GPIOA,GPIO_Pin_10); + if(Key1 == 1) + { + TXHData.BoardType = 1; //壬Ļ + } + else + TXHData.BoardType = 0; + +} +/**************************************************** +Pluse_InPut_EXTI_Configuration + ж() + +ֵ +****************************************************/ +void Pluse_InPut_EXTI_Configuration(void) +{ + EXTI_InitTypeDef EXTI_InitStructure; //жýṹ + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//ʹ SYSCFG ʱ + SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource0); + SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource1); + SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource8); + SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource9); + + /* EXTI_Line0 */ + EXTI_InitStructure.EXTI_Line = EXTI_Line0;//LINE0 + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//ж¼ + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //½ش + EXTI_InitStructure.EXTI_LineCmd = ENABLE;//ʹ LINE10 + EXTI_Init(&EXTI_InitStructure);// + /* EXTI_Line1 */ + EXTI_InitStructure.EXTI_Line = EXTI_Line1;//LINE1 + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//ж¼ + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //½ش + EXTI_InitStructure.EXTI_LineCmd = ENABLE;//ʹ LINE10 + EXTI_Init(&EXTI_InitStructure);// + +} +void Pluse_InPut_NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; + +// NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;//ⲿж 11 +// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;//ռȼ 0 +// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;//Ӧȼ 2 +// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//ʹⲿжͨ +// NVIC_Init(&NVIC_InitStructure);// NVIC + + /***************************ϵ****************************/ + NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//ⲿж 0 + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;//ռȼ 0 + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;//Ӧȼ 2 + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//ʹⲿжͨ + NVIC_Init(&NVIC_InitStructure);// NVIC + NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;//ⲿж 1 + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;//ռȼ 0 + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;//Ӧȼ 2 + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//ʹⲿжͨ + NVIC_Init(&NVIC_InitStructure);// NVIC + +} +void Pluse_InPut_Init(void) +{ + Pluse_InPut_IO_Configuration(); + delay_ms(100); + Pluse_InPut_EXTI_Configuration(); + Pluse_InPut_NVIC_Configuration(); + if(POS_Wireless == SWF_ON) + { + if(POS_URL == SWF_ON) + TXHData.POS_Info.ConnectType = POS_Connect_Typ_Cloud_Tast; + else + TXHData.POS_Info.ConnectType = POS_Connect_Typ_Cloud; + + TXHData.POS_Info.NetType = ~((POS_NetTypeH << 1) | POS_NetTypeL); + TXHData.POS_Info.NetType &= 0x03; + } + else + { + TXHData.POS_Info.ConnectType = POS_Connect_Typ_Station; + } + if(POS_Monitor == SWF_ON) + TXHData.POS_MonitorModel = 1; + else + TXHData.POS_MonitorModel = 0; + TXHData.HardwareVersion = ((HV4 << 4) | (HV3 << 3) | (HV2 << 2) | (HV1 << 1) | HV0) + 24;//λ1ʾС塣0ʾ׼ + +} +void Pluse_InPut_IRQHandler(void) +{ + u8 i = 0; + /****************Ͽ1***************/ + if(EXTI_GetITStatus(EXTI_Line8) != RESET) + { + + EXTI_ClearITPendingBit(EXTI_Line8); + } + /****************Ͽ2***************/ + if(EXTI_GetITStatus(EXTI_Line9) != RESET) + { + + EXTI_ClearITPendingBit(EXTI_Line9); + } + /*******************************/ + if(EXTI_GetITStatus(EXTI_Line0) != RESET) + { + TXHData.PowerDown.Flag.Power10V = 1 - PowerLow10V; + EXTI_ClearITPendingBit(EXTI_Line10); + } + if(EXTI_GetITStatus(EXTI_Line1) != RESET) + { + TXHData.PowerDown.Flag.Power7V = 1 - PowerLow7V; + EXTI_ClearITPendingBit(EXTI_Line10); + } +} diff --git a/User/Pulse_InPut/Pluse_InPut.h b/User/Pulse_InPut/Pluse_InPut.h new file mode 100644 index 0000000..2373f28 --- /dev/null +++ b/User/Pulse_InPut/Pluse_InPut.h @@ -0,0 +1,52 @@ +#ifndef __PLUSE_INPUT_H__ +#define __PLUSE_INPUT_H__ + +#define SWF1 GPIODin(14) +#define SWF2 GPIODin(15) +#define SWF3 GPIOGin(2) +#define SWF4 GPIOGin(3) + +#define SWF5 GPIOGin(4) +#define SWF6 GPIOGin(5) +#define SWF7 GPIOGin(6) +#define SWF8 GPIOGin(7) + +#define URGENCY1 GPIOEin(8) +#define URGENCY2 GPIOEin(9) + +#define Key1 GPIOEin(10) +#define Key2 GPIOEin(11) +#define Key3 GPIOEin(12) +#define Key4 GPIOEin(13) + +#define HV0 GPIOEin(3) +#define HV1 GPIOEin(4) +#define HV2 GPIOEin(5) +#define HV3 GPIOEin(6) +#define HV4 GPIOEin(7) + +#define POS_4G_NET GPIOAin(0) +#define POS_4G_LinkB GPIOAin(1) +#define POS_4G_LinkA GPIOAin(2) + +#define PowerLow10V GPIOEin(0) +#define PowerLow7V GPIOEin(1) + +#define SWF_OFF 1 +#define SWF_ON 0 + + +#define POS_Wireless SWF2// +#define POS_NetTypeL SWF3// +#define POS_NetTypeH SWF4// +#define POS_Monitor SWF6//ONģʽ +#define POS_URL SWF7//ONԷ + + + +extern void Pluse_InPut_Init(void); +extern void Pluse_InPut_IRQHandler(void); + +//------------------------------------------------------------------------------ + +#endif diff --git a/User/Pulse_PutOut/Pluse_Putout.c b/User/Pulse_PutOut/Pluse_Putout.c new file mode 100644 index 0000000..75a1256 --- /dev/null +++ b/User/Pulse_PutOut/Pluse_Putout.c @@ -0,0 +1,43 @@ +#include "config.h" +/**************************************************** +Pluse_Putout_IO_Configuration + Pluse_PutoutõIOʼ + +ֵ +****************************************************/ +void Pluse_Putout_IO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; //GOIPýṹ + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE, ENABLE); + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_14 | GPIO_Pin_15; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//ͨģʽ + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;// + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// + GPIO_Init(GPIOE, &GPIO_InitStructure); + GPIO_ResetBits(GPIOE,GPIO_Pin_2); + + if(TXHData.POS_Info.NetType == POS_Net_Typ_WAN || TXHData.POS_Info.NetType == POS_Net_Typ_4G_L510) + { + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//ͨģʽ + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;// + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// + GPIO_Init(GPIOA, &GPIO_InitStructure); + GPIO_ResetBits(GPIOA,GPIO_Pin_2); + } + + Valve1 = SWF_OFF; + Valve2 = SWF_OFF; +} + +void Pluse_Putout_Init(void) +{ + Pluse_Putout_IO_Configuration(); +} +void Pluse_PutoutTast(void) +{ + u8 Buff[20]; +} diff --git a/User/Pulse_PutOut/Pluse_Putout.h b/User/Pulse_PutOut/Pluse_Putout.h new file mode 100644 index 0000000..d36c496 --- /dev/null +++ b/User/Pulse_PutOut/Pluse_Putout.h @@ -0,0 +1,18 @@ +#ifndef __PLUSE_PUTOUT_H__ +#define __PLUSE_PUTOUT_H__ + +#define POS_LinkA_Out GPIOAout(2) + +#define Valve1 GPIOEout(14) +#define Valve2 GPIOEout(15) + +#define BEEP GPIOEout(2) +#define BEEP_ON BEEP = 1 +#define BEEP_OFF BEEP = 0 + +extern void Pluse_Putout_Init(void); +extern void Pluse_PutoutTast(void); + +//------------------------------------------------------------------------------ + +#endif diff --git a/User/SensorCount/SensorCount.c b/User/SensorCount/SensorCount.c new file mode 100644 index 0000000..6219d26 --- /dev/null +++ b/User/SensorCount/SensorCount.c @@ -0,0 +1,295 @@ +#include "config.h" + + +volatile u8 SensorCount2TXTask_Flag = 1;//SensorCount־λ1 +volatile u8 SensorCount_DMA_RX_Len = 23; +/*_____ D E F I N I T I O N __________________________________________________*/ + + +/**************************************************** +SensorCount_IO_Configuration + SensorCount ModBusͨѶõIOʼ + +ֵ +****************************************************/ +void SensorCount_IO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); + + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); + GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5); + + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOC, &GPIO_InitStructure); + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; + GPIO_Init(GPIOD, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//ͨģʽ + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;// + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// + GPIO_Init(GPIOD, &GPIO_InitStructure);//ʼ + + Sensor2_RS485_RxEN; +} +/**************************************************** +SensorCount_NVIC_Configuration + SensorCount ModBusͨѶUsart1ͷDMAж + +ֵ +****************************************************/ +void SensorCount_NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; //жýṹ + + //USART5_DMA + + NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream7_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream0_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + +} + +/************************************************* + SensorCount_USART_Configuration + : ڳʼ + +ֵ +**************************************************/ +void SensorCount_USART_Configuration(u32 Baud,u8 Check) +{ + USART_InitTypeDef USART_InitStructure; + + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); + USART_InitStructure.USART_BaudRate =Baud;// Baud;//????? + + if(Check == Even) + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + USART_InitStructure.USART_Parity = USART_Parity_Even; + } + else if(Check == None) + { + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_Parity = USART_Parity_No; + } + + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + USART_Init(UART5, &USART_InitStructure); + USART_Cmd(UART5, ENABLE); + + + USART_DMACmd(UART5, USART_DMAReq_Tx | USART_DMAReq_Rx,ENABLE); + +} +/************************************************* + DMA_Configuration + DMAʼ + +ֵ +**************************************************/ +void SensorCount_DMA_Configuration(void) +{ + DMA_InitTypeDef DMA_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); + + /*******************TX*********************/ + DMA_DeInit(DMA1_Stream7); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + //DMA_InitStructure.DMA_BufferSize = UART_DMA_SEND_LEN; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&UART5->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + + + DMA_Init(DMA1_Stream7, &DMA_InitStructure); + DMA_ITConfig(DMA1_Stream7, DMA_IT_TC, ENABLE); + //DMA_Cmd(DMA1_Stream3, ENABLE); + + /*******************RX*********************/ + DMA_DeInit(DMA1_Stream0); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = 23; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&UART5->DR; + DMA_InitStructure.DMA_Channel = DMA_Channel_4; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)YWYData.SensorMail.Buff; + + + DMA_Init(DMA1_Stream0, &DMA_InitStructure); + DMA_ITConfig(DMA1_Stream0, DMA_IT_TC, ENABLE); + DMA_ClearFlag(DMA1_Stream0, DMA_IT_TCIF0); + DMA_Cmd(DMA1_Stream0, ENABLE); +} + +//F***************************************************************************** +//* NAME: SensorCount2_DMATX_IRQHandler +//* PURPOSE: DMAжϣSensorCount ModBus +//* PARAMS: +//* return: +//****************************************************************************** +void SensorCount2_DMATX_IRQHandler(void) +{ + SensorCount2_TX_DMAStop(); //رDMA (SensorCount) + /**********************DRĴݿDMAʱԶһݣȼһӦԷж賤ȣDMAжϹرDMA賤ȣDMA********************/ + SensorCount2_RX_DMAStop(); + SensorCount2_RX_DMALenSet(SensorCount_DMA_RX_Len);//ýܳ + + DMA_ClearFlag(DMA1_Stream7, DMA_IT_TCIF7); + while(! USART_GetFlagStatus(UART5, USART_FLAG_TC))NULL; + Sensor2_RS485_RxEN; + SensorCount2TXTask_Flag = 1; + + SensorCount2_RX_DMAStart(); + +} +//F***************************************************************************** +//* NAME: SensorCount_DMARX_IRQHandler +//* PURPOSE: DMAжϣSensorCount ModBus +//* PARAMS: +//* return: +//****************************************************************************** +void SensorCount2_DMARX_IRQHandler(void) +{ + u16 CRC_Temp; + SensorCount2_RX_DMAStop(); //DMA + DMA_ClearFlag(DMA1_Stream0, DMA_IT_TCIF0); + + SensorCount2_RX_DMAAddrSet((u32)YWYData.SensorMail.Buff); + SensorCount2_RX_DMALenSet(SensorCount_DMA_RX_Len);//ýܳ + SensorCount2_RX_DMAStart(); + + CRC_Temp = CRC_Check(YWYData.SensorMail.Buff,YWYData.SensorMail.Register.Len + 3); + if(CRC_Temp == YWYData.SensorMail.Register.Crc) + { + YWYData.SensorMail_Flag = 1; //ʹLcdCount + } + + //ʹLcdCount +} +//F***************************************************************************** +//* NAME: SensorCount_Init +//* PURPOSE: SensorCountͨѶʼ +//* PARAMS: +//* return: +//****************************************************************************** +void SensorCount_Init(void) +{ + u8 i = 0; + SensorCount_IO_Configuration(); + SensorCount_USART_Configuration(9600,None); + SensorCount_DMA_Configuration(); + SensorCount_NVIC_Configuration(); + + YWYData.Sensor_Ask_Timer.Init = 0; //ʼ־ + YWYData.Sensor_Ask_Timer.Flag = 1; //ʱ־ + YWYData.Sensor_Ask_Timer.ON_OFF = 1; //ѵ + YWYData.Sensor_Ask_Timer.Cycle = 1; //Ϊѭģʽ + YWYData.Sensor_Ask_Timer.TimerCountMax = 100; //1001SSensor_ERR_Timer + + YWYData.Sensor_ERR_Timer[0].Init = 0; //ʼ־ + YWYData.Sensor_ERR_Timer[0].Flag = 0; //ʱ־ + YWYData.Sensor_ERR_Timer[0].ON_OFF = 1; //ѵ + YWYData.Sensor_ERR_Timer[0].Cycle = 1; //Ϊѭģʽ + YWYData.Sensor_ERR_Timer[0].TimerCountMax = 200; //1001SSensor_ERR_Timer + + YWYData.Sensor_ERR_Timer[1].Init = 0; //ʼ־ + YWYData.Sensor_ERR_Timer[1].Flag = 0; //ʱ־ + YWYData.Sensor_ERR_Timer[1].ON_OFF = 1; //ѵ + YWYData.Sensor_ERR_Timer[1].Cycle = 1; //Ϊѭģʽ + YWYData.Sensor_ERR_Timer[1].TimerCountMax = 200; //1001S + + YWYData.PowerOffDelay_Timer.Init = 0; //ʼ־ + YWYData.PowerOffDelay_Timer.Flag = 0; //ʱ־ + YWYData.PowerOffDelay_Timer.ON_OFF = 0; //ѵ + YWYData.PowerOffDelay_Timer.Cycle = 0; //Ϊѭģʽ + YWYData.PowerOffDelay_Timer.TimerCountMax = 6000; //600060S + +} + +/***********RS485/̽************ + +***************************************** +*****************************************/ +u8 Sensor_TX_Buff[10] = {0x00,0x03,0x00,0x02,0x00,0x01,0x00,0x00}; +u8 Sensor_Ask_Data(u8 ID)// +{ + + u16 i = 10; + u16 CRC_Temp = 0; + + Sensor2_RS485_TxEN; + SensorCount2TXTask_Flag = 0; + Sensor_TX_Buff[0] = ID + 1; + CRC_Temp = CRC_Check(Sensor_TX_Buff,6); + Sensor_TX_Buff[7] = CRC_Temp >> 8; + Sensor_TX_Buff[6] = CRC_Temp; + + SensorCount2_TX_DMAAddrSet((u32)Sensor_TX_Buff); + SensorCount2_TX_DMALenSet(8); + SensorCount2_TX_DMAStart(); + SensorCount_DMA_RX_Len = 7; +} +u8 Sensor_Ask_NumNow = 0; +void Sensor_Tast(void) +{ + if(YWYData.Sensor_Ask_Timer.Flag == 1) + { + YWYData.Sensor_Ask_Timer.Flag = 0; + Sensor_Ask_Data(Sensor_Ask_NumNow); + Sensor_Ask_NumNow ++; + if(Sensor_Ask_NumNow > 1) + Sensor_Ask_NumNow = 0; + } + + if(YWYData.SensorMail_Flag == 1) + { + YWYData.SensorMail_Flag = 0; + if(YWYData.SensorMail.Register.SensorNum < 3) + { + if(YWYData.SensorMail.Register.Dat != 0x0200) + YWYData.ErrState[YWYData.SensorMail.Register.SensorNum - 1].Flag.GasLeakage = 0; + else + YWYData.ErrState[YWYData.SensorMail.Register.SensorNum - 1].Flag.GasLeakage = 1; + } + } + } \ No newline at end of file diff --git a/User/SensorCount/SensorCount.h b/User/SensorCount/SensorCount.h new file mode 100644 index 0000000..65d7311 --- /dev/null +++ b/User/SensorCount/SensorCount.h @@ -0,0 +1,50 @@ +#ifndef __SensorCount_H_ +#define __SensorCount_H_ +/*H****************************************************************************** +* NAME: SensorCount.h +*********************************************************************************/ + +typedef union +{ + u8 Buff[50]; //ModBusĴ + __packed struct + { + u8 SensorNum : 8; + u8 Cmd : 8; + u8 Len : 8; + u16 Dat : 16; + u16 Crc : 16; + }Register; +}Sensor_RX_Buff_Type; + +//****************************************************************************** +//*-------------- ----------------------------------------------------- +//****************************************************************************** +#define SensorCount2_TX_DMAAddrSet(x) (DMA1_Stream7->M0AR = x) //Ʒͻַ +#define SensorCount2_TX_DMALenSet(x) (DMA1_Stream7->NDTR = x) //DMAͳ +#define SensorCount2_TX_DMAStart() DMA_Cmd(DMA1_Stream7,ENABLE) //DMA +#define SensorCount2_TX_DMAStop() DMA_Cmd(DMA1_Stream7,DISABLE) //رDMA + +#define SensorCount2_RX_DMAAddrSet(x) (DMA1_Stream0->M0AR = x) //ƽջַ +#define SensorCount2_RX_DMALenSet(x) (DMA1_Stream0->NDTR = x) //DMA +#define SensorCount2_RX_DMAStart() DMA_Cmd(DMA1_Stream0,ENABLE) //DMA +#define SensorCount2_RX_DMAStop() DMA_Cmd(DMA1_Stream0,DISABLE) //رDMA + +#define Sensor2_RS485_TxEN GPIO_ResetBits(GPIOD,GPIO_Pin_3); +#define Sensor2_RS485_RxEN GPIO_SetBits(GPIOD,GPIO_Pin_3); + + +#define Even 0 +#define None 1 + + +extern void SensorCount2_DMATX_IRQHandler(void); +extern void SensorCount2_DMARX_IRQHandler(void); + +extern u16 CRC_Check(u8 *puchMsg, u16 usDataLen) ; +extern u16 BigToLittle( u16 BigData); +extern void SensorCount_Init(void); +extern void SensorCount_USART_Configuration(u32 Baud,u8 Check); +extern u8 Sensor_Ask_Data(u8 ID); +extern void Sensor_Tast(void); +#endif //#ifndef diff --git a/User/Surface/Surface.c b/User/Surface/Surface.c new file mode 100644 index 0000000..d069cb9 --- /dev/null +++ b/User/Surface/Surface.c @@ -0,0 +1,1433 @@ +#include "config.h" +#include "bmp.h" +const u8 QueryMenu[][16] = { + "1.Network Info ", + "2.MD Port Info ", + "3.LORA RSSI ", + "4.Veresion Check", + "5.Test Info. ", + "1.Network Info ", + "2.MD Port Info ", + "3.LORA RSSI ", +}; +const u8 QueryNetworkInfo[][16] = { + " Network Info ", + " ", + " ", + " ", +}; +const u8 PrintInfo[][16] = { + "Print [Gun: ] ", + " ", + " ", + " ", +}; +const u8 QueryMDPortInfo[][16] = { + " PORT ", + " ", + " ", + " ", +}; +const u8 QueryTestInfo[][16] = { + " PORT ", + " ", + " ", + " ", +}; +/* + PosNormal, + PosBlueSky, + PosLY, + PosJP, + PosDart, + PosYWY, + PosRFID, + PosYGao, + PosHongYang, + PosLanFeng,*/ +const u8 QueryMDPortInfo_POSType[][16] = { + "Empty", + "BlueSky", + "LY", + "JP", + "Dart", + "YWY_Bluesky", + "RFID", + "YGao", + "HYang", + "SS-Lan", + "BlueSkyPlus", + "PLC", + "Price"}; +const u8 YWY_Type_Info[][16] = { + "YWY_Bluesky", + "Probe_KY", + "YWY_Pressure", +}; +const u8 QueryLORARSSI[][16] = { + " PORT ", + " ", + " ", + " ", +}; +const u8 QueryVeresion[][16] = { + " Veresion ", + " ", + " ", + " ", +}; +const u8 SetMenu[][16] = { + "1.MDConnect Set ", + "2.LORA Slave Set", + "3.PortLog Output", + "4.Connect Mode ", + "5.Network Set ", + "6.DataInit ", + "1.MDConnect Set ", + "2.LORA Slave Set", + "3.PortLog Output", +}; +const u8 SetMDConnect[][16] = { + " MDConnect Set ", + " ", + " ", + " ", +}; +const u8 SetLORASlave[][16] = { + " LORA Slave Set ", + " ", + " ", + " ", +}; +const u8 SetPortLogOutput[][16] = { + " PortLog Output ", + " ", + " ", + " ", +}; +const u8 SetConnectMode[][16] = { + " Connect Mode ", + " ", + " ", + "Press | to shift", +}; +const u8 SetNetworkSet[][16] = { + " Network Set ", + " ", + " ", + "Press | to shift", +}; +const u8 ConnectMode_Info[][16] = { + "Now:Dial switch ", + "Now:Station ", + "Now:Cloud ", + "Now:Test Cloud ", + "Now:Wifi Station", +}; +const u8 Network_Type_Info[][16] = { + "Now:Dial switch ", + "Now:4G_GM5 ", + "Now:4G_L510 ", + "Now:WiFi ", + "Now:WAN ", +}; +const u8 SetDataInit[][16] = { + "Initialize Data?", + " ", + " ", + "'ENTER' to shift", +}; +void Surface_Copy_16(const u8 *Buff, u8 StLine, u8 Num) // ת�Ƶ����� +{ + u8 i, j; + for (j = 0; j < Num; j++) + { + for (i = 0; i < 16; i++) + OLED_ShowChar(i * 8, j * 16, *(Buff + i + StLine * 16 + j * 16), 16, 1); + } +} +void SurfaceJump(u8 Surface) +{ + TXHData.SurfaceNow = Surface; + TXHData.DisplayOn = 1; + // TXHData.SurfaceNowLine = 0; +} +void Surface_Init(void) +{ + TXHData.KeyFindTimer.Init = 0; // �����ʼ����־ + TXHData.KeyFindTimer.Flag = 0; // �����ʱ��־ + TXHData.KeyFindTimer.ON_OFF = 1; // �� + TXHData.KeyFindTimer.Cycle = 1; // ����Ϊѭ��ģʽ������ʱ + TXHData.KeyFindTimer.TimerCountMax = 100; // ����0.1�� + TXHData.DisplayOn = 1; + SurfaceJump(Surface_Wait); +} +u8 KeyNumBefore = 0; +u8 KeyNumconfirm_Flag = 0; +u8 KeyNum0 = 0; +u8 KeyNum1 = 0; +u8 KeyNum = 0; +void FindKey(void) +{ + if (TXHData.KeyFindTimer.Flag == 1) + { + TXHData.KeyFindTimer.Flag = 0; + if (KeyNumconfirm_Flag == 0) + { + KeyNumconfirm_Flag = 1; + KeyNum0 = ~((Key4 << 3) | (Key3 << 2) | (Key2 << 1) | Key1) & 0x0f; + } + else + { + KeyNumconfirm_Flag = 0; + KeyNum1 = ~((Key4 << 3) | (Key3 << 2) | (Key2 << 1) | Key1) & 0x0f; + } + if (KeyNum0 == KeyNum1) + { + KeyNum = KeyNum0; + if (KeyNum != KeyNumBefore) + { + TXHData.KeyNum = KeyNum; + KeyNumBefore = KeyNum; + if (KeyNum) + TXHData.DisplayOn = 1; + } + } + } +} +u8 GetKeyNum(void) +{ + u8 K = TXHData.KeyNum; + TXHData.KeyNum = 0; + return K; +} + +void Sureface_Wait_TimeUpData(void) +{ + u8 X_Now = 4, Y_Now = 56; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.CTIME.Hour), 0, 0, 8, 1); + OLED_ShowChar(6 * X_Now, Y_Now, '-', 8, 1); + X_Now++; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.CTIME.Min), 0, 0, 8, 1); + OLED_ShowChar(6 * X_Now, Y_Now, '-', 8, 1); + X_Now++; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.CTIME.Sec), 0, 0, 8, 1); + OLED_ShowChar(6 * X_Now, Y_Now, ' ', 8, 1); + X_Now++; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.CTIME.Year), 0, 0, 8, 1); + OLED_ShowChar(6 * X_Now, Y_Now, '-', 8, 1); + X_Now++; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.CTIME.Month), 0, 0, 8, 1); + OLED_ShowChar(6 * X_Now, Y_Now, '-', 8, 1); + X_Now++; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.CTIME.Day), 0, 0, 8, 1); +} +void SurfaceTast(void) +{ + u16 i = 0, j = 0, X_Now = 0, Y_Now = 0, MD_Port = 0; + u8 Buff[21]; + FindKey(); + if (TXHData.DisplayOn) + { + TXHData.DisplayOn = 0; + OLED_Clear(); + switch (TXHData.SurfaceNow) + { + case Surface_FirmwareUpdate: + { + switch (GetKeyNum()) + { + case 0x01: + { + } + break; + case 0x02: + { + } + break; + case 0x04: + { + } + break; + case 0x08: + { + SurfaceJump(Surface_Wait); + TXHData.ROM_UpData_ProgressBar = 0; + } + break; + } + OLED_ShowString(0, 0, "FirmwareDownload", 21, 16, 1); + if (TXHData.ROM_UpData_Port) + { + OLED_ShowString(0, 20, "Port:", 5, 8, 1); + OLED_ShowNum(30, 20, TXHData.ROM_UpData_Port, 0, 0, 8, 1); + OLED_ShowString(40, 20, TXHData.MD_Port_Data[TXHData.ROM_UpData_Port - 1].PortData.ROM_UpData_Version, 10, 8, 1); + } + if (TXHData.ROM_UpData_ProgressBar == 0xFF) + { + OLED_ShowString(20, 45, "Download Fail!", 21, 8, 1); + } + else + { + OLED_ProgressBar(10, 30, 100, 10, TXHData.ROM_UpData_ProgressBar, 1); + i = OLED_ShowNum(50, 45, TXHData.ROM_UpData_ProgressBar, 0, 0, 8, 1); + OLED_ShowChar(50 + i * 6, 45, '%', 8, 1); + if (TXHData.ROM_UpData_ProgressBar == 100) + { + TXHData.ROM_UpData_ProgressBar = 0; + SurfaceJump(Surface_Wait); + } + } + } + break; + case Surface_OfflineRecordUpload: // ���߼�¼�ϴ����� + { + switch (GetKeyNum()) + { + case 0x01: + { + } + break; + case 0x02: + { + } + break; + case 0x04: + { + SurfaceJump(Surface_SetMenu); + } + break; + case 0x08: + { + SurfaceJump(Surface_QueryMenu); + } + break; + } + if (TXHData.POS_Info.Link_Flag == 0) + OLED_ShowString(0, 0, "No Signal", 21, 8, 1); + else + { + switch (TXHData.POS_Info.ConnectType) + { + case POS_Connect_Typ_Station: + OLED_ShowString(0, 0, "Type:Station", 21, 8, 1); + break; + case POS_Connect_Typ_Cloud: + OLED_ShowString(0, 0, "Type:Cloud", 21, 8, 1); + break; + case POS_Connect_Typ_Cloud_Tast: + OLED_ShowString(0, 0, "Type:Cloud-Test", 21, 8, 1); + break; + } + } + switch (TXHData.USART6_Drive) + { + case Bluetooth: + { + OLED_ShowPicture(0, 10, 9, 9, (u8 *)BMP_Bluetooth_9, 1); + } + break; + case GPS: + { + OLED_ShowPicture(0, 10, 9, 9, (u8 *)BMP_GPS_9, 1); + } + break; + } + OLED_ShowPicture(104, 0, 24, 24, (u8 *)BMP_Bluesky_Con_24, 1); + OLED_ShowString(0, 26, "Offline Record Upload", 21, 8, 1); + OLED_ShowString(0, 36, "Record number:", 21, 8, 1); + OLED_ShowNum(84, 36, TXHData.PREXDATA_WaitUpNummber, 0, 0, 8, 1); + if (TXHData.PREXDATA_WaitUpNummber == 0) + { + SurfaceJump(Surface_Wait); + } + Sureface_Wait_TimeUpData(); + } + break; + case Surface_Wait: // �������� + { + switch (GetKeyNum()) + { + case 0x01: + { + SurfaceJump(Surface_PrintInfo); + TXHData.ROM_UpData.ROM_UpData_State.Flag.DisableUpdate = 0; + } + break; + case 0x02: + { + TXHData.ROM_UpData.ROM_UpData_State.Flag.DisableUpdate = 0; + SurfaceJump(Surface_PrintInfo); + } + break; + case 0x04: + { + TXHData.ROM_UpData.ROM_UpData_State.Flag.DisableUpdate = 0; + SurfaceJump(Surface_SetMenu); + } + break; + case 0x08: + { + TXHData.ROM_UpData.ROM_UpData_State.Flag.DisableUpdate = 0; + SurfaceJump(Surface_QueryMenu); + } + break; + } + if (TXHData.POS_Info.Link_Flag == 0) + OLED_ShowString(0, 0, "Offline", 21, 8, 1); + else + { + switch (TXHData.POS_Info.ConnectType) + { + case POS_Connect_Typ_Station: + OLED_ShowString(0, 0, "Type:Station", 21, 8, 1); + break; + case POS_Connect_Typ_Cloud: + OLED_ShowString(0, 0, "Type:Cloud", 21, 8, 1); + break; + case POS_Connect_Typ_Cloud_Tast: + OLED_ShowString(0, 0, "Type:Cloud-Test", 21, 8, 1); + break; + } + // if(TXHData.POS_TX_CMDNow == POSConnect_PREXDATAUp) + { + + // SurfaceJump(Surface_OfflineRecordUpload); + } + } + switch (TXHData.USART6_Drive) + { + case Bluetooth: + { + OLED_ShowPicture(0, 20, 9, 9, (u8 *)BMP_Bluetooth_9, 1); + } + break; + case GPS: + { + if (TXHData.GPSData.GPS.Latitude + TXHData.GPSData.GPS.Longitude) + OLED_ShowPicture(0, 20, 9, 9, (u8 *)BMP_GPS_9, 1); + else + OLED_ShowPicture(0, 20, 9, 9, (u8 *)BMP_GPS_None_9, 1); + } + break; + } + if (TXHData.ROM_UpData_ProgressBar) + { + SurfaceJump(Surface_FirmwareUpdate); + } + if (TXHData.POS_Info.ConnectType != POS_Connect_Typ_Station) // վ�� + { + if (TXHData.POS_Info.NetType == POS_Net_Typ_WiFi) + { + if (POS_4G_NET) + { + if (TXHData.POS_Info.WiFiRSSI < 50) + OLED_ShowPicture(89, 0, 14, 8, (u8 *)BMP_WIFI4_14x8, 1); + else if (TXHData.POS_Info.WiFiRSSI < 60) + OLED_ShowPicture(89, 0, 14, 8, (u8 *)BMP_WIFI3_14x8, 1); + else if (TXHData.POS_Info.WiFiRSSI < 70) + OLED_ShowPicture(89, 0, 14, 8, (u8 *)BMP_WIFI2_14x8, 1); + else + OLED_ShowPicture(89, 0, 14, 8, (u8 *)BMP_WIFI1_14x8, 1); + } + else + { + OLED_ShowPicture(89, 0, 14, 8, (u8 *)BMP_WIFI0_14x8, 1); + } + } + else if (TXHData.POS_Info.NetType == POS_Net_Typ_4G_L510 || TXHData.POS_Info.NetType == POS_Net_Typ_4G_GM5) + { + if (TXHData.POS_Info.WiFiRSSI < 32) + { + if (TXHData.POS_Info.WiFiRSSI > 26) + OLED_ShowPicture(89, 0, 14, 8, (u8 *)BMP_WIFI4_14x8, 1); + else if (TXHData.POS_Info.WiFiRSSI > 23) + OLED_ShowPicture(89, 0, 14, 8, (u8 *)BMP_WIFI3_14x8, 1); + else if (TXHData.POS_Info.WiFiRSSI > 20) + OLED_ShowPicture(89, 0, 14, 8, (u8 *)BMP_WIFI2_14x8, 1); + else if (TXHData.POS_Info.WiFiRSSI > 18) + OLED_ShowPicture(89, 0, 14, 8, (u8 *)BMP_WIFI1_14x8, 1); + else + OLED_ShowPicture(89, 0, 14, 8, (u8 *)BMP_WIFI0_14x8, 1); + } + } + } + OLED_ShowPicture(104, 0, 24, 24, (u8 *)BMP_Bluesky_Con_24, 1); + OLED_ShowString(40, 20, "BLUESKY", 16, 16, 1); + OLED_ShowString(18, 36, "ENERGY TECHNOLOGY", 21, 8, 1); + if (TXHData.PREXDATA_WaitUpNummber > 0) + { + sprintf(Buff, "WaitUpload:%d/%d", TXHData.PREXDATA_WaitUpNummber, TXHData.OfflineAuthorizeNumberMax); + OLED_ShowString(0, 46, Buff, 21, 8, 1); + } + if (TXHData.ROM_UpData.ROM_UpData_State.Flag.DisableUpdate == 1) + OLED_ShowString(0, 46, "Upgrade ERR Check Gun", 21, 8, 1); + Sureface_Wait_TimeUpData(); + if (TXHData.POSNetSetState.Flag.WorkMode == 1) // ͸��ģʽ + { + sprintf(&Buff[0], "%02x", TXHData.POS_Info.POS_CMD_Next); + OLED_ShowString(0, 56, Buff, 2, 8, 1); + } + else + { + sprintf(&Buff[0], "%02x", TXHData.POSNetSetState.Flag.POSNetCMDNext); + OLED_ShowString(0, 56, Buff, 2, 8, 1); + // OLED_ShowNum(0,56,TXHData.POSNetSetState.Flag.POSNetCMDNext,0,0,8,1); + } + if (TXHData.DelayDetectionTimer.Flag) + { + OLED_ShowString(0, 10, "Blockage", 21, 8, 1); + } + else + { + sprintf(&Buff[0], "%dms", TXHData.DelayDetection); + OLED_ShowString(0, 10, Buff, 10, 8, 1); + } + if (TXHData.ErrState.Flag.e_errPCBCheck == 1) + { + OLED_ShowString(0, 46, "PCB Validation Failed", 21, 8, 1); + } + } + break; + case Surface_PrintInfo: // ��ӡ���� + { + switch (GetKeyNum()) + { + case 0x01: + { + i = 0; + for (; TXHData.SurfaceNowItem >= 0;) + { + i++; + if (i > 64) + break; + if (TXHData.SurfaceNowItem > 0) + TXHData.SurfaceNowItem--; + else + TXHData.SurfaceNowItem = 63; + if (TXHData.PrintLastRecord[TXHData.SurfaceNowItem].GunNumber != 0) + break; + } + } + break; + case 0x02: + { + i = 0; + for (; TXHData.SurfaceNowItem < 64;) + { + i++; + if (i > 64) + break; + if (TXHData.SurfaceNowItem < 63) + TXHData.SurfaceNowItem++; + else + TXHData.SurfaceNowItem = 0; + if (TXHData.PrintLastRecord[TXHData.SurfaceNowItem].GunNumber != 0) + break; + } + } + break; + case 0x04: + { + TXHData.MD_Multiplex_Port_Info.PrintPlaceNumber = TXHData.SurfaceNowItem; + TXHData.MD_Multiplex_Port_Info.PrintType = PT_LastRecord; + // Printf_UpData(TXHData.SurfaceNowLine,PT_LastRecord); + } + break; + case 0x08: + { + SurfaceJump(Surface_Wait); + TXHData.SurfaceNowItem = 0; + } + break; + } + if (TXHData.SurfaceNow == Surface_PrintInfo) + { + MD_Port = TXHData.SurfaceNowItem / 16; + Surface_Copy_16(PrintInfo[0], 0, 1); + OLED_ShowNum(88, 0, TXHData.PrintLastRecord[TXHData.SurfaceNowItem].GunNumber, 0, 0, 16, 1); + OLED_ShowString(0, 16, "L: ", 16, 16, 1); + OLED_ShowNum(3 * 8, 16, MD_Connect_BCDTou64(TXHData.PrintLastRecord[TXHData.SurfaceNowItem].FData.OilCNT), 0, TXHData.MD_Port_Data[MD_Port].PortData.GunDec.Dec.OilCNT, 16, 1); + OLED_ShowString(0, 32, "P: ", 16, 16, 1); + OLED_ShowNum(3 * 8, 32, MD_Connect_BCDTou64(TXHData.PrintLastRecord[TXHData.SurfaceNowItem].FData.MoneyCNT), 0, TXHData.MD_Port_Data[MD_Port].PortData.GunDec.Dec.MoneyCNT, 16, 1); + X_Now = 4; + Y_Now = 56; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.PrintLastRecord[TXHData.SurfaceNowItem].RTIME.Hour), 0, 0, 8, 1); + OLED_ShowChar(6 * X_Now, Y_Now, '-', 8, 1); + X_Now++; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.PrintLastRecord[TXHData.SurfaceNowItem].RTIME.Min), 0, 0, 8, 1); + OLED_ShowChar(6 * X_Now, Y_Now, '-', 8, 1); + X_Now++; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.PrintLastRecord[TXHData.SurfaceNowItem].RTIME.Sec), 0, 0, 8, 1); + OLED_ShowChar(6 * X_Now, Y_Now, ' ', 8, 1); + X_Now++; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.PrintLastRecord[TXHData.SurfaceNowItem].RTIME.Year), 0, 0, 8, 1); + OLED_ShowChar(6 * X_Now, Y_Now, '-', 8, 1); + X_Now++; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.PrintLastRecord[TXHData.SurfaceNowItem].RTIME.Month), 0, 0, 8, 1); + OLED_ShowChar(6 * X_Now, Y_Now, '-', 8, 1); + X_Now++; + X_Now += OLED_ShowNum(6 * X_Now, Y_Now, MD_Connect_BCDTou64(TXHData.PrintLastRecord[TXHData.SurfaceNowItem].RTIME.Day), 0, 0, 8, 1); + // OLED_ShowNum(80,0,TXHData.MD_Port_Info[0].GunInfo[0].FData.MoneyCNT,0,16,1); + // OLED_ShowString(80,0,"",16,3,0); + } + } + break; + case Surface_QueryMenu: + { + switch (GetKeyNum()) + { + case 0x01: + { + if (TXHData.SurfaceNowLine > 0) + TXHData.SurfaceNowLine--; + else + TXHData.SurfaceNowLine = Q_ItemEnd - 1; + } + break; + case 0x02: + { + // TXHData.MD_LORA_Slave_Flag = 0; + // TXHData.MD_LORA_SlaveTimer.Init = 1; + // MD_Connect_Init(); + if (TXHData.SurfaceNowLine < Q_ItemEnd - 1) + TXHData.SurfaceNowLine++; + else + TXHData.SurfaceNowLine = 0; + } + break; + case 0x04: + { + switch (TXHData.SurfaceNowLine) + { + case Q_NetworkInfo: + { + SurfaceJump(Surface_Q_NetworkInfo); + } + break; + case Q_MDPortInfo: + { + SurfaceJump(Surface_Q_MDPortInfo); + } + break; + case Q_LORARSSI: + { + SurfaceJump(Surface_Q_LORARSSI); + } + break; + case Q_VeresionCheck: + { + SurfaceJump(Surface_Q_VeresionCheck); + } + break; + case Q_Test_Info: + { + SurfaceJump(Surface_Q_Test_Info); + } + break; + } + } + break; + case 0x08: + { + SurfaceJump(Surface_Wait); + TXHData.SurfaceNowLine = 0; + } + break; + } + if (TXHData.SurfaceNow == Surface_QueryMenu) + { + Surface_Copy_16(QueryMenu[TXHData.SurfaceNowLine], 0, 4); + OLED_ShowString(0, 0, (u8 *)&QueryMenu[TXHData.SurfaceNowLine], 16, 16, 0); + } + } + break; + case Surface_Q_NetworkInfo: + { + switch (GetKeyNum()) + { + case 0x08: + { + SurfaceJump(Surface_QueryMenu); + TXHData.SurfaceNowItem = 0; + } + break; + } + if (TXHData.SurfaceNow == Surface_Q_NetworkInfo) + { + Surface_Copy_16(QueryNetworkInfo[0], 0, 4); + switch (TXHData.POS_Info.ConnectType) + { + case POS_Connect_Typ_Station: + OLED_ShowString(0, 16, "Type:Station", 16, 8, 1); + break; + case POS_Connect_Typ_Cloud: + OLED_ShowString(0, 16, "Type:Cloud", 16, 8, 1); + OLED_ShowString(0, 56, "URL:", 16, 8, 1); + OLED_ShowString(5 * 6, 56, (u8 *)&TXHData.POSData.WirelessData.CMD_SOCKA[13], 17, 8, 1); + break; + case POS_Connect_Typ_Cloud_Tast: + OLED_ShowString(0, 16, "Type:Cloud-Tast", 16, 8, 1); + OLED_ShowString(0, 56, "URL:", 16, 8, 1); + OLED_ShowString(5 * 6, 56, (u8 *)&TsatURL[13], 17, 8, 1); + break; + } + if (TXHData.POS_Info.ConnectType != POS_Connect_Typ_Station) + { + if (TXHData.POS_Info.NetType == POS_Net_Typ_4G_GM5) + { + for (i = 0; i < sizeof(TXHData.ICCID); i++) + if (TXHData.ICCID[i]) + break; + // OLED_ShowString(0,26,"ICCID",16,8,1);OLED_ShowString(32,26,&TXHData.ICCID[i],16,8,1); + OLED_ShowString(0, 26, "APN :", 16, 8, 1); + OLED_ShowString(6 * 6, 26, &TXHData.POSData.WirelessData.APN[0], 16, 8, 1); + if (TXHData.HardwareVersion > 24) // �µ�Ӳ���汾�����⿪ʼ�����е�ģ��ʹ����оƬ����IMEI�� + { + OLED_ShowString(0, 36, "IMEI:", 16, 8, 1); + OLED_ShowString(0, 46, &TXHData.POSData.WirelessData.IMEI[0], 20, 8, 1); + } + else + { + OLED_ShowString(0, 36, "IMEI:", 16, 8, 1); + OLED_ShowString(0, 46, &TXHData.POSData.WirelessData.IMEI[5], 20, 8, 1); + } + } + else if (TXHData.POS_Info.NetType == POS_Net_Typ_4G_L510) + { + for (i = 0; i < sizeof(TXHData.ICCID); i++) + if (TXHData.ICCID[i]) + break; + // OLED_ShowString(0,26,"ICCID",16,8,1);OLED_ShowString(32,26,&TXHData.ICCID[i],16,8,1); + OLED_ShowString(0, 26, "APN :", 16, 8, 1); + OLED_ShowString(6 * 6, 26, &TXHData.POSData.WirelessData.APN[0], 16, 8, 1); + OLED_ShowString(0, 36, "IMEI:", 16, 8, 1); + OLED_ShowString(0, 46, &TXHData.POSData.WirelessData.IMEI[0], 20, 8, 1); + } + else if (TXHData.POS_Info.NetType == POS_Net_Typ_WiFi) + { + // if(TXHData.POS_Info.ConnectType == POS_Connect_Typ_WifiStation) + // { + // OLED_ShowString(0,26,"SSID:THX-HD4-2.4",16,8,1); + // } + // else + { + OLED_ShowString(0, 26, "SSID:", 16, 8, 1); + OLED_ShowString(5 * 6, 26, &TXHData.POSData.WirelessData.WiFIName[0], 16, 8, 1); + } + OLED_ShowString(0, 36, "IMEI:", 16, 8, 1); + OLED_ShowString(0, 46, &TXHData.POSData.WirelessData.IMEI[0], 20, 8, 1); + } + else if (TXHData.POS_Info.NetType == POS_Net_Typ_WAN) + { + OLED_ShowString(0, 26, "IP:", 16, 8, 1); + OLED_ShowString(3 * 6, 26, &TXHData.POS_Info.IP[0], 16, 8, 1); + OLED_ShowString(0, 36, "IMEI:", 16, 8, 1); + OLED_ShowString(0, 46, &TXHData.POSData.WirelessData.IMEI[0], 20, 8, 1); + } + } + } + } + break; + case Surface_Q_MDPortInfo: + { + switch (GetKeyNum()) + { + case 0x01: + { + if (TXHData.SurfaceNowItem > 0) + TXHData.SurfaceNowItem--; + } + break; + case 0x02: + { + if (TXHData.SurfaceNowItem < 3) + TXHData.SurfaceNowItem++; + } + break; + case 0x08: + { + SurfaceJump(Surface_QueryMenu); + TXHData.SurfaceNowItem = 0; + } + break; + } + if (TXHData.SurfaceNow == Surface_Q_MDPortInfo) + { + Surface_Copy_16(QueryMDPortInfo[0], 0, 4); + OLED_ShowNum(62, 0, TXHData.SurfaceNowItem + 1, 1, 0, 16, 1); + OLED_ShowString(72, 0, "OnLine : ", 16, 8, 1); + OLED_ShowPicture(120, 0, 8, 8, (u8 *)BMP_Bluesky_Empty_8, 1); + OLED_ShowString(72, 8, "OffLine: ", 16, 8, 1); + OLED_ShowPicture(120, 8, 8, 8, (u8 *)BMP_Bluesky_Empty_8, 0); + OLED_ShowString(0, 16, "Type:", 16, 8, 1); + if (TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.MDConnectType == MD_LORA) + OLED_ShowString(5 * 6, 16, "LORA", 16, 8, 1); + else + OLED_ShowString(5 * 6, 16, "RS485", 16, 8, 1); + OLED_ShowString(0, 24, "Protocol:", 16, 8, 1); + if (TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.POSType == PosYWY) + OLED_ShowString(9 * 6, 24, (u8 *)YWY_Type_Info[TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.Device_Type], 12, 8, 1); + else + OLED_ShowString(9 * 6, 24, (u8 *)QueryMDPortInfo_POSType[TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.POSType], 12, 8, 1); + OLED_ShowString(0, 32, "Gun-Addr:", 16, 8, 1); + X_Now = 9; + Y_Now = 0; + for (i = 0; i < TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.DeviceNumber; i++) + { + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + X_Now += OLED_ShowNum(6 * X_Now, 32 + Y_Now * 8, TXHData.MD_Port_Data[TXHData.SurfaceNowItem].GunData[i].GunNummber, 0, 0, 8, TXHData.MD_Port_Data[TXHData.SurfaceNowItem].GunData[i].GunState.Flag.Online); + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + OLED_ShowChar(6 * X_Now, 32 + Y_Now * 8, '-', 8, TXHData.MD_Port_Data[TXHData.SurfaceNowItem].GunData[i].GunState.Flag.Online); + X_Now++; + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + X_Now += OLED_ShowNum(6 * X_Now, 32 + Y_Now * 8, TXHData.MD_Port_Data[TXHData.SurfaceNowItem].GunData[i].GunAddr, 0, 0, 8, TXHData.MD_Port_Data[TXHData.SurfaceNowItem].GunData[i].GunState.Flag.Online); + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + OLED_ShowChar(6 * X_Now, 32 + Y_Now * 8, ';', 8, 1); + X_Now++; + } + } + } + break; + case Surface_Q_LORARSSI: + { + switch (GetKeyNum()) + { + case 0x01: + { + if (TXHData.SurfaceNowItem > 0) + TXHData.SurfaceNowItem--; + } + break; + case 0x02: + { + if (TXHData.SurfaceNowItem < 3) + TXHData.SurfaceNowItem++; + } + break; + case 0x08: + { + SurfaceJump(Surface_QueryMenu); + TXHData.SurfaceNowItem = 0; + } + break; + } + if (TXHData.SurfaceNow == Surface_Q_LORARSSI) + { + TXHData.DisplayOn = 1; + Surface_Copy_16(QueryLORARSSI[0], 0, 4); + OLED_ShowNum(64, 0, TXHData.SurfaceNowItem + 1, 1, 0, 16, 1); + OLED_ShowString(0, 20, "Gun-RSSI:", 16, 8, 1); + X_Now = 9; + Y_Now = 0; + for (i = 0; i < TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.DeviceNumber; i++) + { + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + X_Now += OLED_ShowNum(6 * X_Now, 20 + Y_Now * 8, TXHData.MD_Port_Data[TXHData.SurfaceNowItem].GunData[i].GunNummber, 0, 0, 8, 1); + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + OLED_ShowChar(6 * X_Now, 20 + Y_Now * 8, '-', 8, 1); + X_Now++; + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + X_Now += OLED_ShowNum(6 * X_Now, 20 + Y_Now * 8, TXHData.MD_Port_Info[TXHData.SurfaceNowItem].GunInfo[i].RSSI * 100 / 256, 0, 0, 8, 1); + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + OLED_ShowChar(6 * X_Now, 20 + Y_Now * 8, '%', 8, 1); + X_Now++; + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + OLED_ShowChar(6 * X_Now, 20 + Y_Now * 8, ';', 8, 1); + X_Now++; + } + } + } + break; + case Surface_Q_VeresionCheck: + { + switch (GetKeyNum()) + { + case 0x08: + { + SurfaceJump(Surface_QueryMenu); + } + break; + } + if (TXHData.SurfaceNow == Surface_Q_VeresionCheck) + { + Surface_Copy_16(QueryVeresion[0], 0, 4); + OLED_ShowString(0, 18, "SV:", 16, 8, 1); + OLED_ShowString(6 * 3, 18, (u8 *)&BoxVersion[0], 16, 8, 1); + OLED_ShowString(6 * 15, 18, "HV:", 16, 8, 1); + OLED_ShowNum(6 * 18, 18, TXHData.HardwareVersion, 2, 0, 8, 1); + for (i = 0; i < 4; i++) + { + if (TXHData.MD_Port_Data[i].PortData.ROM_UpData.ROM_UpData_State.Flag.Update_Flag == 1) + { + OLED_ShowString(0, 27 + i * 9, "Port-", 5, 8, 1); + OLED_ShowNum(5 * 6, 27 + i * 9, i + 1, 1, 0, 8, 1); + OLED_ShowString(7 * 6, 27 + i * 9, (u8 *)&TXHData.MD_Port_Data[i].PortData.ROM_UpData_Version[0], 10, 8, 1); + } + } + } + } + break; + case Surface_Q_Test_Info: + { + switch (GetKeyNum()) + { + case 0x01: + { + if (TXHData.SurfaceNowItem > 0) + TXHData.SurfaceNowItem--; + } + break; + case 0x02: + { + if (TXHData.SurfaceNowItem < 3) + TXHData.SurfaceNowItem++; + } + break; + case 0x08: + { + SurfaceJump(Surface_QueryMenu); + TXHData.SurfaceNowItem = 0; + } + break; + } + if (TXHData.SurfaceNow == Surface_Q_Test_Info) + { + Surface_Copy_16(QueryTestInfo[0], 0, 4); + OLED_ShowNum(62, 0, TXHData.SurfaceNowItem + 1, 1, 0, 16, 1); + OLED_ShowString(72, 0, "OnLine : ", 16, 8, 1); + OLED_ShowPicture(120, 0, 8, 8, (u8 *)BMP_Bluesky_Empty_8, 1); + OLED_ShowString(72, 8, "OffLine: ", 16, 8, 1); + OLED_ShowPicture(120, 8, 8, 8, (u8 *)BMP_Bluesky_Empty_8, 0); + OLED_ShowString(0, 16, "Type:", 16, 8, 1); + if (TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.MDConnectType == MD_LORA) + OLED_ShowString(5 * 6, 16, "LORA", 16, 8, 1); + else + OLED_ShowString(5 * 6, 16, "RS485", 16, 8, 1); + OLED_ShowString(0, 24, "Protocol:", 16, 8, 1); + if (TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.POSType == PosYWY) + OLED_ShowString(9 * 6, 24, (u8 *)YWY_Type_Info[TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.Device_Type], 12, 8, 1); + else + OLED_ShowString(9 * 6, 24, (u8 *)QueryMDPortInfo_POSType[TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.POSType], 12, 8, 1); + OLED_ShowString(0, 32, "Gun-Addr:", 16, 8, 1); + X_Now = 9; + Y_Now = 0; + for (i = 0; i < TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.DeviceNumber; i++) + { + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + X_Now += OLED_ShowNum(6 * X_Now, 32 + Y_Now * 8, TXHData.MD_Port_Data[TXHData.SurfaceNowItem].GunData[i].GunNummber, 0, 0, 8, TXHData.MD_Port_Data[TXHData.SurfaceNowItem].GunData[i].GunState.Flag.Online); + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + OLED_ShowChar(6 * X_Now, 32 + Y_Now * 8, '-', 8, TXHData.MD_Port_Data[TXHData.SurfaceNowItem].GunData[i].GunState.Flag.Online); + X_Now++; + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + X_Now += OLED_ShowNum(6 * X_Now, 32 + Y_Now * 8, TXHData.MD_Port_Info[TXHData.SurfaceNowItem].GunInfo[i].WaitPREXDATA_flag, 0, 0, 8, TXHData.MD_Port_Data[TXHData.SurfaceNowItem].GunData[i].GunState.Flag.Online); + if (6 * X_Now > 122) + { + Y_Now++; + X_Now = 0; + } + OLED_ShowChar(6 * X_Now, 32 + Y_Now * 8, ';', 8, 1); + X_Now++; + } + } + } + break; + case Surface_SetMenu: + { + switch (GetKeyNum()) + { + case 0x01: + { + if (TXHData.SurfaceNowLine > 0) + TXHData.SurfaceNowLine--; + else + TXHData.SurfaceNowLine = S_ItemEnd - 1; + } + break; + case 0x02: + { + // TXHData.MD_LORA_Slave_Flag = 0; + // TXHData.MD_LORA_SlaveTimer.Init = 1; + // MD_Connect_Init(); + if (TXHData.SurfaceNowLine < S_ItemEnd - 1) + TXHData.SurfaceNowLine++; + else + TXHData.SurfaceNowLine = 0; + } + break; + case 0x04: + { + + switch (TXHData.SurfaceNowLine) + { + case S_MDConnectSet: + { + SurfaceJump(Surface_S_MDConnectSet); + } + break; + case S_LORASlaveSet: + { + SurfaceJump(Surface_S_LORASlaveSet); + } + break; + case S_PortLogOutput: + { + SurfaceJump(Surface_S_PortLogOutput); + } + break; + case S_ConnectMode: + { + SurfaceJump(Surface_S_ConnectMode); + TXHData.SurfaceNowLine = TXHData.POSData.POSConnectTyye.Flag.ConnectMode; + } + break; + case S_NetworkSet: + { + SurfaceJump(Surface_S_NetworkSet); + TXHData.SurfaceNowLine = TXHData.POSData.POSConnectTyye.Flag.NetworkSet; + } + break; + case S_DataInit: + { + SurfaceJump(Surface_S_DataInit); + } + break; + } + } + break; + case 0x08: + { + SurfaceJump(Surface_Wait); + TXHData.SurfaceNowLine = 0; + } + break; + } + if (TXHData.SurfaceNow == Surface_SetMenu) + { + Surface_Copy_16(SetMenu[TXHData.SurfaceNowLine], 0, 4); + OLED_ShowString(0, 0, (u8 *)&SetMenu[TXHData.SurfaceNowLine], 16, 16, 0); + } + } + break; + case Surface_S_MDConnectSet: + { + switch (GetKeyNum()) + { + case 0x01: + { + if (TXHData.SurfaceNowItem > 0) + { + TXHData.SurfaceNowItem--; + } + } + break; + case 0x02: + { + if (TXHData.SurfaceNowItem < 3) + { + TXHData.SurfaceNowItem++; + } + } + break; + case 0x04: + { + if (TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.MDConnectType == MD_LORA) + { + TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.MDConnectType = MD_RS485; + FMItemWrite(CF_MD_Port_Data, TXHData.SurfaceNowItem); + MD_Port_Init(TXHData.SurfaceNowItem); + BEEP_OFF; + } + else if (TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.MDConnectType == MD_RS485) + { + BEEP_ON; + TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.MDConnectType = MD_LORA; + MD_Port_Init(TXHData.SurfaceNowItem); + FMItemWrite(CF_MD_Port_Data, TXHData.SurfaceNowItem); + } + } + break; + case 0x08: + { + SurfaceJump(Surface_SetMenu); + TXHData.SurfaceNowItem = 0; + } + break; + } + if (TXHData.SurfaceNow == Surface_S_MDConnectSet) + { + Surface_Copy_16(SetMDConnect[0], 0, 4); + OLED_ShowString(40, 20, "PORT:", 21, 8, 1); + OLED_ShowNum(70, 20, TXHData.SurfaceNowItem + 1, 1, 0, 8, 1); + if (TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.MDConnectType == MD_LORA) + OLED_ShowString(0, 30, "TYPE:LORA", 21, 8, 1); + else if (TXHData.MD_Port_Data[TXHData.SurfaceNowItem].PortData.MDConnectType == MD_RS485) + OLED_ShowString(0, 30, "TYPE:RS485", 21, 8, 1); + OLED_ShowString(0, 50, "Pass Enter Change", 21, 8, 1); + } + } + break; + case Surface_S_LORASlaveSet: + { + switch (GetKeyNum()) + { + case 0x01: + { + if (TXHData.SurfaceNowItem > 0) + { + if (TXHData.MD_LORA_Set_Flag) + { + MD_Port_Init(TXHData.SurfaceNowItem); + } + TXHData.SurfaceNowItem--; + } + } + break; + case 0x02: + { + if (TXHData.SurfaceNowItem < 3) + { + if (TXHData.MD_LORA_Set_Flag) + { + MD_Port_Init(TXHData.SurfaceNowItem); + } + TXHData.SurfaceNowItem++; + } + } + break; + case 0x04: + { + TXHData.MD_LORA_Set_Flag = 1; + TXHData.MD_LORA_SlaveTimer.ON_OFF = 1; + } + break; + case 0x08: + { + SurfaceJump(Surface_SetMenu); + TXHData.SurfaceNowItem = 0; + TXHData.MD_LORA_SlaveTimer.Init = 1; + if (TXHData.MD_LORA_Set_Flag) + { + BEEP_OFF; + TXHData.MD_LORA_Set_Flag = 0; + MD_Port_Init(TXHData.SurfaceNowItem); + } + } + break; + } + + if (TXHData.SurfaceNow == Surface_S_LORASlaveSet) + { + Surface_Copy_16(SetLORASlave[0], 0, 4); + OLED_ShowString(40, 18, "PORT:", 21, 8, 1); + OLED_ShowNum(70, 18, TXHData.SurfaceNowItem + 1, 1, 0, 8, 1); + OLED_ShowString(0, 28, "1:Dip switch 1and2 ON", 21, 8, 1); + OLED_ShowString(0, 38, "2:Insert slave module", 21, 8, 1); + OLED_ShowString(0, 48, "3:Pass Enter Start", 21, 8, 1); + } + if (TXHData.MD_LORA_Set_Flag == 1) + { + TXHData.DisplayOn = 1; + if (TXHData.MD_LORA_SlaveTimer.Flag) + { + BEEP_OFF; + TXHData.MD_LORA_SlaveTimer.Flag = 0; + MD_Port_LORASet(TXHData.SurfaceNowItem, LORA_Slave); + OLED_ShowString(0, 56, "State:Sending", 21, 8, 1); + } + if (TXHData.MD_LORA_Slave_Flag) + { + TXHData.MD_LORA_Slave_Flag = 0; + OLED_ShowString(0, 56, "State:Complete", 21, 8, 1); + BEEP_ON; + } + } + } + break; + case Surface_S_PortLogOutput: + { + switch (GetKeyNum()) + { + case 0x01: + { + } + break; + case 0x02: + { + } + break; + case 0x04: + { + if (CH376DiskConnect() == USB_INT_SUCCESS) /* ���U���Ƿ����� ,*/ + { + TXHData.UDisk_Flag = 1; // �����־�����ģ�����ƽʱ���ܿ��� + } + else + { + TXHData.UDisk_Flag = 0; + } + } + break; + case 0x08: + { + // TXHData.UDisk_Flag = 0; + SurfaceJump(Surface_SetMenu); + } + break; + } + if (TXHData.SurfaceNow == Surface_S_PortLogOutput) + { + Surface_Copy_16(SetPortLogOutput[0], 0, 4); + OLED_ShowString(0, 26, "Insert U-Disk First", 21, 8, 1); + OLED_ShowString(0, 36, "Than Pass Enter", 21, 8, 1); + OLED_ShowString(0, 46, "Format:FAT32;MAX:32G", 21, 8, 1); + if (TXHData.UDisk_Flag) + OLED_ShowString(0, 56, "Find U-Disk,Outputing", 21, 8, 1); + else + OLED_ShowString(0, 56, "State:Idle", 21, 8, 1); + } + } + break; + case Surface_S_ConnectMode: + { + switch (GetKeyNum()) + { + case 0x01: + { + if (TXHData.SurfaceNowItem > 0) + { + + TXHData.SurfaceNowItem--; + } + else + { + TXHData.SurfaceNowItem = POS_Connect_Typ_End; + } + } + break; + case 0x02: + { + if (TXHData.SurfaceNowItem < POS_Connect_Typ_End) + { + TXHData.SurfaceNowItem++; + } + else + { + TXHData.SurfaceNowItem = 0; + } + } + break; + case 0x04: + { + TXHData.POSData.POSConnectTyye.Flag.ConnectMode = TXHData.SurfaceNowItem; + if (FMItemWrite(CF_POSData, 0)) + { + i = TXHData.POSData.POSConnectTyye.State; + SurfaceJump(Surface_Wait); + FM_Data_Init(); + TXHData.POSData.POSConnectTyye.State = i; + FMItemWrite(CF_POSData, 0); + TXHData.ROM_UpData.ROM_UpData_State.Flag.Update_Flag = 0; + TXHData.ROM_UpData.ROM_UpData_State.Flag.RightRun_Flag = 3; + TXHData.ROM_UpData.FrameTop = 0; + FMItemWrite(CF_ROM_UpData, 0); + TXHData.POSNetSetState.Flag.WorkMode = 0; + switch (TXHData.POS_Info.NetType) + { + case POS_Net_Typ_WAN: + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_ENTM; + break; + case POS_Net_Typ_WiFi: + TXHData.POSNetSetState.Flag.POSNetCMDNext = WIFI_WifiRST; + break; + case POS_Net_Typ_4G_GM5: + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_ENTM; + break; + case POS_Net_Typ_4G_L510: + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_AT; + ; + break; + } + POS_Connect_Init(); + } + } + break; + case 0x08: + { + SurfaceJump(Surface_SetMenu); + TXHData.SurfaceNowItem = 0; + } + break; + } + if (TXHData.SurfaceNow == Surface_S_ConnectMode) + { + Surface_Copy_16(SetConnectMode[0], 0, 4); + OLED_ShowString(0, 16, (u8 *)ConnectMode_Info[TXHData.POSData.POSConnectTyye.Flag.ConnectMode], 16, 16, 1); + if (TXHData.POSData.POSConnectTyye.Flag.ConnectMode != TXHData.SurfaceNowItem) + OLED_ShowString(0, 32, (u8 *)(&ConnectMode_Info[TXHData.SurfaceNowItem][4]), 12, 16, 0); + else + OLED_ShowString(0, 32, (u8 *)(&ConnectMode_Info[TXHData.SurfaceNowItem][4]), 12, 16, 1); + } + } + break; + case Surface_S_NetworkSet: + { + switch (GetKeyNum()) + { + case 0x01: + { + if (TXHData.SurfaceNowItem > 0) + { + + TXHData.SurfaceNowItem--; + } + else + { + TXHData.SurfaceNowItem = POS_Net_Typ_End; + } + } + break; + case 0x02: + { + if (TXHData.SurfaceNowItem < POS_Net_Typ_End) + { + TXHData.SurfaceNowItem++; + } + else + { + TXHData.SurfaceNowItem = 0; + } + } + break; + case 0x04: + { + TXHData.POSData.POSConnectTyye.Flag.NetworkSet = TXHData.SurfaceNowItem; + if (FMItemWrite(CF_POSData, 0)) + { + SurfaceJump(Surface_Wait); + TXHData.POSNetSetState.Flag.WorkMode = 0; + switch (TXHData.POS_Info.NetType) + { + case POS_Net_Typ_WAN: + TXHData.POSNetSetState.Flag.POSNetCMDNext = USRK3_ENTM; + break; + case POS_Net_Typ_WiFi: + TXHData.POSNetSetState.Flag.POSNetCMDNext = WIFI_WifiRST; + break; + case POS_Net_Typ_4G_GM5: + TXHData.POSNetSetState.Flag.POSNetCMDNext = GM5_ENTM; + break; + case POS_Net_Typ_4G_L510: + TXHData.POSNetSetState.Flag.POSNetCMDNext = L510_AT; + ; + break; + } + POS_Connect_Init(); + TXHData.SurfaceNowItem = 0; + // FMItemWrite(CF_POSNetSetState,0); + // POS_Network_Init(); + } + } + break; + case 0x08: + { + SurfaceJump(Surface_SetMenu); + TXHData.SurfaceNowItem = 0; + } + break; + } + if (TXHData.SurfaceNow == Surface_S_NetworkSet) + { + Surface_Copy_16(SetNetworkSet[0], 0, 4); + OLED_ShowString(0, 16, (u8 *)Network_Type_Info[TXHData.POSData.POSConnectTyye.Flag.NetworkSet], 16, 16, 1); + if (TXHData.POSData.POSConnectTyye.Flag.NetworkSet != TXHData.SurfaceNowItem) + OLED_ShowString(0, 32, (u8 *)(&Network_Type_Info[TXHData.SurfaceNowItem][4]), 12, 16, 0); + else + OLED_ShowString(0, 32, (u8 *)(&Network_Type_Info[TXHData.SurfaceNowItem][4]), 12, 16, 1); + } + } + break; + case Surface_S_DataInit: + { + switch (GetKeyNum()) + { + case 0x01: + { + } + break; + case 0x02: + { + } + break; + case 0x04: + { + FM_Data_Init(); + __set_FAULTMASK(1); + NVIC_SystemReset(); + } + break; + case 0x08: + { + SurfaceJump(Surface_SetMenu); + } + break; + } + if (TXHData.SurfaceNow == Surface_S_DataInit) + { + Surface_Copy_16(SetDataInit[0], 0, 4); + } + } + break; + } + + OLED_Refresh(); + } +} \ No newline at end of file diff --git a/User/Surface/Surface.h b/User/Surface/Surface.h new file mode 100644 index 0000000..f285752 --- /dev/null +++ b/User/Surface/Surface.h @@ -0,0 +1,56 @@ +#ifndef __Surface_H__ +#define __Surface_H__ + +typedef enum +{ + Surface_FirmwareUpdate, + Surface_OfflineRecordUpload, + Surface_Wait , + Surface_PrintInfo , + + Surface_QueryMenu , + Surface_Q_NetworkInfo , + Surface_Q_MDPortInfo, + Surface_Q_LORARSSI, + Surface_Q_VeresionCheck, + Surface_Q_Test_Info, + + Surface_SetMenu, + Surface_S_MDConnectSet, + Surface_S_LORASlaveSet, + Surface_S_PortLogOutput, + Surface_S_ConnectMode, + Surface_S_NetworkSet, + Surface_S_DataInit, + + Surface_ItemEnd , +}SurfaceMenuItem; + +typedef enum +{ + Q_NetworkInfo , + Q_MDPortInfo , + Q_LORARSSI , + Q_VeresionCheck, + Q_Test_Info, + + Q_ItemEnd , +}QueryMenuItem; + +typedef enum +{ + S_MDConnectSet , + S_LORASlaveSet , + S_PortLogOutput , + S_ConnectMode , + S_NetworkSet , + S_DataInit , + + S_ItemEnd +}SetMenuItem; + +void Surface_Init(void); +void SurfaceTast(void); +//------------------------------------------------------------------------------ + +#endif diff --git a/User/TXH.bin b/User/TXH.bin new file mode 100644 index 0000000000000000000000000000000000000000..b8704350ff9f74126910702e5a1288c1e44e4aef GIT binary patch literal 234936 zcmb?^3w#vS_3)k9M>d;;?1lg#gs__gS>EBHBEB}8uq2@JQmYkh@KJ+SO;9mGfeoO> z2bw5t!AHeM6|}S@h=NKFtLLET=KvL`k2)lWZ{m!}b*txT_k@ok&Z?m&A z=bn4+x#ygF&beo1Dmsbl)mmcP44)_7A+{~>{Rj9o!iVVoZG&^$<@4{u_fGhHnBX(? zH^ep?K8dcsvw_&Q!G~T~z7ycm;y84RDIrb;ZpytT+okX+hL5`+8a_7YHy_%Jg^z;k zfBF6^;QazVv;PY`-$ookBHqwTO3BQIr%kp$oF;(^m>X+pV5Sw$^&N}<{~++<3E5dNm6;cDYeo+$v@qHn}64FvDP)ldhoA9T+@rXd9k=n zxZf(k(dnRfPltC4TCa95JCJs~{L_Iv$qf4x7)pW^5JaNg@E zo*5jK_UF@f^6_c=JigwW&DDE7cYpKo>4C(1CNPYwf6nh}B>DT>P4?T`Q&PC~H~O19 zy!>205pU_X`qTV#{Wto#7oy=uqKX(yv;d(P1~{ivx~h!^1`j#xEHuFbJ~*T z4{9aD7Pa%-9Fh2V_`UB0@sXUO&VX~We=Oi@>o#o#em;vdb{&&o>Ggpm>!u=C)@z+) z$jo*V=WY9{^1Y$=6gh=^Y;)Q!vd(C0eh~3%S~$z#N+BUb=M^DtigykX-~NEC=kmOS zeSE-k17^0>4)L|E&UmYb=iX~i;cjmy=CNtTZK+dk$tr2jnfr}@p8ptJ`{eXM z^PIMnDaCD>3+A+$Cvz_qw^>bZbflX3b>t=B_`5{BNaizfalmKLkE`V|&W170$n?V) z?J&loxosBS6}+~MvD2rmbYxfbDR$h;JZn;G|Q!@+`e_ z#dhq66kt!yS&NFkNy7GI-M$lCex5%cFgy%!g}WTv3CNNQG;dE@^Xb8$V}z_6!&4qP zb`kfl#+X|7bo`1BdU@ej(~0=I2pM-Oi1KP8w}HiS?5f-j+@H_EOpyYVGViJA6qK|V zd>mk@+=czV;Ct=V6rZVezK@76M2JxD9ar2D^!h6MX)VzZ-+ozy6Np$58CNW7=&0NU zsWfrCHE2(Jt+RXy(oM$j zt%V-}#WPFNOWIn@EkwwI-|c(m67iKCAeBEuJNKObMSq>&>aX>C3x)|Ef02KtKM%M$ zF|xq_Q-5=ILy_YPr$39H8yp#*4OZPY2Yzub;wEBRWJo(nzNW~P`$h+6{0YQ z&7>h^!+pSwzn16DwmzRbJL!3IKFs^%;j?Vd@&3DE6hwTpD|ze9k<6aT?T>A>f`&y4 zNdv%e#5KsD>NnR<_AmCEH$}r=MtQ$^y*q1Uqpi^fHs0m;l$+NRPg)T8b%?C5^Vx#7 zVN|ZnN}CU&)~%JhLTicbKk&KZN$^cZZ`uuOPEHxI?RJSAshsI}cWZZ`mvpC!Xt~V0 z9UoQBENlF{!)11No6k7AQ#-PDb8dIBt@!o!RPL|C=d_VUbJ`p(-)`bUSknISTt^8R z{RV9r!;IG)+cR+;HQT=N=75fIsKMFATnKx1z=|YZjkD-%Z0xQ*#S1{kDc9tBe>8kW z)a+09d)q)`+fq23Ph0W8pwqvgjUz*Yd+90@4Ns3+U^T{7#s_T*qG$&=ml-&7iELFY z#r`&7>A2#Hi|y-gvwUaY2`$aVT zLQmE}vuzrDnw#dF5$6%{(hmq3eUQ1u9cbJ*m$5IY)=i0{VYA#uc<3t1UsU^TDB=dskY&F|8-=X0UKcbUh{` ze}BzH|F@AHtFl1zdb+^&aXUK*;lKF|ctHfSpX9$aE4$s4;%hhmG(!-Ql7eIWQ~c9F zTchEddy_ze@wdZ26nx5kf**8@PfrQ)g4gfdy7pMfnZWHzyH)#ur$|FPA2exwJ==_rfhg}#ucFwF<`a| z=^H9?Hg|Bz2xTkBc1v@Su2ud*j~E;)Agm?ivYNg`_@%j7!d(AEadfY3TUy6JZfP#I zduoPl|JxmfBqhS7xU5NE0X||9Tvq5TN*p^cWZuaJg* zGG%o$QYmE)F-q!yLwqP@L*0zzuW{uEd55+IrJUe9m0nrvk6}$;kK8gJ!jZn)Lp=Wo zbuC6(qOPX^2jT&bzCNjbw*M}_ZL<}u;X{2e#xG%oCu5FfiUsNRppcXaQe(}SR$&@` zX*sC?Da}X`;0zZHf7Z+Sg(P!mS_MCRI$Yz*J^lg52+0J8PrS0@Ks4&B@HKK3=w0VG z&du>*=O7HO4`{I~XQC}5`Pu$q*-sXk zsC7WU2G?WR-x~x{m=a3jLnP~-qWQUGl-UpKvvZoCYroZgg+BmZx8wyy!+-1DGqkGc z!z_P0N8W{q;=y*3YX0K8>^s_tWe8|U!BF5Pxu+=LpXxb!sB5SnJe=fVn~F^PftJYw z{je(M4fGF#NXFl8pNIAgY~_Dpqn-jAwF+$1N)Pun$+HR8S$z9kzBwtQnuIcvc`=>m zT=iZXtc8Re$S~We@8jd2BYB|z&~r4Lan1xjQRVihvmidXX^@y?;zDqA=@_RKzsH&c z_KLSvIGUy}U!xoKa*nM=EmA>?1PpUW``1EDpXy9uJ8uU_>X_yYJ1eiH9@ zRGS2dh-T+!9cW6)eHB*lSDVg;z)K>P+qZOjmYX5^Ag;IS->fGWnA=Opj54mhnRuVv z1fCCZr2z!kY}cFh4+(hn^4TW1%0G$6cocZTQ&QV>NhuK>U5Ld=p{7bWDt1L)%J44a zHp6#b-L>$S_vQqe-m1seV<`-I5@G6mM_cjS1;D*#LZ0;I);4hp6Ll>>f^!CV%5_=ah2d)4eu#Hhe$XdmKE&Ns&)Z zKkgvn_{e6fZ2%ERN6=rqAVLbvu<8@h9VyRQ(_|hOIY$AX7 zfS%>yXic=a33ZGVa?lRP^d;cRl}CF8Gurf?EIQi3aCMM6+JW>a2S)1z+6KXB)8Tty z@8zy&_=D&e`1^h|0Ds?&z6F09qtX~mbPT_Va4zT_dffoMg1@1N~P;3H-g6{=J+2t%xG; zJvT?gw?&c9@A@J#pBsCSva5hbv@8?FnQ=5)!J8ih(Z@vblE`R(A;{|MQQJ;(NM>Qi_Mb)xj#one-?ZD9!*%?+1z<@Lkoj8feXm{s|-|8qSQq3KA0yJ1Es@ zG9P~iG)@q^qnztc$MC2VuI|?Gu@EdPNJYMx+SYRK!knW`Pr(Qa!IGmz9qga%9}QYY zL@rXfE3(}LBLa9g*=-d*A$i@F&XY}P5i-}CWA>Z{oy!)ie$xJrhgLe$cXFdR0amAr zFNb(KMaW&qjpst?uu`>jn39G^k}6ktbFVGSF^}#z=*`*aJMu*Y~G8N9Pm(Ssu*CMX! zg&scWs-EaEg^2rhxNhs341XV`P!(`=6&xYI^MIlUdM1i@_L%+10UkzB((UrYRe8J< z#T((;MDh9_3;bQsV}-wSdy*)$1)#@wm$X@2-Zrb(+m=*LZ4TuXO3*04J_E2%gH{&5 zzme>oC{FHiRo-awO$9%FBVS@#30Z=!MdU{KOtQyAcOo-wW3t=*7O2 zv0JJ3e%Cz_B&XOj_M5SwaUVtV6HE<5yhIDQ+Bf7f^w z9Bqh_cJru9{8s_TXGZ42nR@xmTsU(@1o8>+Jw1Zh8oMv7MymI9Cksn+F05WSo(oPK zPeNoQp54<;#-CQXb$=Jj=kd_K0jOL9Sy+kBF!$o7?sz_5uj5l1w0r<~kL^+Cp6Ql! z?n(Ui!W!0%I=7ng2xa4D-!v{uXp(GK7;Kkgd#?Ch4{A)VxI+G(C4aw3zg^;U zAXAR*9&rG*AG|+#Hss9q+aOZ0mO7?!B3Ur3(K-0q@9v&!mx=FsKt(piq_ z4dqV@{<5q|bv_Hs=>v<3>A6)xQCXpK&UpnrS1nvtRw|tnA6Rq=J$J8gaalQ>GlwoJ zyAaNV%I^@SlvUF+Q_2eInT5iHvU+-EV%a!)W`QuKY?F-X@_D1^xiVq2Ox37aw&~9D zB4MP4syuq`V!@@M3i4P0H(nT~p(=}>%NGXAR5{BA&dM0!EYB94GF541>GX_KNRz3u zm)YqVn_#0ImjXbk1vM^(3_4v%jGWQJNO@Bz%;utud#S>F&q^yG6}_t z^XXAwbV_hcqp5-ubItk1rgF0&9ls98sLzmT&EqQu&d&CJUXfCfUwqZ#{NktK^ErG{ z?}Fd(c^bd(hHv;}7xU%5#d#tGZzocw;&0!gl*Ps6vny7YKUMKD#d&2QN6gs{K8V}p z8ZCZ=cDkN}9Dy0=UK_Cz6a2N%<0P`!4_=3u7cF#yXC$tR67V?!k#~m@*TAy6O3qbU zxwmr8neNKEa`f@iOY0*k={I_uhYDQwvd&9Nt86Y?RiSHdWu~jH(go0jdZ{TRhEtojqgfpAmf1ae!K?;V^(O~W*yVP5~7NE0A1MtlgA_aXWF zYxw5MY}96CUdDMj^qTULW)G_{!48ULcIK2}6)E02v1!Jfr1prUPD)kBRbJig5 zLijr}4I~e~Ef~Wi9JZe%$EXNZ=Q~29)Nz_99^=h?@L>@40yUl;4%BV+O$kZ;xoCe< zgzu&O6)i;gY>Fpy!+@IC(^y zeE(=Aqh?b+jnd5Kw~_khRCzwFbUtsR^NAc<)szc!3i}c&CzZSk5r5h(jR`Xc&4fw@ z?*zPi_>3nV$Z1|W=6kH9D3{B_S?raw2ET)>0T)_v%qk#P8|Az~Bg8Nd$b9?=a(&24 zNuI%u6u=GuWS3xF2S4uVzS&^cdVfJ&vmjOr2xR1a0x8H8W&5a}ZH|QBM8xm9xcWl*+C-Um<7N-5 zGqo3+#%i=-l!8^m!2;l5pbIk)NZE9neQB=9nUzt;xBGb19f@OE@)?C|7RogadSBFq zbLo&Vq{}k2$@ge$3Y_!iBm)m@aFhnJxarEN5c0OxS9{&@AQBj7gs?BfQTyr24(iup4`%4 zWSnzrq|m)JGMVFhh+}Ifxsv~y{E_VLI|d#>g>7dv{P#ZC_XGY70r>%MxXf1V23i)L z!)ybLlg?R+%<+xBA6o4?jvqak1pTD)ma@I~?>Zh?jblR|=kUcoSd)%*Ai`ogERHh&UvI(LRnWBjTyNCkHcZ@B7Xk zv_XCh;#0^lj2AzR%JB&Fjq8P!U-F1I^(px!kGQB$$}f4ux%4bw>JhK)i{+Qd_D8pZ zM3_9{&wB^LH7D?83s~4KFsoa@AJ`JHkvV5b<(7z@*x*VkjBQI~07-(s4!E)kuJCle zJ>vL2&W-qwp0hw!n$Y}}o(I1G9t?vK{I%QRhOCSDS+^DRdLx{L%nQU@5{Ev5tH_}b zx_P+T0NIu#Z#29Xzv1^2QK2asehhpPi{Pn_hHIk=f5I|U3WK>xwQkdawt0g1hXdE0Bkvur^WY~(+-L=K8 zQmzu@$ORd%N*Eio7^b$!QdJ+$^4Brm$T)48m4_3}Z`T7^+7N_z)A0a;9w{R@L=P-N@!N&pl`A3$Mg5?`Y zMNd8IT3`6tXr||p(6Z9L@Nc6va&MWQ2SR<}t>7Ckon_jy3ueAA9PYadBK+M2w(hXL~fig^KGeyDo^ z#cUU@0W7vc3G-Dd{A@UzJZ+=zKdo0&+&}9sk#QFS?j+%E;U>WEEuAal&m4#NFQxb| z1^hF+FO~6M1ej7~{8LrC*55t?VvR1c`+HbR)9i$lf*eePj~6~gbFaA^G?Lr`$8#?yu1n!~Asqjt z%wKj*(bY5XA|B5zTCm_JbLN-e?*%jFUq561<tA& z5&r<^H^TQjT^OnIUd%la8+=mXlR=VQo(hYyzf znwv1AL<%6*jNA^k{KY<6$5OoIRO|92nj>EiI}xw?p8@-}FLEFWy+rebM_QkPc(%~Z zwL2Wv_D?yk-Ri8HJs>|vN_x9cgns_h0wj{K@bJov2rDiETEA-5uO*M z>jTI&(iuA1wUKnPqk~T$9GVWE8h9q)?Obv*|F*d!nK-XSZwIPj4qD(B?3%vKgT*iH zohjTY(7M6UwX}@|esSr1Xg>Xgc$|P|wBUsbAai@Ls?1Tda88?hsNJ=pM--deo4I7D znXr|#G+{q>=qCopiRsDlaORE_fZB*VJ?%5nzc^@jk@guXMbRFh%$?TRQ{ETuqIPjA z>{NlzRykB~QoCpiDYKDEXJc%yWFcJu2VOF@khs@qA2D7$4!&_K-Cac+i8+gMu!D-7 z#5_jj_K&s__wA)~?B;Alv1c;#fDeeKBs_H!Gpd-t74&5*wB86OC}Ftayo zBd%`9LUosJjhF{?mnB!UbS|r^^Nk3F(Szt*R$1G0x^!ctcQ|pMDkUTO!mG}8l!^4{ zwsV~8KQJngud4Rar>8YXo_28V6ZG1B=e~!ia_%z!f%t_o+a;v|;yze<)wI6wf^&z;4$z~ifc>C^z4A+FTY5X^-cPR-o%>s9U;oC~dBL7w~^}mx6yQj`c3Y-w62k0{-8X-VXRXdz;EO)1!a% za;~j1?Z1V#dvE33uhT0>dtWK7tqwfQmAnjN;7VSkz1d2LXXTlT|Bxv@wc|yQBu^u8 zZGiT~J-%V6ut7faYdFKf8Hey|`OGij3=e0LgmrMn1+AWgGbT9ma^zhHM4qI%y~XiN znG>SX7SBZ??b#=!$iCX<83Sw4G8pT%xp18nHgX<&koOD-nmkz{rvUpSMJr3A;fv1U zF`4%W92cHT!SnNK;CReA3!Y!J6pjndp{<1|8m#O3W4D*4PQxA@pr@R>u{}6qfmrj{ zy)a^X`i{n1fp^&7q=>_jjPw$SPq~)%X2-2a8OP<@@T?2!^q`_=#yP}jb;}(D* zj@p`W0I`*%d7c+1Klbf$hZuSxjT{(KJ?__+{rQSR#V^h8E8kI>{`meEY%eLTksq_@ z$cw6N{^SPY&Jl0yYiaVp(M1h8f&z!VlwdE;!b!U#2MG38RQ+;fBdLYVJD$Nd83G=8 zb84F|LRwY&E~50c)Zo=x-p0p5LQ^%gKUQ6djH`rBruw4$l zR$D!~VOQi0xUIzD94iFa!xEurF*cBj-O!$UtjzRD}?O8Ym|Dz84d$dV=i-~I_?H@-?=S`Kf zKH9&n0cUKuct!Wc_1aN~Rq6sj-L6P0aK8_JznX z@2S<396g+P1g-=)uJegSI6ELiCKJpRaDoIPB`&Zlvk;nZCmDF%dF=s^KM&zNUX|}S zw_gAj;wUTx7zfTh&{z)|B?d^KFnNQma#v&>dC!v>{KPXf_!aD~e(lK#Sz-3yASMq~ zTf0X#3}Jpbm|w}vFJ3@+)D*<}v4<1iTAkav4Zbf~lh*3=@Zyw5GvIIaqXXgZz{i?A zKJm`SIC0q@w*$=OYu?9%-2q=@6>$xV$BzN+4%6J?GxlTACnXWEVIr`?fbI8wz@4maS+P{cc&b8T#g^1k(? z`qtBgC>&DSVU|y?4=I!$U$WGuNNtlUK%O4#L|rLy?LhkiIRUg2XfG6eXd4)OIE%c( zH{=D{2V-846#z?C`5q49$doy3*TZY(Fu5KvD-!f=T;D#MehdnoU&g^=-^aIo&G7$o zeczgS`xLn3NFk8n&{Dfw-$JFfKC+S!&mBQ$zLp!?5T05!PPkX7J1pBas(onN>LZ|U zvIX3v!paz^biR(#$@860+$y&bc5SIpu(mmPP!*}4`RIMT*NGHq^=fs_ghDa^`R>vGK zA()e9II6;GC4?`t3WT67K-++O)Uj4EI{J_fWd&EIg=^mvM@MlL@*QpQ+HT~dqT&Bh zdApH%YUo>WjCJ{5Pp>KgWCi9ER{3hsx~Mw!wH{s_UsfS&U4q!R)^n&%-eAX7jknV^ zN3krQ#=&8~$5HB38QB#FgKJ#{BW=_&Xk}TYtUlr=J9Z*I#YR%gU07|k>vTaGIqmL(s)amGQgw)bXXNVKbLf=tbnNd>-V<{>P zTS%}oTvLx|IdO*`mf_mgo$UC2s)tskB@mh68Y8fDT!YYx{Gv>%+(2mU{9;|YWCLV5 zm34%Igj;Z91sA~_dhE3Jer<2}!YrULY6@ME70O`wL@iYe((T zk3%!+8PIknvqoWj!OVaLdL^l2BsD`f5)NXc*cxC*yGDvCKW663jQANo*#xu;)K>u8 zfPTXRg5tgVsw6HeI!-+ZYCk33`O2j^Q?8#aBSM?N@^{Y?dME%(cZ) zB=^qEoU|))oY-N1{y2^ArZ?b`)$^}|MtBY+#B-Y=o^-(T9o0KUQ~!(@w9>EPJ&#I86mYp`xi=o>t*fr|D0 z4EC+8IM}vdpG4Ih;Ti#L6IuwZ_OLSdkfF>~Y3QKTs=BF{ub=C%`^qK1UXia`bk`Nx zIv1V^^-(Bg=fXaEr0DHDY@yX#^m)l##+qYAhVi_6YrgVihFFgWeFz3xwM#y_GAc8V z_pUH-sx$?vn>^E~EGbl?jfkhRkcq*tt|bn}u~8S54A%F`Qm3x1c;`w2>K^7i(?hI| zngqpv=*4!7{ZMShs{7fv>Qq8Vm~|$GJ4U63tD244s8UFC3WnO~eRwP5C;l_xSa3Dw zJR?FZWq&oX?=spiBkxc3(`!9!(Qw4ecrYu=IN@Dk7T9%TiK&mQA_pK>JH25X zV^8DsUbT>L%@JIx{~oTb|D7*GgT9NvYid?aXtoDFOH{|5K(NUOl&kQI6yFWkZO zc`c4jE1y5oC+a@ww@C^6+7(^?hX!s?G`3U|gX0CvfH1CnYtifaT?KC>diBorJ z<;YFxBM%2Zr1?e<37$MgT+{14R9BF5Es(7p3Q(AJJWiT(YzuKeDA_{}Wiv1i9gIlo z0VbZq`&ACxzIp%Hg90Ine}MS~g*NOJy#c8Ds^-k{S$+?k?E;-?CZwjQP116pk)A(I z&wFdQVuS`B(g^tn)G+O8MArty&>YEjXnQ+KdkfUCy&a-ho8x->r$ogvwzn^^H^ru4 zlmop<>uz%-*U=2p_6D&7k1sXg@y9y;8S(f79gH!LZ61ZkHV^s6g1I7UH;|`j5hzcs zTAsckjRr?qq&@!|dfpp1`t|fY@QUH}^Emqccuiv<%wpF`RMc<`6{{pFmg%W@M4|%E zQ@gIr_)>`q-5e}IDiY2Cj84_BJAsOLUDoG4Z=v`w?>QB6z{nj%wthmda8+hT`{wJh zQi3eiPeb1wP zD>f)s4;k|^U>(0yw~h})XsvaW#tssvU%hP!A#wG#2uiLI{Q@n|F^>=+T-6KTvm=W1 zgO6iojamf2pl}%F5n}|@iW@ycm=*E0&h?9QyqBXn7je-&gG^?oFr&cClmbm-KkN}b zNO$+8I_f_|>J!MqNFD4S&wHfX6#3L)*wRmLKYWK&DzpE(3JJShD37t(ufg3F){FbK zN*V5nftJQ*zlxo$wJKy>Zb6+Fj0PSBIBhhbX2}Q{j@j%H0vmlk)DK=(cYh)CW+^jX zY7yu>oX>b~QhWQc@nV!;hEKY=%9dDsL-gG)%rN8meo;b+E zb5$P?wLz+X=W0;z6kF?t_NXCXgBeSbjT9J5?roQ;x`9}o07+LKW;IWtc;i=d3q7x0 z%`G&KfOY|G0`5pjw!kRLExJuB#b@+fqCT76&bLzz8QJ;o=oPNY#Ecww91M65cAkyr zzDmrYs#@fb8j<`(g*1}B**a~byA9OV#!DYd!Mnzk!fde8_YT1Ir)?ZsVzdo3v-}Eh zrIxc*jS$#%Z9_l3u`)?B1z?G@zGu(Z$^6FN6iHq4Beb#hr5b54mddKbj0W6`ctHas z|2GwUv(R@KX;A-{_KvcPkwXIiSB1G*2V?A;*;U`n4tvTkez!`1yRqsg)?=T!@MMz- z4#IoeoVOAF{fuk5;%u)msXqsM+M;1@(L6j-Do&hs8#nEFD zr^4L?0h6io3DAm-sL?bdgZI;TBY7iysf0bhqnD=j{es{hz@qY|GiDtrTFcV+@f0~I;RSJ@&nJ|$V|u@PU`}w zpP=>T4DBYy4zLS_bphx*5s)#M2jbW>1f-LHndZA~)K^t>87&0kB|)y+K_g!UqCp4I zyo`93ACguckY8FefH8y?%bq1`q`M^CTYEZAaXnD=0+1_9#}$(HB1f9MqXRlYGb2l( zwJMP)H>zioSLn#&{I>e!_1)oNefJsQyi3A~+Ns*^TOl+3?GeKj0rYHcBzuG}!j14& z%q_pk0OR!$ zaLA(?h52=_%xxOgC!x&6MVfXYR-=IXkZ2!pzX3fLdB>8rrhbFmn$94#l3jY;v{-;X zw36~(I^_!B;%81q%R+`b7TT`EBdn5A_6}a4dj~#&&8NrJFHucGe@MHNs@-9rbWv() zPC+}?MEP`iKO;rApJDgxIQVglyJDb;^C#EyuAcCJdf+Z&S1;86e@L(Iq`OPj{qNIX z-kj}aEpXQnL}LK+=N{z0GSgde7PVP#InFW5e)(Im{!~qTO`1(dFp}?@upTkJQi__{ z48JksedI*md0v3CN__~7J<*5gPsX*d zrxU;`m4&S5d|dXNwd0nm)qFJOQfA{{hNB>nNiNpg{n8i?M&+xz> zC|(=#g>n(O<*RZW;oR>-CE?U;7=^kDYIh?yqW)3&(MMXFRF6TQQG1PE;dE64Sg*iH zrL;alq~&BHvgi8YLph_d=sPg-p=t{5on07W;}Oh1V$P|F>8;;f0|WUBeQzosS5;;T z?EEZB2l=7Tyb8SCuF4I+BVTQqgm#`8ABCA}u7LTT!LOav~`Qj@9UWq!` zn%s*MVp4Zs;#Q*2!7~hY4`PqY@aF-)o23lDOV%>T@V7W~;5^)6U1KZW+IjfOhp4xy z*vkySWT>rDJry$_Hl*B8t~W-WaV4pHk?2EUd@+z|jdsDfHI1g#Ri~3u~f*J11 zA6cKmjOJ~6We_~)Z)Cl;#T#^#Sd|~kMZGdB1MYQzOq8qWR3TUA<3n${M%G`>;QN(9 zy9Q0WNwnQt(9X@YtD|)Ap24bgp%$#B*jQe#i18XKy^%h}Zqw>UQd^Dp8$771OkV== z5LTuSQt_kQq6c9ly~_FlHRO)sQ-yq8c7yMcU~;Q@^s?Zf(KW$0M>~RVjrNIctM5F# zwX^xYs^G>`TsiUF8{|Cq1kIifs2iWXo3&=w0NrTKv=kfHN;@KxAfGV0)yl~K6+kN^ zA*war#K28OI72P-RSh_-?R~T!l3HWz-R>!DO;NF0gbxl+J96fz^dIYqhb5$Cv)T&b zF!z{iPDuhiN+BjDavvPT%kpo|kn{_Mlkb_ZB^7m9I*rBF28-_Oi2q z*@i?Ka`7?r3kETE(hu-4zhE#tIoGI??t54n25%Yz&y>S=C=_ysP87Nwc6d9=?XSU8 z*4?gsCu}ZQ9hb}zi3#s0>I#p*d%#qwOI*poSJ8bzH5=`M`NeEByBACCL%a=wxp<42 zv;OSEj{nnAl-NG7IZ3mpTDMy)?N)F)E$DCGQrj=yHD#!OTylf0+MCnTg!k8ITNu|j zp;a||JRv(X{(tJROIiyy>vaZhUq4bZ`Dm0@8YnumM-Qv&jM+0)=V8AuYo~?jt?@jm zdQ0DvD)GLmV@I?+p>>T~c~EJxd8XVuh zP3$GG{GncgcHNcc7S>%U+EBDDE{ag$R-si;vl@qiQf-b#$tx+IrWW=e2-{DVPYe53 zJuJP0?>No-6Tt_yeMJxjaE=x|TwH~O0{Olkl2+DA_dX~vzt_Xa*f3%u!V*Eb;|*85 zpLZR`6-=G8-$2`Vi>l96tfLZyyBo7{O;%eQd(1SG1isTnK~|D5eqj1iXGhwBg;}IK zE|`5}G?eO{g!MJJW1C&`&>G;H_aHN_io`geV&_WTF7m>Jl&!j-9Ycb;CMt=nw>?u& zfvVH1pkjlS@5>VQ@2g_#b|%ZZe9?C-25JusHH1pO>PzJH(-Z3}4v~BM4E!FLbHqS> zNT+$TFdhY$T3MvxA|mj!K=imJ4(z(_nR!xG+$@&x^JYl8z|6Lu#7X%E%r($`OvpvzUS^%|&iz_Bpnil_W>m?okKjE;^Qi19UczbQL;~oQ zT5jxF!tUh?y6e93Iika-r7l5S0TQvQT;-*3Km13oe6GXC-uv?>DhowS zj6+x9AC;o*suW$JTmAlk{Lr>nC1X$38;lmekq~lKCA&_(fRI`qtNP}vsyU+N&a-+* z-P}p_6w2JK(NjP*2DMAOhrCP!63J0AlgW3by^_1oDSE~Moy9L0937!P1laKMr^);KKnv#iB>_|qta5{ zJys#nA{aqxo{OP+P*NU}-J|>t+8gi-ydPzRi2obxMI%27J({S45MhjsiMBW zi{3TFySl@H9yXWyF;ZcubE_(M3koI3>zx3Jyq+qpM=BpM*I>klc#dJV!3a{a`|R2u zmv2yQfqw1pXYVp@?SDMsXnnf1f4MQFa3OHIg|Pnd5(>-C?mfos&k`~VOcla^;GBVm1Kb`avv3UHv^vi23mi&_g;q1vC-U4ii4|SqoQs4{?(O2ACGR9+iR(p z`e*s~iZMp8kZc_LOJg{kk1A!3FoUud;1oU+;Wg?x8Q4=bda6Zu13y)>Bc#qh?p&gE zEQGs~wS875z@f$lYHxSwA!#0{j#_S5Bf;Ks4)hfmil}v`xgymbQ$N9g>UeuxrpG4d zfFyeiqfl{PkpL3jA1k~k#A?BG6|8^(Y{$kBS$^N!3m8Wa@q@tOno+H0!8RVFk}?)>K$okOHR#Dy-NTLaBFB>O-}3 z(Ktfu2`hA|byx7LNV)Dx%hOXjii)IqIlf(n&R46ny5LFB&=T%|>Vju*pF8>^s{)<1 z7Fe+lLJ!iaka8Zj&@S6!ZTKn~ROs8F1up%~}Ss3JRs z?oXg?z&r!`4OsVtxds|VXsnG?t9`A|WzhQ>na=oH?f;-O8hRhvn(Xg2P}Ew|nruO@ zG5=Fd_M3(^*`MiWL$!F?cp7t$%ACdG=?^s2(s=TJsL9?G8!-ydjDtpqH9N?ezuu?Q1S52}@ z&*9kYSFw2u8f|EMmoU=U9P1|sh;+YG^+7ht^^<(a3^j+TOlIR%xq^}l4U+2-aTP!h z3Nw<;gsq|crKT2AuAzihYz^hp2JIf#w3BNnp&eU8xx%o968AQnb@i$bfE|_ZDwb(h z4oYISrLr9`t=NBt6%ko6z39-FjVp|4(_j_tLcwImG?|FMy0p}rqg z79jEzvvgIQ1-Js8cNHh^xuVsSXA-)FMTZ-Ye9vT|GZNCr?jvC~lF<~?0NG9`aRuI6 zp{xl(?T6-#g~R;;SjY0$AQ88OnT`ta##dARQ9mlx(y>_+S|b@RJD@ZAYRb*}QK{o!RrxJb!AA2D zhID#s^p%I0lQ0^;aphrMLKW;}Q6 zAysMO;_89Q<-Vld4MiS*iWuU#3>wPr?9A2oq@l?|Gx`cftd3-;S80OUH(mXdv}?gt zv9)g(o+nLX^*w25`jF8&w;ocZ$?6%@%5oofEExJVSnCX!iiW3rhkGH^8tPi# zFPNQ4jOvBfcGK!9Ls<`0zvdaMtEW-!%hK1V95J2?+8bM=azK`^ z3%+OhNxh8opm%S=o>swoBD7kAcVD3W?|}Q|wda*eN_K5&N{CmgB2zpCv?5aePs$u9 z^8A{Q#DpwU1Smt<(om z=A{@QabDyq3U$qii%1OTMXH>_d7)JlYU{*0XH-Q&?T4WZ>#HcTfLg6TuB@6yRTOCm zYY??c^PNO=fPaG?Y4g#=G(iWrZrNf6#Iwe&0NZy&G~>Qy~Ey`jZY5yKlaG76;XimcwWh z{+9}gKgjmE)~BzK*p!eyeTBqt5<=>C&M{NLa9ovp{qtIJr&B8(zVf+@?}~X#29rkP zu=<5QpI?=C>QiWWO|=CzOPlebk%tTw%lQ19a_IakD6Z61P+W^6(d5$NCE*$ziM0knuNX{>FJU*cuT#%4Dy&U8ugw)GHfA!UD1%(C2tg#Zl z@~aNBISRB8inT=V0Ij9Io}x>Kr9Zp$Lju_N{U@{tTG|w>MimrT2NBTiuYN_(#YHZ< zJ@&sO=tbFMSH_RDV9pYr6(Zydns?nW6%>*1x7}>~)L$mzS4^JaEx?Z4ovPGDLY4vh zLm$D25AhuPbplAE3JToqWHem06_|5l*V9!9Ypg*`)tFQ}$?nqLueRlce;gSOBi@Me zBRot%jL(e75P2)EcPTGDW2#{XF)y zVzma~htc?LWI`%_wBA9b0do)%C(dVYEuIr*N`qC9p8taT7?_JNdfx^?VV+;p2BNl5Q_o%(-M~jqMLRiIO5O}LD z?q*^YfueQVT#Vv(Jq0u{wun|CuoVVqEf^U6oha%&Kct70>J>iJQh2W(Msp_$-i1Ph zx2Y9n_hPj?$NVK@=~Q1Pmf61^bLdc8K!g>7R9|p5{25bUFdMPNNfT<9l--{}bK;4f z;Bq;RLNg~yCVv`jr98o9DpKK`%09tGm7TGPC{VNb@V0t`N`hQn-%1uA-rP;0V_E!g zI3QONgu@Rrl?3CB>dRCsV}c%Hl?2HG#u3W1rycMfjP-~4|2fU01D^&|B#EUuzqpF4HbTE6CJY%ry z`GmadDOWA1^=d0|Y+4>@v{tEF=!CbN*BIb@K*GsXE!>Uxw7gQI0Byy>&ke9G(qL2U z;7vF-jXuL$s1D;Z(qLMKT30{saN<2S0c?59MM|M6OqWTD)-h8+;m(O3Cf|Hma1xypUTc6={>e1EKGM?F>IoXBMmmt>Ime z2#4&0Tm$Xno+7965BE;AHcRnAifAjv2f3WmK!m4+%UC}|9m(WGRH%N)IEqoOCQ$pw zOoz6A#Sd}I&{{v_vL3cVWRSj3hU08b-kuQFr>PQ9Yz)?7U|gg4Dfmdc}aVq|fYxE(75?(i%Pnp-(fGQ1hv5?U!V!h3+>=x(RiZpog55)otILu!A7*GLGn4)0Jg=i;R%lAosNDfbZg+qN7&1 zdz_^fGoi-v#8OKuvJ5Q@Wa^uL35?Lc zOB}PIV107%Nu+1P-}RC_ct#MfU_?8#A0ha^m*TlXc*DGRgflC-!R$_6?-Dn5OHY`F zX9^WVH0D_3y}`>BuLymr*aCRss1_I63#>mH*?@XJ3G{k~ry{iD@D3Gw*0dsbeNTtD zXGlvE-f#3S$ocOa_-xu289n$NV&YJeNPED6v6`UX-+)xV0q?VV_VApeTByvzy;W^I{_nLEVbyjDvi`VKM7*@avQJl%(m_E^{2lLPEpSj=%~VQmYqglCP+KRoyF zfFSlXU<3BGde#Z-D+Bw&`}2#+9l|RoSK1vvI23H$G73|RF!1hR&RJTn?FYSxSU;0B zG`$>0)6aFVNRyVDave1srDh>R%};dH*cfWAW_p;eq2~HHYJ56aJvEoz{Vk(LyxyU8-()b2F&?f_0*I!kmWd0Yl3Wh?KZc+Ppc+oqEI# z`dLhdZ77PKz3KNvK+Dm2MBCfHus7meE}x@M`^0Biws21@ho^XWij)|Lw?wzpVMsGP-0;z%lC7w`r-EUpcut5miiExn7eQk)EpibX3)T5Q)uOCX`%1Nz&J*hEXrQe>uT=yU!HD0%8WL`-;WK z%B;i|U*RS8gq2z7YuA*XpmK)xK1E#cfdbP4+K&4r5KC0c=cvtF4AeJ6>u%~Aa*+GZiP0Z-};;#i3D6u(l?T~?A@4=|3-@GqnBD@Bob-(%X|W>VUU z=<|E=ebUM`92Hs;eI&9GA_{W|*F0QZbP)(01Gbzda|PjQeP2ouh+g=8BF zyuU@80soYJS9~9agL>H=5EGyBR0L0Z?hKt~D%v6%yrU^zsg;)3n4OR%7Cedr#8HBL z^wKxZN_%;VY#swhDW0(i-ye11IY)CjV731E&wji?OzRG*2iL;)prz`JvYK#AJZG?yOC6?nfk2r z?)L@k*EwJk%A(EiO}KWoU%O{`P|K&Maiogphdnx+FfXz9=O|AtSE~I`H`AqOhpEzz zc?x;WlQC%hQDsLLBd_tQ_Mz3l-4QB{(CRqI1N%h!JCHIZO9Ec-0g_b$^RDFJlw4}u zQ|b2|M7g#XqSWI2N*sokbj`h{-#(cg5`#X=DUXTp;1T_M=6T>S_8XwuqR2gta+1;` z%nkcC+Oe{=Lrtaj&Mmj2wlH748i1?pyIFJLT0q(D(9wxjx9Co!rJ2%_N%z`B$Q>$g z15orVP0L}NIhX^jX3Yf5_-^IWMyK!?wG)a>!2J=NGt_eFT{(77NPhd4-7_@g&C|*l zv)7@c7Bx5!S>d|*u(n0Vk5GosH98KtwlNJ^@D_!Or8h~dT7(%*RdV9TMJ1;d-)#fh zy9uS3NB_bH>rN}IJCJvxZ<21Mqq`WaSu3&1Z*|6_3-*s&U;KN@P{Xu$q0Fd{Ag8CwxQbC#ps7ZD!p1-Fi)Yv8_*&> zlgk`*dUAta&o!Z`!YO8snVpXKS%KW|RH5T&$I-0Ar?0&($}JGWk4TVJoKYGm>GQc zM_T!+vIMrpTR++YdqK;NminRw#RlQJv;o?}N&z|a1K`148UDYwMe5TjBd@d%q4k8oi>@YENi{z)A(`*X03;)BqYLh(9{J-`{1?g234xNfeJR}$?yX_i-# z&T1#1I?{L=Zi|9GDNvk-thX?k?1k>doy)B_#5ETN~vlE<@e^{n#vSN*tOONc-5xM9Xr%nk5H%mR2LW;5|V!g{e!qMu3vk6@fH&oT91*Ufl|DKHxu}LE86#&-$?Bse)fOy#Z^sW4psk^wg`-pW>sEMw>wSs_{q< zsgkc>({Dk13Kcj;)e;e5hJe=jn#0=u=j-7$wq^w>r=Dnf%oA02ic1pFZQz4m#`vJ7 zV2W_==((fz!{~pa^^W&MuLn;QIj&f2v<8NSa5534st=l@ z^Fa?MYQZJ)KL3T@r#j2Hd%;MPDjlrfxmV+5UKu_Pe&@${CKEl=THhd@--$5-gH@GL zluvE{je1D6f63RhfUh|ee9hv}IAQit*4w0Z!B7)?RbvI#!~C_rAC)3s)gYa3$>bFn z4a2==+flTq7)#+eK>z5|rE38{*cYh5SQ0Y1R+QN)!_3Swv4U1Mq*`=!KJGy}4OeZb z1ypt5PJohhfNBt}BD^J`b;2j>qO}juYH<-g5w*X0dcJ7*AM0;6_U8z|=*&So+{<>Q zFzUzw;e&j@q-yXL{ZXz$5n=k_sT#-_{S)-`LuH_3UG+}}F0Q&%NMZU$n~;!eYTtu3 zP_cd;*sqe0z?n%@kw}VZrGb`v9K|R-+YW64`U^vODQ4h0pIC%3GREkN=cS!Pv=;g~ z?AFr)Qc57FikU)b4tbiVR;=a^*uS9$XzwFLk0L;PmG97XL6KPWCQxE|PgTh5`WHxS zgpt^PVk@mAQd+Q$^b|;-f!5gV)595#_G5t3k5;CD)lEm5=-?=}F0lbj! z0Yh&>l2{W+Y)$AgVcg+ujLf{!AKj|VU>$_Qg_z9L|5vh_%JhqtLctg(9csVT8mL&m zOa6;~F?!PKC+>G9?pNX4jR2*er|bSpspN!T2}^~U*x!%JCbb$Mn>VA+q|V;ONQFT~ zuC&H$M>Rp;i^hIQxpjT~?Zy^{a?M8GW}#XbbND@|>vRej?+?`Xq*+0pJFJg~ZT&z$ zd|1gvD)vGsf0ZlN9zBV5Z+fc;V>JcV-2P896~&QnDyX- z2pi8=s5@hE()|hT_%wX{L13%Hs2^d7^DJYls7;86qqd5zUqriLKqWvLzjgK{fH#iz z)+NNG#@BKA{Sf5Y-yjdGvfcu@jMdl!Ve2(kfX1P1hPZ?oXJRix|Mt|xeuVz*skcL4 z(%Vxf9AsyTW*ri6RV%SH!qCFSRsba$m$JfOk&?xAOsxe*8MxbxwJ;ayb~w>Cpe@2I z584B)wN!RE52!nw`uq?=PQ;e9#uD>G+8s{h_$bK6mNHsz5HbSZlE-AU_%f>yyN3hq1M;PrRwSMdFY3FvUa^lj0<;k*m9Pt) zo4gRCtXdyiWptK~(OXSCRfn`KaVJx1$>tW?;d~;!C~*<@cS_9z-Sc-|dsti7tlI5X zz+z;#10+D-Z;$*=f<0k-Ym#RfaNQx+kP7QxtTkl5HQV}Ss$*J`=M+7Eahf~r9&!&! zA~w=##XR6TCWnDs*d>jzhO-ig)Z|gp_#G=8K%-HAinQmq((}!D-mN|VHa$<4vGM+! zaF+25Rc{RMYR2}8ANHc2d#VNm0n+AA2I;}DBt6r@o$=No)rQuZgn{)e4&`KbvE_pb`Ee`8j3spc$ zCD18&N({dHQcHPaJ5hAE&7VZ+Cf!gMGkIf=X$IG0nn!y0L3|#`hk6VM@x!`qVPjd2lQhn=bscIc-DbZ(8YNV8VF$n!v z;ML;o&yQF~K-Qq5JS(Ve5$8!Tlwb>!XRJCuI5zYpjPzam#0kZ-L|?)PR(dK!rXt%^ zBhZ&Hf{i_UNx_QV1jAj7ae3{iJ^~1azpB4MRsbwn<@*K0g{^vcl?z$0njvPTZz;ym zl(Bc1P8j@T4v+y$>UP ztt3_xkz;sOl@Kdg0kFWUI~ZQky-P#c)$P4ps&sS<`L|=mC6ZU%p z!>2Mm48teZW4b)yi11la&Ldh$nXHFZXC9wIwRI;u0~hF_H8U{7HAa`G8-~z|^+T!9 z*ozsAy>J4gmQzY*UV1`V3e7X`Xw>q|f-N-BQtW*^n3D*=y~y{4`k>ut(D=JUJ@n4R zZhCj*?fbRkN1uVw6wUbY8Aex8-B;E;yfZ5i^h&Z-_XaP_HfTq+XNh(M2Xt3CCCfoG zThiU(MV0KXDAq|z9OYs4?-MG(f^1|s3)wpAJuCXUTi1)P9B6<$4^M|*j$*!7pIdEG zd(dG{P`{Ij`CP!0D?D`crX#Ez#$_9n`R^w;yocIEh2PI0HHNw-JsnK){}gD9Dj0c# zxm0S-0;=Cqqk)QL8L+lm?MYp!ai2qdO|*X=X;KnYw+6Hc&5mw^}uDsVIc@S zIbFi=dlf!OlUg_7D~tPMBu&9;xCnRq1ikVL4ff#Rsx|#2%*glXFt9B7ld#LKPUjV?GBAa zKLrcAv+03_SSf30r@TNLfnm|x#3K4t4svX`97oPEbIt6R$@CfA&w%;>&k|l-DZ9Aq z+G1;~J&T=Vju8unc@$n&L;ksA?gz}-JYJWDSqy>Bn$W8wXV<4t?_ybwS=R#hCO@A2 zF;bMXW20}__*7+cr9GFOlpimfEv0mbCv^ z`v$baXdIo9@m58xUQx3=CfAERv<7`*O@B!%;#oo(Pta0*6pgmLleS0$(=u9+-DtRp zEKnAc;g*$yNWFRRJM^&S0r`KnA#@9&Ma-tU$)?5s&>T2 zMd!QJ+?Z?D+)%3J>^vPZ7HY*E#?sBh;Jqxp9Bu;F@61$ooazEI%3zXq;(IAZEL`?_ z&@N)NoN*>J%~;d2x?`tR8Dz8ok<&K-LBB!Rzqi}(k51kHuN0htN56S z&N1-ajWU-SIxU{sU96$=kP&!~IqmQ@LMz)2e_FtH z6|N+&$h3JL>E?(xytsLV$VIDK&aTV}d$C&1_nFY%l-c5*iZPQa?$(Sz>+)FOy*tfs zqb1AX`$m{+Eu0JO1CmE!8P1(xEA!o*RnCF;d0b}jTAV?la?WDs zZxFdKgWA`^ElvCuXTA|)7pLN#;UK#`%J*gRLWmv#zV0EHooWhMy-xs`ct;sxe8GbH z?=xFF?+jeOUPWA=z#N+*0y zYaxwQR$T~nO8kRGEP5EI7kI5G)DL*(!28`;BL?*X+`V10ANu7|Kh7z%93*KZ`wV>| zIgzDXc7hF>+e3>~e=5$yH`vFGyTHdlHQt{osHaLSq$%?ZywPF*KjwH~{L+0?e_x^LrZn7zDrm&e6Ix?cIprTD5$RdUej^RH{ch4kB09Xpf0}%rBQ`~QGwuDl<&kf z$csW79qKvlH^du?Vx)!h?hme1Xa+=&;D!Nu=C$fjTIdNr&|R4$;JrVSo8&pbx(`Ws z*F&zf>5=sSYx6GY{BehhgP=`h?-%(Z9J8kC*Xu1EV#m301`+~yIA1Oo=K(Sgbc~lpd%Rq#lk))0v($^GMTGQuG8Z2dA|0ITGZg_(a%m zb=XBT<1L7Dn^lK9i8hT!T*Y07qD|`EmoSbma^A9sVv9{lptCDRFeN;#xwK;5^h=FK9NwKDY!Qz;x19(n#=XK9j3u$R^!R#3Egzm-S3aZvvXi!_h7Pufa&xEJ)}qTTp61X4mNa6d?r6o9zZPM;(x$!v zb2+q>B+>NmvUu78So6Vd$u*+vUWh$J831p_Pn*w&mKZ@>)O;?Tp3k8O+7<7K6#t+T ziZOyFzu+>hlh)1`TqY`X$Pu)0%CB-%B|_S>tSTVsXv}MH@-W9Zs%??6uPu-4YBf5d zW;5^@8mxafQBH;`i?Y0+W#AkGZ5R1&P(IzaBHse|7|_4KZ)f+3Ks8Y~8LH7av>n_b zd*8Nr)_AY=zSghXj&FOg?c27yTE)5h3gLOISe(0?$l~E^7WITQI>@&3T>pX4%0Ab# zc&1n0Gpum|)=gmV%u(WNs4ql`mL*}G@~bQfYg{Fv6HUQmsE`HAwGZkGaeP|_=!JQ* zCU#5bNryMm(gexsWMracOX9k_9ifY>k91q9q=A!eZGx-T^_ArNdT1rhsHNBB`u|tC zLDQaCbFT#LqE4XAkWP%`XKW`KmzKM|wOd1Ia&n;1Sd8sbB7!;L!{i{B>rZy{fz;`gu9_pH{H`28ykpC$HO zHKB!O&DHaW58pwpC_l@`8>EF=@tl_v8QLtbf+qkscWG6ltyBRD&JP_e3{oEj(gO%d zTqVNlY%%*(N;(%c1MAV1ctoH4QYPwOZ9R zcmePi&rdg)v|J?7f~SeD(=wyWv_vhqPFlhWEyr6>p{+#=yw=2beo3dGPC$Bk6FmXp zJ~6H#v?WN7NNZ>?^l@85{pow>8Y+hG8zKH>%k1^-qRa;1clR|EzZlwSxeyEFK8ALK z@6}`}h>}LT5Bd^B*t-!n#okU(yi}+Oka9bQt{Ex16SCcvgF2js?~!!;r|#{5H?hPO z24c=}MZbc#TpX|D4E)7{dng&-V6_zI8s|)1w`)ymhZ-^sPj>=A-hCc1A$-@yR=!%d zc%}Kf?Dexf3rNL_nOTeR> ziHCc{JQpG!C`lL(2W-L|n^O=QF8!rBJEj3PIlZ+VuR%0mS!HA89Y$Aq!hMd&6UfW= zNOOHd~AlnJZ8xbRVE60N`wUrwy#Z~z|j4JJVWTC4* zDm(v)ofVjL^0;{$oiydRxx?Gwh?`?3lxPiO-26r}ZqB9qZ%Uhui{5sL@4ms}yYOZc z%VOpl$B`dx+2(d6{JYHNj^|xqu6Bt%KLOPic0jcSiC@+(DMrH|c7gby0Fl#&J_ml@ z(2QTe?gVQYqTzKe{qHiP*vq9T_Rn2f)(RtWUWoaS_Kt{JlEuxhb%Aq@0Ec6InSe23 z>lXK}RNC;k_m5o0ILD-lUI~esl1X0LGf|gvtJ2!Tan}{&-qVCuwAYZHBF(^aX|V5q z8uy0N`E)}&Qd}`3fjUV7XvH8W#hb~4g;w_Ycz}Q{%|aLB-dN>>dkqRBFKjNbIcY_{ z)0uU9nXf_2Wx!bY&dkca`>Dr1^W~U!`YT$JwO)?dnOQEyztR6Fu1+gXO!wWsvd6bF zJ+`r#6yo2l6p6Lt-&TZdVp|^5 z{joFzALG@#C4(a^h zdcHwl|7=O3Cg3=tr^fWGy2Z959&M9)avVm;14YzNV>Sfa_$G=7f?mF=2vnvki%n^Z1T6E(6Y3Oxx@OKWdOznf~8zhQDcDM`eu?pT2) z=e}XSYA`Axjb@$bmsJfm7(WLzYvHGepE6B$uC&vp$C!I=x_Sdj1L}oFIB))%DsuZH zdh>`>H%ltzvf&7hlhIY0*#}oX*}HI8(?3co5zfm|QoRFz4_oE}_8p)rc5O zc7b18ji;pmR$)cWU2L`|OXC>p41#OZ&QTU&V!nb%RdF^H#Fn+O)mtD}AvkSUsc-q9 zy4X!nQQALhX;a@(H#GfjRIusyqhjguThD4)y{F-t#Z9Yr>6IGPl-48HH2EVtn|Mr-|IyyYR7OWc8Y6iYlT(NAXxWvpchUwSuGS~IC5%l(=z z%V8igSh)pMY4(+UlcX1vk$s8b66Z-XC~dTwZjs_G-6bmGE;Hmyh_f@*rA4&nu}CS+ zA-CT!FWSvUfMid)T_al`M-xoprjWIRm{DD@_R^U*J7kX2DMFzsmN<1gMh*KC^?cVr zd%^S`loZbE_ay2UXXfa(&3WN|PYg|iZ4}1)@^G^~94rLC`+`RXlg@wq_cFWwfKdwmrr^C2E5nNc1zx88_b|PfV*o=nqzb{EFXJ zfp@6IL@)NMpNklMLM_$R?vGrdSSc({sVnmRHsK@hJ`_*G$O2V_a?=t}u^O_Dq9q$4 z2a9g}TCHF3z~;#2LP;W-|4|;-mv~fa^Qa4~SYj;X%uw8eu)`CDs-LtPf8V77xi z%dy1oB`kjE%8LRA7UX3B$&_b=bcCWWRbIGhiCAKRgvAN2SoCmUF~*#co)RyPa^*!= zG(=d!f}JH~erYv5Bjc4B!T2Pu(jp0qTo){K%4twJLi)fV9h+N3>2R|cw3=Y##x2Fe za*Q`y_O_I_jzsJ&E%T+z_&#Oj8ZK>EB%JS)=xtQxY8hy$$#v(T9<|o&UtQWU`%j;a zSb>(K6A{KH)%}@gGmG%tY=$J-lfl>k6CT_Px*4imYeBq8#bEmEs`GlmU_3=imZgR5 zBMP>*W%-LOhz00Mz*wiM($ZdqnFqlyFt5vMlQKugQ;KMH*!~C(?N+rVq>PsbLDEGKIoiCo*nV&foJbgvCxxWZg@yrXYR(G-{7sqAD;kDRE)xiGs) zmCIyya!AG(eGF==m|_hNbs2M6qQsE(MPFA)vX7#>sRz#5D)-HE>AQ?9ryMKCiLbW~ zm$q=KmiD1t<~Su=s!FQFF1mQD>P z&k0-qXs>JV4v`7l#b*C5^Y#8Y(%L^6X(5lC6Qc={QwSr?xDqrz)6Lx1=#G^xNeWp6 zB5VPp@{oKwK7#O&bs?=*OXH(m;KmP@Kg#7BIfY(Ex0bAGQJ)t39wp{E@}4;3XcOR! zk7IFbYu@%Ec8Y~1&$#Vl{Baj&9CL5aRbD~(jK;w;3h-AtqwsSVpN9`UXyoziLPvu_j4f2R1z3lyWd9J6mNZv7Fd5a-?U zcCrd7lznTpCab`swKMy+9>Fq3MwM~3fi`BDq}^x@cPa~4TdV&E%KrHib$nP6EL(MBVrDuRGcllS z|9PHmmsLI{tur?-<1*z$R)Nq2O^KehSmG4vL>8qss6}vfgQO|*cBLfQ$Eo-Uyi8iN zJKAa`a(4uA$Q;SadGoGpbF7ki+Yg}1QXtN9PhreemJRGS%Q=KcSydrK(0DyJG51-7 zdgyt_T*oBcJyhpCV_~GOYv;U^2U3(#OGearZzZVmNnD-xe_|WQyvu8*8QO>|Jytos z6)8tugIW8p8 z<3wv!Fk6W4V4YhMT>g+lqf~m#(;3^pWSe6!;v?=Ro!A_`sI6*q$nXl(HpXKh1+`FJ zauUR#EF6lvfP<40=Xv5_R$H}rj#>d?%iNPeHVIh~u6q+Z0rIttmV~%J%csAI@T+8n zSv#EXdU1UmL+xyxhbvpwEzFLh=8 zkCp+*1pb4;{D{B}P0mIY=jaB2Anje2{cYzsmeR7-J%$LGk zCr7@NMZx(`BFcmUOZoFHvCmqJX_9}vh4jCUKm*UQq#=rrvf~0S!181jLmbU zCYr77T&Zs}ckIWWzRn?K@{yhHBy>MQ?_00Iet`1a4Q#MwkiUE= zZC)68pY{|nbGe9esRI*u{s-oF|E#)iz4gX$Z@?2zl*a`-{OO!C{O0TyP%Q?Y&%kRk zU?#YklO8^%?%2A?b)8c}z6yboz6vD+rj>o=$69nmXS9S@=5wRu>%*d?#iE2|uVa?B z?6VwJ&a`je`e;eR+P;z{i>D3I!a;q}w;o@Q98B7R+xCA^+Tq%ewg0Q6<5BzfYZ6z1 zx0ellF1q5|LEA#a2gi}UjE}ptNLt=XSkI)zSXH)PyJVOD3i?ah#*tlqkJ7>|yPU@{ zxR%_wXqiif>WyZGs+wJXEz$s*=;$`L^Szy6{&nW5eOJ1`{RxBH%amxc27XL@ar0J* z+2!n(wp^iXwg8QLZq7s=nAw_Qc6rCUm<$lX*Luo58xUWLWoi;NX z)SPqjN|>4Hq>U&OY%i^Ntlwx_#Q#yw`LF3lcudJTXMPDmF8D4a<(z+P&6g=tUEY@3}0i8gLDwtjZPB@cbdIGCsFTZaK@U_QDz}2}mBy zxhhm^?ec1qe3hS0EzL85(W8auUE+CM)J<-FiH#RS3$hz7+l!z0PIH1fI;Tmf(^g9J zXWL!<`F%+8Lyho)VA@?FvSMas2OS&D>c^US>Xz-J>IiOk^`>6j?kXZVDDtqoavc~H zn&%KPryBFA@yvjBIIq-()gogcnX*0B4)8=aB)AZ8=5NLpjcZ5N^)m32{X#aE*Cz?L z+8X?|Humlo_7)t+2V);lcgxD9+z2@0eQmtKi*Mtws%5-2+BJ49vTrgI_Z6r3dPeH- zzC{CAd+-`jNpK!YIA{gPuWl?}4lo<>m*A{w@86-3EB~{b8{6WKDA_LUzd0hHR8x2dXH!V{Pz0fN61VGK}1)2j&e=jYwgow){vH zy;60J|K8O8eI1&2&(YLVe%*=mgd(ZFMF2x9qmlEFKi1esm}C3$Sc^N?2Jg@3EplFi zdF=(eIARz3N{iWTh|59E_&40pE2DM+yWKDwkK^-s*;n^%WUFP1u zT%c$>2Sa;j_9(t>jT|W~tz8?e!;wbgK530aF%8d=FtVXYiGK7rpYgV_$#~On8?Srh z?=)U_bG#Gk9yDYgP*hZrJoM^(?2)Vg2wG_5$;MoLk?R9N4=C7?hsg_4%7z5%jlZuq zjrhT5@-`>Mn#EhxCDxoTb!pid9aYlk-f!~#8TjX>K`DPy;2ZNVp*EeG`N6Zxj9MdU z%`Dn!XiLD0qYL4Lua#-$oNKd4gVa`vGJxJpk~Ywn1w20b`JMxdZ^$tV z@LlX>cV{MtU-DLbOS)OG*rga zP^cTZ4l76B3Aw*^ku@VOwcP7fbtVwzXy)Y{D^Uf!DXEmNPlX-=*+8|*fM z)>Jj)3uY@>Gh!ajTAY1a!OZ7pXM)4Kb)exm$7HRKRU1gtdTRZZHeN9X1#x0ppW|L< zw?W)tf5A3%;~Zy?boz2v%x~!g>mdTx)=oqg#&sNPcn5-yCS!DE7cjcm6(iCBu6&GL z%w8naAup$!ZNM z6PoxGo2}_A-3y?ZI|%6g6le#8$m&jUz0Z7QvOdvnu6z!6%n7vi#oCY}E^hHndB@;9 z+Cx0*Sql3mSS2YVI&WD_YYNaliaKX9tYnPZ{e3geCVsl9d2(tLX?2cgn=&J`viRQ5 zbvMlji(s(P+(#;mG@Bz8MrJC}oVQ%Y@!cxY-Qdy!=0Lt}NBqavF9rVdH&}7Eft+Gl zum1s|nwFGi_#xj;r`vC_gg7?kJCJ`L{Xj4#?ICLYi+UOt{h~L0g1z}X+z(?&vI-F19xDSHQE6b{3w{mQX zU|%-t<7!5Mq1MR#CUZN~I5hb}oc<9}tS5ZZPOTZk4BN9{a*TNv;MR`(aufL#+;vQ1 zUzHI*&d_^rHs`g7HJHqG)gsY?R*E+4S_1LCu#+WJCu9U^qf31s1e*T zk0rhXt^~WW`pjHPzEs;=n5VKgYo*T>A1Ttw&I!8lcuT@?lPt0F1sBbF$Ucz7l)Lw!2n@mrcxK>fJ#qpm*%FGqb#>e;5p0P9s^u_!* z7@NI`s=oX-Eitx5mgL_G5NSnOzBI5CrB(9_bJfV_6pTf1jO6~RFODn)Q5)GKE#|o~ zd1ii{nni-3L6TUuT*y&TR40kGwQvHKfg|bFG*r z#w5VbkTlhP0S}wUsCnG$NmCY-D_7O`OutYt@v0|{IziS;&U(@xINCVtNx!2~V$G4W zo-|nsu2isk(svnew$3Cghs)@n+%SNu*YXN~3UT1`hjU`DJ7tCAy==^akyrRi&;IHP zzZdk_Ft9~DMsuw4pQ+pd%-9YSn=hZDz4ZZRx*y*v>hr5rs1ncB_h22`z`_9`k5O*3 zpjL3F4qI!+jf4rGpEIDfB=@FfV3{iAq{rkM)=}&so(~}QdqeXSXgLZZ(bqRmrZ~_< zibY-Xo=A0RCsbn{(2DS&DthBhv3QvY0-nI6+|j@I)i{V6;2K6E3Z8e8!wp~ zhL~_3<(SY5j4P~rR;Uv&4zU+?EX7J=l}sjiFR~j1jY74QN%P#l56>cM)#>lO@ZoVN z(WFSG4|lTK9(((t*+^&PL_50RCP2;g&`8w9;ndq9&(<@Y2u_VjRAo?nE zd;9$^Fz;b7A#O(+g-)=yf_+hu-1@^y}RPFxRYMm4+m`WIg+W&bR2Y58MeB))FWL0*XSY~juFjm~y~bEW`?V|i@x=8*w(q8A2Mrq6hShM7Lc)Yq;J zgbM0*WVRlV&t-IH+f}QnXG8KWxVH4o7j=BGikGD)V~gc;X+E|TX8~H8r^m!1I!maz zOmcrbL)dx*^s7A*`7yYJp!d;r4Vu+U#P#|WwiV7LJfDu=p^|G+d`i2zPNQ+jU=bGi z9u0XNos>eH{|8Fu1dB%qUQB@|w7)iFn;?GxeS~=AFlCCt550aS#6ST4H_Ze8jm;dO@^UO^qk7$5s1fYTj0|Cs=+$SNQOZ(z6<{ z^^yvC%#_me@-FvWtn~a*mwTS0^u#Rau34`Q%*Ls#HJ;~GHx{_lFnM0UUCuM0^ zntUjYZr|0ivouc5tbg_bjG&PGpltP{ikvx->SpoVAV6qywJVR)MDQ6?Z^6^>EVI%dUr z(aNYkZFF-6EbzVlP#UWw?XIYW&-%ajkzPaH;lr4RMf*2IyC9pEor154V%C@*$!YRM z7B(+5o;7e6j9V)N`LWrg@e3_ExM1EVGtloqnQayq-m_Xnp#}aPEs#Bn*U^zj)ozQ48F zaBPk*W!PXA4Ml`aY??RATE4CmY*0Q&g5541yw-`6n# z+i|;#bOpSVeDT8t^#ju>vz?0_Ev_+upK6HMq62>QPcAogh+ zd*7J&6!6$AldvCYj#yhY!ZE@C7@@=FyH?_foybGXb7;_u>v14m8TM?)nqd?%h!OY!D zkW0u>?MOazm6WSx(MZ~yAWwvBn1Sg}_M;rEUNaDEsuK#qrqcUCCf*5ydMjg8L;e%g zS_}m%mRH3qaozQdYt=m~3aSIs+5h&S&syY)-9LGD%Ic~OXzz{D*xcYeE%(J@sN1ti zE!0cXLcQU?KJZ^(_^4XEp1*RQT`U7tE_Sg-qf-xs{E_`agLo^?Iy zy4Q89E3C_`%G(6o?8W}g>ji$CIxV!PB2YCO?hQvN%M9aBTCldJU)|1%+4XovoCEWa z3vUADg}<3GyB;%m=hPR^v3q<@J(5u2wr`XDEykZ98>prrQYd_j79oCHNcR^|d(N(p zPh&Uc0^{ZY7U&^OYCeef4yt?E;4S_R{V+4!Zh<+z3pIT@jYzxK>mXrx`lW2e5&cqD~OCVSMag913P{-trC`W_CizXF<57%Mfa82yjaqPelu1w@I!Yl;UF~ zu!Y5WcKTUJIqKt{wP*VhXod6YkNBGkBE6alp-T5qV~vH;j~y7{%ZCqJzf-hYnweOl z$jGsNC!0|DU3>MK7MpA6ZBEiz4`sykkbuo-)8<`7}~)XZa+O*;I(P86vk)VCfdDK5{z=mW?sXWlKT@;W6(8L9gqV zjV~Ps;*bBH3jg*4-GI66_^trjgr9w(r9a9aH1?zD>`QAt`sksT?%HPYcOQ;Oej8jH zc0PA3@v<;Ws2ki{Jt?%ZbJ|o`zcj{KBieSL+UjSt&3sQv%1L7U<@xQ9eb8rLqEaV1d6_YgkH z1u{2b6y_bpHP-MwL~+*Gcw=-5eDF2h%AqFy+5WnjyIWw4KstGFpkcS7d=_Zsud}~H z4FS8$!W`%WJ%5e8E;%^2{xvXhhWMR|xNNe+f zwmsq5^$jo{-qwNmRJJtuo9vvR{T*0CP=E0ep%s2pTlInRO(X2h91fnR8gzeMPS_8) z?>V5C3%{X#1sPGf;i9_z(&&ZC=mU(qThD0wn%*%*n*!|%%l~|<7Q(kbPBd<6o7>Xf z_UG2UZTSC4g%`&E>@vm=N*Lq)eU9;qowTBcX7p~qD zEXsX<=I)?|?=1xN-j-eQnP(sLg#>+%3$(pQ_|{gTWir^9Zs1N(RAMitnxXDF^axo)@66XV4RNZ$8_3G}{OEi?jVKwQfuV zV78MMH5daI^s}{&fCD>&Gl2u?U{vLRZI_US75Xp^{7%5}K7j*6O!{*e{lUL}Iam*r z4_@&_W^23113ZO#@xUM1BJqIT$!&DuK|b+dsl)?zBUfKk06e($b5VZay(5qHX3I|{ z;03Ewke_+p+(Y?kc9S1wm!O^K&OK3n=M2kI$5!T;pTVGyHxo z@}oqSCRj~j;Kr+aMM*-RmA53x-1y$4&$*hIB>hn0#uwC@NmAuDQIg=ko`)nkHTP@6 zY!G)nHTM8%^i6DZ(%fNb^o@rx`rBO|{huA8Bs?jM-nvx}{SHopA_pEm3>;qSG7i6z zaKKyqd?#47)fc)|!6A7VI6T*79Oge^kX6Y23O^nB9^ zJvmS#O{AsO#Lni1yjMpgT0W%KOxNbLin9vuA9=`?xa$%pXxFf*BY(CscSv2MIa@gj zb(mf2HCuk5u0@!sr%ZgE)G^(;Zm&2~n28VThIZliB)b!C>v>S;)SYh#<0Cw8t9OYs zI%e1MReQfQdX4Ak_KLyi7uo<{tbbY=pGnhLOPVf4X|m79+)C1CWrr12ECiVkZQSYi zy{G;4%Oiu^GZ!Ba_boiJcpj z61|jfye$3v^q0~pdkT|Kvh;lt&c}P=d{7;WR(6TtUqNrDR@`$O?)C-qY+NzN)@z?B zgcFOcd;24VVDwJCm)*OVa7BH@qY*vKR*k}`nz*=_ul5|AA#*2W`7-=$0Wip>!F_Rc z_8v_fiP;Q|7L*PFirP;cJI$o{T0Xj+AwyngaXj$#0A``uwK*Yw-4~f&P^E8BT_2;h zLgm?Ji)Y1@DI!`@tM_O(Z`<5km=CZSfSzQw*yfu~^`^it6x~$}S|>mKg>+7S&Fs+& zq8q(I^PpcbFTMShIV<{De!lfYKV~_d1rab7gW*0w&?5&#pCI`@saAvCR<8k$j7R?^ zo+py@R)pvge3ZV`6OWoPB^*be?uU3TdIkMZzpq#Nr+a@xm9;tqYT+iYhhDrtURGmE z4)R1#+!NQ8@5&Ol#~Z8VcD0FH;|BL`uxaJiml(^ zFMns}ci(Cc3w)YkjyHv3_EX3fFRHU4#jM}wuE3~1Z^7|EtASNs66SP?-G98*U+jH< ztBAuW*ETkcu=Tq;4j5ha#KE`_-tI|iK?{b62hPZGmaT?y5fx4&?)%`a%h9@#?*VOw zH;!eo5xnb<^#kSeO$Q&T6nhSsj^l|d(;s;gaxeCu}^3UYObu;ZQwG`sD% zSpTatP8NcX6(tet#i2&vJL{KLK z>1Q5>=$#waB1EjbRCK>TW%s~W*c1<2wsW9%szO0Lz*{i&SL_RMJqw9uebiKP?p9MR#}p&=g8DUWfNZe!YDk5+|zt_Ix< zoYuaAo=L5?a!=bM!@T%xn3!v!ZmCz>IPX41{DqwXIf*$BV<0QOVeOn0e!|y|-Dlz* zg&TIZy=6af>@t>P=1DnL z0>n8xrA_l}v%+jMrjs^U2N2;5YRmP6bDKhsogF88?l&SwT%_}-W`C5IQI@t_?7@{< zYrm0ql}ipGNq(r{gyUo8a#7vd)&fs@W-Ii}B6)X4BE0CCCeSm+qG#%1(lZWTlUo6A z$acOy{E@#2RC&)e*8nn)nO)$NJnorPJ$ZOXw=<2HWAd2oEm|wu0eEIuZstkw6-a&r z7avx_`&Dg;;k-Tcf>#FmZ+Hg*KPtLJ z4)xdJuRSN`q^y4IWDk|3eNag{r`Pt(WBaV%v`>IHm<@uG=C9wL`OSgcRBpXb81+4D zq2cc_^URlATLf)HPb*pmE^X2uy<*#n7;O-9h3x#GKf^DocEE}NpxwwDfO!f|ZvaLZ zl5k#sM#wNlKfseheko+jXj;VoDgGNBg8qlO^$$-hj9g8&#sMf%-M%-QoB6j-I0Zu; z59Te0al`n6ItL6lEnTGB(6Cx4$e&jl#G@e+fjBQrk1br3fg#dj@=`XcEhb z3m79?o-}T4yQXbJYh6pmILqh{Se!L&Ahbjo3Ru2c%9^zO{>)bk_ez$w`Gt9gJ2joi z$Sk2{cZe^bpCJ8>M&|?c6YzXWqOvMiXpP@AR{6odHoZ-hN$@mwGM-Z=$2njguY98? za+GgeB(4Oas=(drq(~%r8qKKc&Q=l2e;g*3;}r}VtJJl0I9Lvouv}xx5XOFg+bYi8 z9}W{s_xZV2qWo}mhI4*YUK|ePk4w?a#RBEF_T?3T?7ZcWkhlC3ScjPPK4%5yy)UcE zm8iS$FgfO=&N;7K?^K}PvDX`qiE1q0uJC=aCyPRqB?=6YTPG5|WtNu39Bem;4N%>u zuvx?{Vsh#T%lbLWvu}KzIOZU;C;C@x+o>P+cCq#OIWAXALiU3W`m}VMt=aMsmXGX^ z!K!~y&T-0%ytP@xg2f-opn{T!MY{(U+}6%<#bSqrMNb!BbJJ!~7h~3SgSPBin+B$f zdy%%dP>NQ5K%8p4whyesPYh98{QWScN~E0WNpUXm8$F@65p^22sHGbr_KZFIAMt9H z#j6I#jQPRZ#rY^UM9GB+ggM9E9NZlk`BLKU?Zn+=b~xCLe4k|e9S;2cJo85>CV3+MC7PSwwa(ThXi>OZazAq6 zr)bH|25g;{+?n*Po;Xvn;N1)^DNHA@oTq0b%&mOrF50!~TKaEx=g%{UE;6b=wpm(>)lq_dNbUDVp-+29`kp!#Dy2S1mA|Ku8GDfl`mc2sXxy& zNikK(Ss4 z&s;#1sXO%#&2RbMKi31IbEmE_Ic4wE<(_@zoqDp_Q{E%(YCy6dn(x&4u6yK2gypeQ z2SD$Ol2JnAHY$5FWiz>02z+mLw-5@faf6QCBM-(!&gYprf#*YWeXy6&f1Ptr`rd-t z-v#QI1eHT!xy@zpCXu?cwOCMw91_ZhgbVC!K_?ur229?LI3ygrqlwuIqg~)^u;7e2 zBpmWG0-W(KaNv|+;xoY&j%W|90$D_SCOLNONwi~sAe~MhFtMK;JPFqCX2~YH=P=i= zC~?S>#wt}`>4^!-K3C?jl2ohcDqLHKEu}xUIOep9P)eP1ezw)4hl9teRfPAhkjFe0&Q{%_GP z!ki_iUDS=f)f3$myC`3_TW+bMvUkfv94W1TF;U^UoX?FhSXJ2)vkO~Ta^Q{^Bbse ztwLZP1djLby{Su=>b4F4Taa)x14j@Otqaam;uBJkt;A)8P%XpyZAH z8DNBWP2oma(3cncsyHP2F_#h^wGRJJV?yNs^PsJlA?-PYCTw>XboJ$vUkxO$- zE?wf_lFGM6$R`vyXG}BBXn7lBh;Rm%-P?9;$3$IuttOrSAP%EIsbcGkL+2)306UNC(vAP}fkK#1XsBxNMK99AOqjSJsf~weyyVYh5|8-sV6^ z&nx??S4fnJKOH6qmRKI9-$73|jhU=o6PeJ&CFD2Q%0*)?tL80!A-7;z$24d5dc9K~ z%hIUJs+{w|P7WNpSEK^xqe0MVi%bbsH3!q3=sCD@t9_#zZ%3iG{gFMN%$IL;!#5Y% zH@fY;3vW~6-3rVVD~BldwC2^u-1>15U(>0PDb0fo-2HkRfhTdV5;KU;K)lFOS3PR^ zk?ouD+{F9lIr^S_$i7HdvoQxM*kD8ncqwFCjwQKv_||1z1@lx3UKm?T;fhuC8GNHB z3Y0dYKZ~zpyqWoVrjhFO1$}sn*r~%Xn-MjZyieeF%Mt<5S(i(>OYW4xYldJqb%ipO zF8ObGhpNj|onuqwvXi|>($@%7iTfM!vX(N{ah_iJ+?J-lpfp*vJIbo<2&CIhDA7K9 zi6j?mn2Gtwf1+>o#B+*$_N-u^&8^=Zxe0Fi=Rz%josn)$yCOAB-$yE&w)e$Xl04+zy~fRSXsekmZ7I8CFc^CnE%3-5Xxe7T2C$# z61V2Y>9aryQD=qu6*`-h{iZePe)bw;j)yt@@~%ZW3m~gFD=dee^4ng*(&C z$1AKBuiZh#pUKp}9rI=Hk$&Ji+au+BP-utg!d(s;(dC>4BSIe0woHx92N&IpTE$&D zGx&>(bS{-{oqc;4JaF!iyItsaI~{Gy^s}jOu|M7==__-!KhVY;2KkwIS4y0{S3NPu zxe{-eA&0$ky;PcXiff8@>+qc6mg)bHCGkQ`&^yUe>EtQdf4-lp4{x#9rsetnD! z9J%`ESX}Du*g4p3I$JN3ond9rZOiOyx2!4`nE^Y4b_1sdm}LE;XaKNcbJFA2+dRj- zNOwE-XcyW=J9Ze1;q)_>(6@S`M6qKBNOo*K*s+CM@*|gkhb@?1pylez{0p@4{;zXV zxxtBn$S(T+q`dcY&(+S=0`T8?+QXW7GSp@i&^d$K8T{@P>NA_4q*;W0kF5jw_qi(? ztDN?+!%~E*5*s^#ASHxa+X!)I&e zT`7kD3C=w1e~8Zu+eLg>MwJIX=Ggx&E1m z-TpWDa!Y_b9roB(h7d*xZ)oPN?vOFGT3J=AT+kS^`#B(n7&haY}?{*1LiVMPmWl)e^KHTF{)e7yJkfuo`SUPQH7w za@er|sX~G@-GbEJQG)>S;=IEwOks8{-bJr4`9Qau(B2ov8wcYROXEeX@rpVfZ>Z;Z zgDTc^q|?q(ZGKIFQ9s-#`r^7-qxN!)%J^l=Bg?14d`zunPp+9Oaoq z}--W(_r8 zthZ;8S1mJT0;-lB4>cf;U(uGiUBc{h3o|#l*kbYjQ;$)Z?B>6(8Lfs}-LSuV_Os=e z<7!t}I}va_5pbO#;Y$8au)7w*O*>VFvBH`tz4ls|1hY{j!Fkf6xpSGrnCYQpj^l3g z`6R&oB*6UxsX`vwAZ-1)$(_w-jElIBdD9`~?qr~Jr8Fv@ZP=*pawoDH~PcvFGysX+I65(Yo8FzD}?Gat;EE%&4eU^nasyW!T%-BRT+ z@^@-w*AIf-=Lt!hpYT7_<~A;Ljx~4Yt(ns#Tv%Qu+X*j{aOwR&#U)_*J5djyJz^Nr z3BbZHBgK_P%b}NqAM=jdRQ@+s4A;wTD6cM-b7y+FtS**n%bY4z0Bo}4#7z&``vCe! z-Nq}sB2cb_2P!B1gRHN-TlrtV^ywSoTDUD^?8Qo$=z+*d@7|A}MLof__O!a`fK!K5 zhwl#-PHy@JYkctecoVJsKT;=TQhzJ0upt38h@|6;HGnodWT4>K3BBvm?>VL+mrySU!JmA|9_IyHw z#M2*^1G%tvOZ1E4%tM3&=ov5316~lcnHQmF?o5fEzW+md7%n`wirWpC9VlzDtx^WQ zs3kB4;Y-hc+1C77pvwL9hM5=Y`V&uY>>juph1dq1z^K|*<@9C57gNgy;0+oK_z4-g^UHnqSeQy2jk(-;k zZ|MV-i~U;yP~SKhxu$t}Ti-}kQ!=u*`Mb6|BUd)v6}h76p2+1*_eRpq^0{n1&4x2- zbgv*0IFsTjhI=}(Lh-iDOVSSUdzyE4M+QdHqLI8U^zZIu)ngTbWDdoeAAwIgo$YOD z!dsvCRu+1#SHde&VB}|mbpMZKz`!@~*A&Qk*}D1u)?8y>TU~2M+gU9)L*-(brk@i{ zx4Tfly&^Z`98*m=uFEl+;%0lWdk$1rSZ7sH`&(XVytARo1FneLg{;oDFa2}Uxp@L6 zKW6I!B1M`p#c-ZqPOU3XwPub#C|b~X=aX47&N^v$POy0x$Clvhz?kFK%$w4RETfTG zPOlyBKG~aYUQHOH4Ok7!d1oeLA5VZC;!1LX&Q+UAQfikoKS)CXp0zWOZSUtBubs~Xx3>GfPXDMQQkBurJWg{sB&EH&fI zx>zUnESf7~Xkd^Tf{+6?HQ}Hn;B=y?f7N4~pS9D}>6jNfw1Ao7Iv= zevHOtvRQ4dFRwF*=`+Ae#Zgx2+NS#cLsI>62U0D{<}Cu%+@HX0qtolo0Gh9o&e7F4 z`*ap_u17r4+H#2+0@ovx%MsFg#B2+QAdy_E()VLa`sTSv-?;=8=cZuZoI^<8QHpM4 z)`U~v2VCTlTX?d*-zd!-WNRW7bSF}!Vys2QXcsC*3RE0<2rBH|8FRDj-I+4*_0Tx_ z9sD9%uovK?^(q}d2j3qELKa78_KK~UrjAEi)DYjFnN<#FtU-wB-g<`A4Yq4gr%Q3d^Ccu;m%muI+H^2V|#iaQ-|T6DbT zLdOP+j>38C$%h}#216*f&K>aL)tI4$jqnkAttajEk#%Yvvuv`wZH{bG1*isEE2yG1;P`aNfj2$ilmd zM345MqHmX}SSV4^zY{8oEh>s!s3@?gD43V;F&E5-i8=(&Bg|s`bhEljJ3MIW(`A|t zNH?~&cS2K(Mbl?4H2u?}sc_y$hnN{Wap>ung{=B_ptr4$c{NF2dIMMqcK+6D&`MpC z;>ih4Az*#0CnvNm@Z|I-<>a(lI5}|(=_wq+#X@p>UFNrlv*UFcUwYO)@pT!jKZmWv z*JV=lo%p(pFMYzkx%FEkXEx<+c^GoY9*x}4v^sJsycDwy-jn$pPG#F6e=H$I$05TT zR;8@9nGSozG5f2PZyJTjmbg-VX+yGlFD7|lwQze#HM5yca2ws;WwF|Xd_KZ6h#P;| z`Ka*y9OIOhzOA!c>s#GC;nO^OGq3970+r07sIAhB3IlaCKP_-C^I3H>;j}OlP79A@ z#Zwa56CPGs4xARA7skMdDrO-%wH}_FeCf#&FR31-X{p_5S*JZcX~K6{g2Fp2LkxBw z6m>h9L|q6XZShl?7CUNnOVS@z7l7!`jof5x@GfLfio=D z+33ODSWePkN4S%Q*Ti zQN|6AHxx!%Gp*!ulbs11^?WtqcAO)RGm%exWxyCpw_|UlIdymn;oN|?NPOwr^6Gi$^-I(nvj=^sj?v#d@gEw@Oc4?c|1w{>~+0n+GxqMeO?D(C~W4fq*D z%s+xtLzg-6xi>CWwP?nP_as{sJ(3OPy1^a2?^dx&^k=Azl$w1@PH$X0 z$I1=-n@bxpoBK_d-|gDckbwo-P_+ft(YJcyMbj2=)|Q4H?XYV}J<7S=#XI-n9coqf z7*Dx9ayQZFtY@f6wWNMVGvQeIKz-M1N%e2F<)31nj#^TenWJ#rF7?Dst|j#&>gU)c z|HE2R+*OD5Je6VdsmNf&lq^@oet5gi?R7PegYtXC8!SojKRzUafor?d66K(Km`?7ZmT=CGdJp_?=I7^9eC3w{<+d$zA4sx&3RCM+VD6PzJxZ6T zTlQa5XRlLP2hu%tdwp4XOZ?0rYEyW93oR<8b`;Y<_DziQIoLL60b<%UKs*B7u*tbWb?Y;xgTQnaNfBe0?}73Jh1Lb z%QEdtSlLx8QJ*zJ{pbY{C7W#J-eCrox}#&2=>_mQgTA8-ZoKQoJci28C$LvgZAZwP zFmH&pYo2Lq#DrU~Vzn&r zEQWfHN4jWz!>i%kPx}|BI|_5Q*~KZBs^h=5lST<>nkL)SUNQ zxI{f>%?QOo73+^n)Obsx79GaCVVuLBH&udY-NRXl%^6}SOAy^4k$y)Bnr7iU(-jll zSYj+N5UMTVT#oP*V&mf_NAC^hIQaxQI^IK${_G-0=SXsNlqpBV|>(RpF`|h!2c%x9QqdU+W%x zu^*yf*9fO>l>(6~#09~k<-R-gH??Ng+IJFMZU^J;-WdgWhTGX{&)}_Hp26J6#Z-?Y zCwp<`HSK^v!F9w3^^K@9i1W!*y1jIz(ygm>Ysu>9klMBAS>+m<_yITFa#H>k-O|4` zXH>o!cNXy>miSJo>#!_=_g$}U74bjyzrbI#)N$UrfWKM8nd5(oEB>KQ@$V_&-`4~G zU>EqW&Jo@|8VI*YxzC}dWx1t4F_R$)xAxu{%TI^9=^JfN<$TnDfqB6}V!Zzw)J&w0 z+5IHGd-C2}O?YpU{;Z9?y@mh6au`zCw+9bYGR{8sfQjQ5OBrYAS%Cf3Aw8Se_onpR zY_29*dS0bAv1=XDb8T;so|!G8^uWz=&|yyLk92|iwoEhG$%XwY2%c>F`v*;W7t%XU zLNrv1M82X-?n|Nlz`FCTS-RKc>N|t|b^4Cx1afBej`>C7tr|W*rxx0t3t-k3YO~;l zDZbw&NgLn{`*yrn<-ac$JbMWC4-NvGBKkJGEwUh30kcJwk6^#F@mxf^U2G24_wjCZ znb`_qVqBM5QaO=TuqSfbxC~ri(t*-})r;=jVvk1mDx7nx&x)hH$5&R}UZ(5ixix(Y z*-;^Nc9YqoL!)7Se{6{JJH=yu)s^#qquq{mrJ+BQPY>;eIv)R@WeN_4eRm9G3eIev z0#?oxt#VB=9Ei7NUdiHLd5}4%hjZiF(AG?D_GD|_Yu$a($0~hM)*}$kK##|%$G0Yaj$~EsXRq|vw`HEqZg2TmiSzwK zi1U5i(p+)nq}lbw*`U@?kc4Wd^y&N8z-AxM_ONA{J?D&v2usDLszIqf#;YxFI_?dk zZ;^TC#kwOe$BoR>9Uzgx<*}_Fv-o|PN zY`9zH0{eFW`z8gpAK(m1^)^;HVEoDz#xDWJJOxH%+Xy7c)*oltupaz`_SI5G5KU2oDXz>k+mrm4nECY$MS9CvE(NS2@7dOu| z*HtoH6mQLZZ~#|X&x*%r?RAf@f^~JofwQPh<(fb^58Av&ZE|T1=g=B1JTTSJG+gf* ztanZGMX|0u#v9PL`0mMCX#UEaz?Jadx$s{Q{yPKyI~xA8)^ws6ApepeLnZ{Q`<|dr zS~8#R?`3O;`GwHt7HX4M@$w{G`TqEVi7lD8_akNJtPXCVu@MKrW$c&fACLW}`<=Pv zJTDYiudAauLiAJmTRQYq|XO*8V?|^|#TN(%)9TQ~*`FXMQ!Rmv6^1pS~le8JU|qW`BLeXd`n=d)e0myG<-F z0~q(icLU+O_xBo^mX3TFud?LzwSh5jY{uU=eBJ%d4PT@m(&+!riw2+9hDUb|FY6gE zN(Zxgq+fIQxVHTDwS{qQF#e0b<;Q!bmmbtZc@^=hJa`YJVb2nH3oJLjD(fGD)N0eU z=()h-yDEX_i?k4jSqS|;Kd48FngawA`Vvgk(`Acuxx?rNcsv3yg3SelN4|weUL31b=f)c@XK*$#IB_SO zU`27fCG*NYm_hjWANw>zdo>#F0gx9S)FRoYWVjp1#ghGn75VW2APrCML%G0Duk1t4 z1*!nUWGJ)>=tF*yoG#Zw{WL}^gMW_+|1kmnM1mh6_%jH8DL}0u`1t7_3w{XrR)z3^ zmjpi<3Uc_x6}@FW1BI+`{yS`;T9vkG-(TH}Dhh`%x+{)!;pM-c7;np5;?O~-(iyNM4kcKqj9 zYsN`N(j4bz8mF3Io=do2N1u<|w>Vx2T)yS7u)o}ddO1P8m>`S=>?`Th*&XYQ3*!So zH=p-kU_ZwkV>XR3gWz>^AlFZ$&mVQ18czY{BM%GnsV3B^1ob$A(A1%a$J3`h?emOd z<8gqxul+yg`zUja2#s+B!TT*?K7c+i>F5`)hB4l5KOBkaZ9?r$Q1b}FV!%9yKGnD5 z9#gcsbOY)UKj;zM-zMIxh5WGQOF^H6?uXB?HkaR_g#y2V&#;D!yWp*tm0GCec|9B` zFHBE@IrN7L)5pWV0r+kgkDf=}8k+|yU$ceC>0(*yY3{9O2yYA?Zk1#OA|{HMWx1ANh{=d}^q zQQGi>nR5>M!^Nr02T!z=q)S zzH)tCFx)GvpQODC|J!X^G(H60F&&a^&Pm^_;l4ih%Y$Y4Yb)ex@TBz8L=9+pZ650R7i9 zUC@DJZ-TKmw*PO&J_DeF{s_;2fBy#K;Mk|Z=WAf>Q{mtBGBmuV;2F`FpQ1X)GTvs zv>kV~2jPU@Gkpq;od=(OK>BaP7YA#}hC(|B?GVs$W53*Y8n>~vI=C79>X%?=k2Dqx z(~gXkk1PKy^N)`H<@M!-@Hg7QpJm?dnE919$o~8Fj-rq+I%tPaD?o`!FYwJwYdNg% z3mpiX+0h?t{`5;t-|)r0+rYLz&0nsKd=W;{j#^tjGp!f+cT9&!oIi-wq@YsK4e*|H zvj%!WOGoy%$Aj5Epo)`PvNThn!)I9UJErTqXLKL$%Z4@l?1T4-msjymaqH8js$6PI zzk~c@i&CYRZnY5mK}*62Yt(5$s3QXB`lvltCDU57I(R#*P^Sf_)$qUZFC8u>qHddf zfPahmOaQH>XCz3ThzvG!hWDrt_XXkjH26+`Vg{a4fm4;^87IJ7fqzv)T!W3g z%7k%^1rP>h81F38nQF3jL4lF)lJC z0qlWGVV8+ORmLz#8tXsb?9U|Pkv*TAt&`z-V9Sm?7zm#a{~mb|=u4ajpN8P4`E%jZ zz=IsdSp*}Q{bwHr6Ddk&Kk1{7xZawVQwguqQf)_WFjmcJ!?`Lgy=(}++ZC-|7V|e3 zzzdyt#-+FHK`tgiKd{0}^LFIX%j?OkZx!#2H!bb{Wz}qStWsz8=!Jd+y88l z%7#-_C2y{MidG`)H-vu2*MoC+oT}?Pa$!91tY+&fp9Gv5vC=z0fye_uFgT)B?M^jn7m;c{XOOSNzb7swvlG!L4isY6g2=yQcCz`) z4#zK(%wM)TemN0#9OuhK6n)tLbjp2ZK3r-x$=5si|BREX9F}o=zzma?`3v!q&UkUZ;0Me)Z^9PLTKl$|i`}*T^pxewb zSX@J;y)3b$;N7?*mqIIU&3+2TTv7TU-s4A?aTbw>V< z(_q)h56-c;7zpZ?hQJ(Z&OvQSZS1;c&Iep0{1=_pe)TlWmt->)*bxU=3Ye?&X5w!3 zG|E#VX@cKjjR(v%o{S>*tEY{p)q-4;f3H1@V>w#FlFiu&YgAE!lUX)u<+Q;TR9Ukm zt5|=^Q{pl%Xr9_+fN8@3AH7>et})lR&A86E*oYea45nqGr%uhxd$zjdFKhjDig+=W zXRzD_)Gv5mn3}10_C{+rt9He=ERhS=2;QBgXunLss(ry7e66D?S zRmk=e@wXn9ZP3%vkJG{Ukw>lG$Gm0gvr%X5I=IkbM5Dp7(=Q`nP!Q z!o2mzt6c&jAy{TKMcUAv_D8p}r){#ez^#`m?>-k%P*)O*3pSvs8Z% zG)s1ECFi_vPcT6q>Jbx<#gvc047oN1r2x zoigf_(i1h-K1JalU(tpb8;i0e+<_vL@(w+c+{az;L-Qe@{dzqXE;PbP4 znVjds=O<}IEz|?3s{+5mfF%cqqCaOj*lK?8yL@ckRYRW|+H4p%rdSTdkHt?JXwA2b6O|^UZ96}rlIO=p}wc0U}58)C5h#+A&|K7KzpmIppK7vt=qrdSp#SJ|nyqd0{cTzJw;C(7YoS*7{a^9NCMK&<{~MtH z_24Zv`k1OF{}_K$?wG5Z^1x@3XXv31D!PwbUZsWNm1nno7;h+Doek)lsVm{bh?`;4=PEFa(x7o;2a<8K4>flu_$C zb4qLHydIAZ(Q109He}Dx*!vh&&0iX?nD7ToEDNVPcBUDO#%<#y>5EzeAYYx-YOb(Lo|Eha>dWMAEh2NyR zt6sf&_3G8DS5>d7A{eDRrRC_qb!ldfcLm40M#XC`kKjFf(%mZFmR>F1vz^OSN|#0O z0%I-5crC|RsbZ{EF}f#Js2Ce!FuI+KRE!HX7j{@2?&fcs6_~ zZn>{%DE7K?5`%@910`uXAN25;9P@k%iIt(>HBVAyNDwEeSe+VqGCC}>2gJFSE1Q_! zUcggWA$6ZhLcSeeHP!xH_gsCxKd+|R>U7Vw76rnXIN`G|Stwx*zH)$Z$MT_o_JNatURY(w!?yds5vU2RJv$Q4%pwb=F)dUG@0R{?X)+{dKHB!+*&^^={GFf5?w zR6JjWomRM5=VGr#WR@rjhARFp6}0FRc&+n=hwJxd%p5TId2dW zbA`$#K-rw``8K6QpJ^cEx}i4X#!SP9-U{9>T;Y7QqmhAe(vBGwQ&3;!`i}cp#W|0M zucr8NeUIr7{Gx8X(zY#J?Yts)O6iu156}PG#lH_q>Y?*D@NW@eg8*z-i=`vMJ zDbYj9s(Jm747}=F7rq*;vk4wq)nWrYvOaBzO2-S(=ZhG=;a9SGuMt+>daukSl95qu zg7`<@Mn%^=Q~xyP^j_%Cg-qSX7|wF0=fS&u{yqQVcSg` zl7shlVa5Fcthhfg>z7RHzR2JP_e!KD`euVOaZYPO+nU+6H-)XBs-gPFp<(2G3; z(F%Rz{I!wmd^!9nHT?O5i?Yjqt+70RaA9`iuQl1uU+tEwy#9kL|=GM%H+ z9$Th~YWVX9$17zjRLewq^c3F?toKme$yB>?L{K=|=UtjFl-_VL65UE@8G|9 z2&JKK8(_ZTA(X%xH(-q20~CsD$zP z7`D^RSf%^jvzeH2J`>0P^ySQlHYRx3n2nxI@XBcL(3-F%kcd@d$|=PAZ<8QD4FdJt z=E{(_ae={6*kXha*^YV4esR%`dHF?+3uvYw=&i&T#&<#xUM~XXNofpWbR;#I9O=yl zwACNIK0qW%lkDH~w*-uK_VYK)C*%Pi@}>0qc(3ipxze{b$v7&3Rm=s$QU#*XY=Xzm?&Qs@>Qy2Y0>sVtleXn$?3zsxi9 z=bx)A9cfiFf3}Y(l{P^ij_!Y|&4O`qUbnwH0{^rE-?+SN>R#Ld83}(v6V6)Al2uOE^Ee+jUpn=D z!1DigOI=^+XUMn?b;tr%kIAlk+8q3?H-c%Ef{CqcJY2(ApaxpMDQs+90Y*1#aZ9i5xbO!@kx#*?x`pDyKiZB+Y5} zhi^(NM-AmOp~IGT6%W5z3Bi6<=5$`}yJ}KR_!eQj{ZbxV$z$!zX{Qu(cvzJZCa1WV zr&x*CYn5Vd1sP8OijVoo$=W@6^0N1!uhAQGv)xz0W{U!RB zBhIftPvRjfc!&&L$f559^eH^zQt4eNiRBdaM7 zJ$HP+-40zbA3B5j>)jY{e^ZD)o5ld>w?9k4`m8Kp;VqqFDsC&rn`vBj0tbGSnQ(6I()WW)6?e4Z*$~B+v zJl%qK_uORVCcEtBB#DhNN~R6|1sfHvCQJymB#^fZk1-(T<+vDXWv934K*1bP;4gjw z6a>5Lfw^%3-Awm9-nd@WKc}JS8I__NdXnpmj*+ruw_@a;vsj#l1%U8_x zqPfcKk^SKx@cMJiL7~Usx!-qT)o)@gc12hNUrT-B>bO)oO{%+isvo)yo)wx@?;zDO zC6!Id%Yal=uPIU`bjj7WIw#4E8M_0_okn&8>Wt-~HpAC*tH(99V=t}6Eb=En!xO|J z6=F+gTI!LOD>3pTYj{4V;6+eyneW2eKsWsHt$`JwV4gyOL!rQ2WrSoiai+p)$AoYT z8#9GV^QqDd)fU?VJ8bx#Y3jGn<{MexVHQ4NZePWuS>Z9ZX865>Cc)I<(Px#OGvo5P z5h@X)vz49+TBEY6Pi<-;8HL9T?75BZf9{>A&_15iJ`J>=;;RXdbNwdPgim3og8ppK zKRS-@+S(e)Q=Wp9IU2r`%#4uqkeRc>!!`1l;hQ_jQfHY8y=t$YP?LgC`j1`Sn+AZ2N`EgLYegSqlwR0Qh&}dE} z74smOmA+yf6F1h42;%q#`r27&oyBhleysQmlVwGk$vx2712DFC_-LRD8Gw*6|0NB z4b8#qih;jXU{*ont4L!P!l@e>=6Tkm z90rtwbT`?7&|Cjn*Z!_7|kF+^i@L;$< zG^?KlKSm9fV^@n>AeyOh);WSqo@gJIpR(ftKbBt@A z<854#?I>u0*Zx`NWz2q&_d;jQGQnQFY{xS4#ugUQ3f}sowUs;2UTT(Nrnaoq_rY0S ze7U_J6bVb+92aTp3y|NrdDRjtsDeJjjHT{u?_wvz=#t*KH#csMruWk*oUh8#ms9z| z`H7h29Pe$EZQu&>JSe7_Pn|=7s3|9if(V3SC5y0dPv=(hNbm2Q!n}#nWN`%XqI?qS zh(ajU`a{F9t^wOR;uWAv_brA!xe9&&!(dIPa!6OM0)6z6%2?z4a_8ZVePPvu@rCwf(};P1lIc-%n#SS;ubn<0NIH_KkDB4qB<@PF?uME*$z z_$SGpO7s@%twb8*-Y&tOi09_8z&(acc)z5}hW4Bk{1d_&?K-?Qgja$NYRk|)b~Y+C z|AXqBH-}$XP+>SCE&kvreuoq6J30-9_6AFFY4smnZ4GOxGhFtPqy&3P%7w=2h4T#6 zhG3piD0tOntiCDjHD>ITMt>M)#fg$8<|0$|vb3q;F)o^4O*#lI^c|D@ZA{Wlx43jA zx*6H!mDBwF{ds1J6Jbf%P1tE=!hWh9`s}&WbDA6cAP*x)opMa zTXl7=5xRg-S5ztlUYTlWeWk-_Wp%Dn7SQ9aU4MfVC)^Drt_$Z;TK^XO>tF__6O+#q^nEsjhrRdE zN~}s)q6(FugcwyAoe~lRpNU7L(=1{_a0awaBfKdG*G)5_n>HSYMuILL9LfWzXOHg` zlY_^40lUzR@5Da({*`~9k8eHy{sI2p$I*NL(v7|c&jWbAj^}rH{u@sT&-Hlj#d8Cm zyYajL&#&~nx#;J%9@lgdi0BkMZ_Lt8^vvu)e>pTaY# zy$|!`d0Kz6JY(uf3@+v~-SB|1kQ@r=VK!vF*D%Us_c-AB^JpK1NLlYUP^gr(qk%%# zsG+AQaCai4E$h>Um$E*=j|Fx%*a27B$F`?Qgu&2ZX74u`J1p!y_^g=W-9mWE`y%Vj zTc&ojY&#HsRJK11og0On4bTR`RHeLDJZ&gz0_>_3iH(LwE7sjU6wC_*K=pRfTC0Ej zkrvqx?$;J-<0N}zL*YgNSYPJg>0##RYOD8|k7V z^4aT~N&8bCgI}lc2ee|pxlo4_u1$$~lIUq4Zs?eEYm3c}8HMleGIY$pYv#|tB)!n_ zS<<_mELGQpmYpP!9h`J^X}-tM@de_SB!~B!UCniytAZ?!gjJ>4HN^d(A3b>^+81!y%L{0ob~`L5$Lf42}v971uqgm@$B1rsizgTY4I=F*hw_q68!ZBOHz=}|2>U4 z&8MF~=(5iF#dhi}>=@b`YV0q@9A|6jwXT1H9s%6fB@U~*&z-h+SRHeuw2tyP^QmTv zJeH^WLu2|yaJs1~v16fdR_VXM-wUN-bh z7ttJ*g+2MENA&E6?9E>K1!ONGg)elxueWXzMxlO3WtV={K<#)c>RKN-M@p`KTO!^<-BjKq)W^&+;QKeku!TCj z{oGADBcelXo6+7X99X>^L*pIHH5PcyPF7J{Zq6^WkMd&Xz29UP@%&>~o-eVs)@^Fa z^|BRW5LS2Y2%mYW38M#B&OVIKhWmUxeyAFcnV+R*jDY-zzpE?Nx0c5ztMOJIZ}v7K zeo0q??_(a19mEQLJ>qTKY*-`CsDUjAeGh-%nd>$}N3L7zNnMw+?g3Box}&)vC)|u8B*BRF7*Xh<_d^ZL@$fFbu{Ib2Alkb;A>k_P=7lbQq~>D zh+5|`GtuABo1``-84SzfFVMBw~6?Ff|+ zO6vxZ(8iorgziD;&dO*g%iWF8e&BOJE*74niA0Wi4gw*yFVQwUKT{>2IqoH?mxVJSaZ&Tn>X||{3O^QjK z>&V(ev&CttCPzl=D_$lIk$x+3EiZ5+w`}mzTbaYW_eJl~qMBSwg|2*UZH<3lsJ`1I zCTaNQ&v_nnqs$`l(N^lpd1kt8e(}$2T$B%(P4k%N3#KR(%Uvf!6-UEdxev)<_Gp+t z_kKCddOsw0^;CWEFZXXf+I`FFLw~xT+IGp|=kBlZHip^8JG~pjuV+z8T}LAB3#xHj zT9@&##7-S%kZKxk#s10Hv-GfOD*0O#&ek^D$})YPeW8M|(L-MX(z;j1|zzlZ?Sq`bBP9mUnvD{Aa@s;4HN53&AU&XrvsN4)L}u z7iN&kbJjFa$V(lJHRi2%x9$auBGZkzMJS1FonSu=a%CIA#4~-~^4iKXXg5sxXtLq&l z!TS4-xBnRsmensfgy7Zpz34d7ECerncZjzsoTRgD$`dV^Ri)j6KeulS7l3~*`0_DZ zlH!q+;<)>Z42dy5H;g^T&gbR1;sVSwymc-U!+!D`ak)u)2!N#*Xp`$IVWp#k%2dXyGDmThe34^)jp;-Uj>yfG&nNrI1D^mI=5&0+?*{7RXtL zb$^3SS6Lnd_w5OA3};RftQoL$UPhEZUvd68k-x}C>F#pMQ77)hUS(D=jGwL%DGQxs z;vc9i!n8@2c_dL8g+H{!r=r^-2TpahlFCAT}~Iz$7eNs9Ns)sqE+T7A89|qz1nwgdrDRb%<`n|Hkg523UK3N# zbicxYr5v!HZwGyySVzy^>%zJ0se28M6-~yyVbuH`yyhQnlW)tqwMoPY?Ni!2icF3h z`D}aW*wG`04;?B>aUA2{$9u`|SPtzB61QZzlTR}tUs|f!hy;;OeIR@fvpFtrmgPW( zo;@h_{_s6w6f2!&;^)4y@mO8U!wzRt6!N^2K!zM6nhxiir26)=+84Ktklx$>T3fg+ zns!2bTFsro(VE%Yeuzu5Tmt(^(?sh&bI`g+4Kvch=F&)Ow8qph?J9^VyGj-Dh!vbC zkxr?_UINk|@$v%wkmbtxZ*;>DDWg5T-PWGcp44t>&ut&kp4C3QeQ5iT_O$lY_T+YJ zdt!S+yRlv0PA8SjQrb`|&JAD%`H=HiIi-AUPAR4&tyGc$+i|o-?t!mJEGBblw)6jD z@O(NL9_*N?21f>_W`y(I7%XoOhDBJel+9R3)Yzc3NjFIQwe=poTS1XXwN~6!kSJC1 z>;H#(e(cLTm4PD+Cx~?2FRV-ce z{s+3eF?4wb%|X^Bq~nQSy_yy;?=u=mTajKlwMmec?q~a>8e)8W9=v}f?dDn@atwiX ziNfZ`!ww=LS^qkOW6&IAjXJRYaOE__ zVA&X3(x`={meQc;4;L?Gqogfm^d7f(Zp)=)((CXOmF=(JpQNNwP4n=8P%cWG}bazzqBR2c2MlG^|@d``pL>Xk^Zt6`Y#$ZhuD@c+iU|_ zc;^Fy*1{`&MTUh{1G_MB-I*9iJ)J^&y%zSL_2nt}ruDSTTFLUi_=J{WE*%>~A?*~= zw2G*#3}~fgYOKhi%@&MvhxzuNh1|tj?s01ngvvxIEhfy2Fq!74EgPXefm7>(&nD5o zVXr>u*`l=>Xl$~zb42RhSQShR9O0H{IA%11-N@ii)LQpfHy(D`nB$se(s#<3Ck;O6 zSZ|Aig5PF`7RvTrJgyZwM=>n8sBW=zJOG@ZU`(?IT%@^#p3sdwRDNBD8(LJC{w3Bq zbn=MANvr+o)oz!ins%R>U^GV2t zc4orrJaJ|s$$8?;M6#1+CWI0yH8?c6tYi(^n_s6px^@xK7tzxEq_Xlzj!gPlGMA<~ ztK)J_cit+`GZX_-r18A1bcpk2W$qywmf^f!%@sMIw`8`($d_&-q+IE{7`f5NuQhZ( z)p10cY?qUqXt*a-M`b@qq3K{ev`mvUUXpVe5<}PifuT7)8PZlw33iO4U)Be+Wy+ML()PCbAKtus|Iyt?%SUfps+%eOgih~v*SgX)`D{>+cz&+i5;cPxLn4KN@dWBC)k zb?wBqa|-8AM0=luoa5W+Y4P0Ewuz&*)Qo1MrY;=u(3*C-0J~74wGlmqAciVQue2Ty z*C4W#4~fUBr2*|SCx(WEcxVj`Bc#1;G;cs{pXLrWwP|UR&k)dzjWj8rY>Uz!IUD)J z86R2yt!REUM*sZ;isJd&9#5sVOq{P~4Yy9F6E2n3Y9K$4$IHv0lZ;YD+vymYkp8J5MJks z){(3gN-Luw_Yv*5)4+h;-*{sJW;Y|2!Aey}-i3A_={fo76xtT1$?GvO3RfA2`90(s z)w4I8pgXP|KzA&R(;a*t`G28X=fvoa!F58c?%+B>!;4i_f5uJp$q_!I*EolB#OwsO zslll&@yJFx~me2{{gN{^f)m zGo1BmjuHEqJl_YhkN1W`#6{IUeuC<95c~K+F0aLvT753Jc)ER!WD&WkJe2L@h>YCB zWrTJVnVJ$D)0)hV%W<-SyZPxzd%)__t%FL0tn*L78j{uyy)GVJ)0f2Bd-G2MNiAtf zOusqnB+$Rp&^s+2PL<#&z1n_*`u>>FV+_4oZS6b>B+;8888o_`&jV;jr5d~^(-T?9 zC8`H52n~HbR!^kG#K-ChYmA;a`WoB*^Y=8)U&QspIs4^vBO*2cwfCrGo1NWi8-6)v z1b%eDHcb8qs)VNfLh}KGNazoWglgbz5-$afx14;uHPPgJc;du~2Qc7b1Si`+yW=^o z)+K49x~-pR_&sp{FZa-Y*Vr(0A4-gM&HJ|4k%N3P8Ck>UYqTZr6?u&^DFBS|YhE5! z^v=r~iZ;aO6m5kucKmbkrPN5uOK3;ZX_WoZ+4a-LGkn zC+GvU4t3HFemkLDm)f>N^8tgk$z~01J`bR6V=8VLr%h8EQ%{2PuNs_OA87j@E+4d- z9&2Y!;`p?7Rw0FGYzwWOC7&Qf^>RUcy$q6<*3KFhhxxtAm+eX`fyI&%XR*}4risQT z#Kjg@;Uqd1(E&6jh_<&A#sP8sG->#G_$2&1nST2L>9qRoAJ9@nL8MRG7ZV?=-*(67 zwMPLl8R`VR5cM!E&%V$!|$JpZ5e|8_-sv@pY7!G#0@5XV9{_T+8N| za=leKIrlxY@i=SH)FqSVx2**1U~O(j+lw0L+XzxCwS#Dg8&1H;q_J&!^b@jH7Gtnp z^$T&jxC>NG?w~ z@MvwADn&E?CoRGxe%d0eIb$65_bOk^H$xvpdk8{`k-8#1MA8%M;r9j4E$ZRd^|}P#eRJS^ z>GPPJ9C0~)K7}!c3bj- zs@D{GD)ZWtOa`_l9Y*33 zxzE`I&X>gb@N~vbTk<(DIP|Rs`&j-Rm1<^BT(?!qkCC`9dZK+m9!BCin^xBjkAZzx z1DnBNqq^L%E{VgEO=>wwFO{Os8%A_PBmA4mubKAK?~}ShYkQ)-SRc=2@E+_|4Mm4# z*g<=W1sd1`9JY8+*l8LXTIG_S(4)9=$dj7-are(`G`;zuF~~dEX7gsrZkn`X8gzv9jh#Lz(;xW_%|Isv@829HS|q6Z8`1Ieq9a4ZV1$G4fbfiq=x-P4y&TGHtEzYIiK}BQ~>1j zYS=S!Sk==!g!Z1)art7{G1?M(x2HF>CETz-Dw}5KT`i$oyKV!e z*3^E-wC0wOh>=_b*6dsY3>Aa{5)cVZbY6$hs}UMY*+PUaKxiyw^AUO}LSrer1fjDD zZwzI#K-nyXvL&EwOjnACGq|d*`_U#|$WQ8u&|r3YfWb`|VkmPV^jw6-Qg#kP&qQb} zWv3%_5<+7sb0V~m@WxPf3Me~8p)9Y|vmHw_sV9 z@?(maM>`qpxkx4CnsA#Oc{Y)L&XgeE>R5b;Z-a6w6EwNJ!@in!vawC%H#bo4YEn|j z{cEyB`hau<=>{>f&X6zP!B*qmiPM<0`5ot)JJL7P`Arlnw?29^I9`Ppzx+lXOowo? zhah%hCrBqsT&wGZteBGp$I6yu5&Ilsxc>{d1UV694;HiYfHKZDqOC`2&gx9_XrV05 zeKM4YJyd>HKx;A)*d(V|x(oGzeN=p3!dpk#%HLYP#I0iNP(L)fAnpl`>BiZf_D?yN zKSvDRS+FgfVdH0AHhhS1mW!KTd^>Od5V5YD50DFX8`ly{tvjc68_Lt0B!c6voVRhp zN^g?cLm>io8zf6&(1bh9DHQNbIM!S2^)tJGcDx&>p1caKyvn&^m2BcG;0Ean!iKZ^ zoqyrj5`SP~J$M)`mD%|xlxe;1J)DX78jFTooPUhrU!t>a0RAP#@z3gfMByLwg`cQQ zto4=z-=wz;jGMN0+ENo*U+T0m6W}{Il6ML zkKyzgu!z7x>@K4x$0|@t)=|uA8Wv$sR(FP8qSH9&?Mm$3>Mq5u=rI^M^D{3lqnufd zk~8g!UemC%@K^KYKPWC&t7M)aJIuw7H?Y&1FEkGPrbQ zC~dA1yohRrA6w3pbqRQ(TE8>`p>+p3*I(#NWWE*lpa9ENw$y%VNvHGqs#pQ-&XFk* zN)soUvkob1juG4N7ve%%in?3qM@?xmoIiqcL2AK?uE3&bkRi^t0b0PYxE3(fxm#%g z&=oNnL?|5&I+}pFd3u^ggOHx!{+l8!2eGC>4?Us_2j9fmd~y2Y14Vzl56Rw6sdC`i zq|qN2Vsw~6lB06#%>lXP%Zc#o0Jm&m!(yx^q|uxuS@>uN(j`*jJ;Ygp)neqMk8~Yi z(hzUbJ(fe3b%v;wSMpq7Huq{ur$cGh_D_@^2fc#h)MlJk6hk51sB*IU)aFgT3o?B& zZ8Bw)!=?R9TnPzX8PR|C+r2_nwMPHl&h_8lH7zjFc@yd)TEAxQ&xjeC(Kn*KXQaR6 zp3vMBw&^N-&EcfNXH7T8Myy&TQ~_#NoWv$gKUk6E}`?j z;&=F_IQve>J=NKDLhd%_5uW>D>_Zhad8eU`$IjZPJAXPM^$_QGJoR@-ov2Bj!8OD_ z@F-ssI+TZggHXFBRMsY6B2?6b4(G7{=iPBflpmQq>|<|@CM*kK=J_A^ymxHH>4XmS zaS>gd&11ARGQzo4E`g>-a-46SP^w(#8@yDnqg12NnqPx7X0+MJ+Tc55S5a$L?Z?01 zq;P8c{^dy+`BIF$V)7?Qw;$_iJCo(z@a4@fb*3<*Vgs15XWpxk&qVb6Yv3UsASu%L zZCc=?vj(TtJ#Ye*RwZT)r&Y-pv(?-W8ta7%%3aV!5q=1zNlFgYF`g*ZoJw}Ie4)Ja zlzP`S?uHhFJ&IAjLB$`wD8qt#*myV}E7F_6(SNM^jflNk*-ZU;h032ruo>tySfk@I z&Y3H4qi#KBagY)-Ju+WroWPf&0r)a~5WbWS%9rywU(UxF(F5~=tl%@fbvRv1wxOup z@1fk2y;dja!)fdBmbuaK7_5X;i4|C26M?fL+1a{MTh=ILC-~&TLx9K}03urpfiVf~ zg&z$p+5AnEGHI`T;>JzPo&?DtUoA89milwV(j;gb%FC9OsNhKEu&HSeZXe|YP5V?x8$6(7$UO>VRogf9UjZ_QLw>13W;&Y`$bTu2^V^#0KL%t1 zhx}ND6rKN6AU{+fr?q`pza5Z=x+r&=jX1+XbUK{xD3EU}kdxb{v@PF%$NsJLZvuV~ zhi_2fi=1yL@UJWI*==vsZvf zh1XffQ<$aSt6?t8K*-#AOu@2Wdb0i@V0jo=M!$*M6(B2Xaht0wtr>+O>{3mX9JylY zYP9F_+*Q87Sr&d8L2BV)^j>69P3yTw&B5!uljra^siuAz@Gb=2T;NTVo|4vJljL!pjNdF(0RN3>c{gcdjqx#4{tilQ-PEAofzxzXOVA#7XG!aGkrU&%+hII*8*pe zjN{K;lMyynI=y}(^8Nx?uGus}p^?Utr*ax;mg*F5P5BV%)cVnY`v-?Bh?GUhM=y3p zHnZCmnrZEB|Na~vPwgq$F!!KIA{I5;lc7=u=JIXTa(}AlFxTbDOi{L`rO5u4H zv}M&>5MPVR)@tv{Mm9?dVv^V=o;R^I{G zb2w!kDm|j}0FP%l>s!_e?@4bQx(zpSBnC$VcDyXlm~V)cw?r;)yP)sNbHAQmJy||o zLzd?+6im%(E)IAXf+K?3iS&O;k6_D1@uqb=vvp9ko%fS$LB6=2Mmzc9-; zvdHV^J(jNUSj!|eH>Yy~&rJ~PkFr@iZ+D@Ljl~Y6PvCShtQN^yMb*2k$Z6+kP66yM z#kqj(JT7a?90iuV%Vo~EoWnS524FL1r31DFu-B-Xmt;iNyd)z@kP)hT{vUUskln@# z4CpNl%ADw8*imWxq&2d;B6_#fTT(_k^=t4}K1b_u4=Y%Y6FAL*gaGFLwzJVSo>lxN zT{f0&Cyad>jJ>eSnB)AW9-Ng`jk}Y=kV5%vExK!BdEY3BPEpY}nW``2ECjjfr7i{@L-LBBh{eScd(w%Ly+vu#M z6EQv^V@#8=Meo4WVk--0Pb|h=6Lix=?I4t`Qt(7dbGL>wtlC_;VvuyV#pJ(qz|y#G zq}wcR7zD#&1;bT1bxc=Lj9V_~j*BY?fxa}3&N&)7T@^dRqtK^B$`GxQ;&N6{D)|P% zSt8@Kjdju}x~jwloHg9XEW$;h<2_+rn0sGLPV3Qi7O4@TNfg<7gy0Aj zLZ)#za#U&LISL)`gT@+~lf<{|3pmZG<}F-@ar{r1TV(bF&=9r} zR`EN`ef+?0S}P9DzYlj+2G{hqBR9o)DJrK!pCf< z3#V~n4qYtWtc<1&Si^V?)D>;r=(BVtGXbaBxpMApI7`~#^%t>lJ(%H2y+do!9H6I6LB=R^lv(`vY=0Rn5gD3F70>?U=!n zPwN~n1Yf;Z5Fhc`umZXk+*qTQ>WB!ZijFf6r!b z8FGxjPxwQ^pB$-82{`@j?xsAPiB<1#1)sd%Ed3dE`+_6ftc#v`5nQ|7Cf-bQTIi8) z^|A%yvMOl=mgH6uIQN z%9D*PPV`3W*`&sSQNJ?!w>hnZ3CQHhfNGFhP z;Bz}VoV5pAE+1=1w5CLQgmlNSNAzZX9y#ka{(zHLqIBS-3-qCPG|{R=B)>ilEv|}4 zOIeuJrO1P!@TV3>?!67HAXAdHBNz;_n9}bwhES#T5B{%B6V4we#D40EoPwfg_ z-Lo)ji-OBkxUXdc=fOw?Q^SCm@|`smjVdN9Fj;}=d|-Mp4wF_tKMPzD{oM5Wi*$zO z;RO3j(0O&x9rV4Ufo^b5oBOINeF2_^W>?+KI%tfD#ImuYrRtmqH1f8VQ`)%TUL}lX z7^&`8`_9GOwI5y&2{yK1Vb`|3u?*?`yc5=~cGH{pDVwgz1PD9jl6? z>?)Nq@`|SxZgu20Cy3W6x#9)~u0zgIo>z0cT?RRnv`{&;(88=M6e`ZrJMV=DRv^OF4gdbY|;xjtr08o+_=~?V`8b5He&W7 zLy>^!SsAc3R9j)1lS*-lQVL7q0Y#Ta(+zB6l=E~sN;)0VZQ!z-CFMvZN{&N$O_H~% zHb>VjQQ1#Y(nn-pD`f^=8rce{d;_!CjPwZU44NapehL$>!TPhdj{D;3_$HOBbe@L1 z>Tz}RQMDc-bu4R%PEKtg{7Et_Zuoa}DBP7}Y3IDWLh`*5PLeCf$tP;i>IvsLMvdu8 z%wC>~);G$+W1%l1ZT>5@+&}X+Pvw?z!KUE(e3HDy{jV4a{wS_=WDk9a{_W|Mjj)sc z`s#alr*n~RZ)Ia%q>}TS;pF@6lAHgoP#r1rTi)x6{0n4hCRp-qBUqDTa`USSEX@|Z z%4C>yRaSG*USCikUc_y$jS3c4fSwyzEUX^Y(c7$}Mw2Fri=L6t;l5~&v(xO;ySF79(s@%R! z!M(-3FNVuE4Z!6aIcHrXiO+N1C~3a|wk7visf2G(wb7Bd=Q=>hc1GsbWN|UE&evH@NQ4U2~?KH+n(phLMA4DH19#HspfRBOX@OCAvT@G^?zOldz z|NJL|%_!~TVRQ?xL1^Lc-(VbL(`oV6G=qT?ZRI7#@IN12LMUJ+scTSRc}_PrnB~QrMCuwe_erZ z3JYwfGNv(i7=^z;4x;y&8B+Ign@h%3KM1a8R9wawT#ugw*CT`As#S3%0++0ni7tN( zEvjcKSvVP1*-phOONK3#{M6T>x<0~tLkwP1>TYhG$#}Wf$^bJo zS1EXtxs4XVn+m+Cz`KOwojV}jvOy@Fu3)6QE2k>;H+2x$3shJ;i)fLv2Z23Jg%xp= zhb(au2Z0@@z&5TNtw4?*1Ts&7^smfTAhQR7%upa*D{TrSarRUxWe|9?0*_lO8T@H&r8X>;q^3Vr2WuHmx=q75}6SKpI3zJQ9@{}`XX-8Alv)jn0-iqy-nXVXJF>D z38@lB`+~jnbDRy|`jg4NJM?ys9P%;fpj-)ly}M)YPUtjCs&^B2rR4KhPkO%&B^+PxKC(ODH7I#~ z5PpPXk$nOlBz=g_{{p;Bc1%4j%Cw?stH@hr?Z{!krU73@;F) zGz)NU1@2%oONHydWCj9BAl3-T5CNq|3v!%vYOl5Ul*?eZ_YvpUp<%e? zih4*kirUbnuFG8Jk_^lln5AKe7Zw;W=amGzPHktlh1si$gDqM03CN|R$B4g2de$@~ zsFXGIV`Y%hScCKcpXY>rcy}@GmV#|@^l81B)}?;K^DusU@%sS3H}MmZ<^?>h&*;tl zc;1CyG8z+=F9ho0{mSd%2=aWphve#rn(H0#!z8#M;0`Kq2LbmN4)?PPcXdDQOE~~} z9nRq~*SVlgfo})=BOHF83O|Fx?^RZZn%i5{R+Q|>lUq^VlxbJovic9NY(IRclhgVo zaDJxXYy!^39OuU>PJ6%W*p^8j0p|iPV>+_zOAwHWfax-^bzL7rWqZ3f#MZ zE8=i(s&Gg9PUmoc0~~zVIIrFWTmgrBNrh|cvvauD0QV;a?q$H)INb9p+~5>%+9O;rq4tIwNcX!`52{&1z4J7k6uoCc?=j7$S3-B8_d>O}8jX3P4;c?{k zavhicKj3CClK!RjSL53h{G{KH8?mD;VFFr$Raz?f;5l=J(jGF{Jf%Hsz&y=*_o2P{ z_6%nk!b&}6seI%t-y@R}=MQyWs6YXm&6neXXkaxIZRcRi8;5pd%^LOGU4p;!y4N&B z^u(^vkiI#b-itvmcGGZrX8_90%M#HOX#dAAkk0V>D_nSSi*tZ)tb(ry__8^^0+pA$j?3*~GT?F*xQT!>aky+1?)~E>$Ler95wM~U z_3fwehrCj5bY#n32EO(09cK(TTkfo+ob!M&QNfr4jICWHJw_Gd)5r7S&oT^cp6d+g ziGNeuhmN=yVWczi{-`&P!SCPrIq^FOKM#I0@w*bgyYM4DvldTUi`|On2>d?5kMs)@ zk8@gR?X^dtgjRFOM^2`Zw98Q?#>{=L%+MrrG3Rf9J@BhilN|{88aLvucL#SD+9~D$ zV(4^sbAU8vySET2%(!Q9zmnoxgrNQN6mJ~*tavZVKdWmG{$AeIf_Zbn{ta&S-4)6_ zPFiUfxcWz4`(J~eW`&+F0bRm*_J1nR*zx~U>pRo=snQR3FC?9Er*xOJ1Fb@EWTN+< z+l=!Mlu}~<-hy`&tlNP#lVjbgV*Ph7c4+W5?}ivIy{4pZKzi)G;WC*5F1^Cr(9tlJ z-(1I}0*Pi3%+iZWOG#nt6+W2j*0>Kt?we*kgM6F9Pvh@5;iowVp5h$%Lodk_apCtU zLl)=4ACTXpN`6luMPryG=V6uJyL$U%Y791D~N& zf;6rM&WKL&1LyBK&T19soZb_?V#va&L=H`ys@s48rvY*z8$VGq~&EYOk;r90|k1BLRn53=Wr282Yk&ByKrF>!EwGcZHVskQ|s586Y`=k40$4+oTgnr`$z)1bT&Z ziU~S_bjntQrQ@CK5v?sU58;dPE5Pq&{747UoyK&N^)Rm?`1A3iH|c!{-mkxv#s>{nuOELwA#Q+cJlb7egLm>OnR%qU+~`ZpCHnP9mEFVd zjkF1_TF{8uE!k!Qjg+s!X9Ucz=%)zQAjA5ZV++A5cUI#L(Ow5)g&r5}iNGF-nMeHP z@I4W+QX5Fb7js(hg&Xbz$$=EyR1HrE6AR=jH&*Woz1~ANRu2b`2YZHjokhDsE!}hn zAkk|0FEG-L)r2u}Uo~M^(?jK>x0kx*`>Kg%1IkHtLOwKfx2s-c!3DhuxUYJccXueW zCm}!0GX!r#dKyKB85O#HTE2-|zJr=V4D5Q31u$E?MZgSx*Q)@SzjotpQ-coo1J`cE z?RBI3Lm%|_hZf;B**4rxeRCHJUWl89U7+IZUIBl5a0~2;N>lL1E~~f}V@C4ErIm4i zcy|^P?%99zKXbTmLS&nMCC?naICBr>*;qQrZJ1bo09fR7gz46BrSqo6T5fl z4lpL(=Ci43R#Z}&n-TLFu-)WK!d_W9pKcy=17gk{iJ5!kj~QN2aGe(^w&$To!%jkB z;q=1Ey0D$mJNZ!%ROH=TDZ^0s&Pw;Ouo_cazBtEF*!m^I{Ag`eedl}F#qctta~YT; zp;i0s8tJX{dY55^81Wcknp;biFTuW}!-ln$+RF2xQ!2KKxNUoPXi@h$O8-P&Rz-?E zBHGVE-0bct7@Y<%IvtAsDG{U7k(+VwE$;$!9F1bnCQw^Q+!#NWno zm{R~lR>&xCW|3@%K#x?wx+x#6+_yMNxo?s8W{_+0r(T?sQ5gO*7k=6~zO^exOrO0X zd&YK~0{*%cz+}pT(m~ZX!q0?tC&zLb{Iqu#>xXza5U0toKPOCQohavbkjF$A6 z<$I*pwh3#m$kDv9avLAxpuIi;{qpWo*}tPQO<*K1t^KgHyV7Ec4d%M{akz2Rv zu5B}ZNi0cx4L%sxd#uo9pQE)V;(5GVQ106{1fT1%*$t%g5JvZH8-m^4dBBSkd0fCIr9j75KBI*UX>0dK3BcOKMfnAk=DY_$%KfZ$cS%g+A)m4H~xisv!HS)7Kq!{L%+`l@8S{TdG2t#}>?_o6S_9r}T=EKI~(TR0Ii zNw@o%eYH#BjUk%wgf6n_Tr3kmIF_MiT@KVUjgv{&BW>lbkfS>jHq4)i=G`Ci^)D8U!6nd*>HREtNq7|SH*KZAnOk*YKKAqIBteAdL*+=^XUHl>@|}aO zpNm;zNj6%)*+V;b^{f_f)H1x4IFBQbRft;!F$3-2!So0xzg7oJ16C%a0YhfG>*pOT z1#cO6t6@oav*E3nC35`cl1!)3w-fi3p1Z2povABvQ(J>KJLg#r=%+ol=FKM5J!5+O zjc+H1QQw2beUDr0NygG3VrIBCcl7rg>=}3l`-eb>ksnnWp3r2?XafO~ zGvL5q6Q@O%b&|3^kL@K>nupZcOzI#XZR>e;kH;R;`jK&c({hw6tfj zlc;ts{$e$jZfB-9(eWF`Ji5RTiN02`4W3ONm&fP%cc{IajgsenShJbOMpM}wKVq*F zrC9GCzLymaZRNPO^1r1K+%mjVq*J5h+~4aQsjHn^x=8?MCP150_y;@;D@lPYt1jiu5jST`yVE`3vEzhF1MdU36MsYm&wz;xb zF$eA>{`@EXHUAE+P_XT2KuhVEmL9xVMcbjLDJ)WRf&N2%4zVyE;@O< z?LWky_8;P1{~=!d5Amh{A-(|d!OhH$4I>4*(QJ%v)a02LR3rqG;O=V}XKXT$JG0p+ zO_-Tbeugw2f2T;N%)B7)f{Kq0`!5;G-x7is=x^RMX6D~}4u`%CKh*eYry*%?m^FTO zxHc!DC+SF%G*XGHJRxqlf=igTGUsmgR?pE;Lb*;#M?PfXr*cYyLSmwA=8E|V6}w#1 z$}JRjM4GkMVnx_Agxz0mJ`z1INwiJ$HqEIKE5#I`nW? zKmI<@W$@Uz)!uR(HhFMaw=6X}mz?%ySlA=6$30o<5ABA|_2VQGt3+5|>dnLm!j%L2 z!jF5OYj-*hq6H4&Z#jEx_B7=5269Zr^R?s8Bd@tU$65UE#a$Mx_uAmYzAN+`&-tuw z6V`ztvA{hAxpw`?*aWQ8Fs5@k>ACs-jntd>hj#V}b{+08f1;1HSSEWoJc2>)%Z&l! zOA~;P9VZ=^$t{vBuIaKFg^YmmC798G`L)-WpKQ;^+oa>h{1m&0w?e$7VmIWj&{*7_ zUG6dlsPE0>S~7x%uozz=?fQ8y`i@{(m@F0sOT~bnY_(8-NH$9*Vv>;mYvB}@fWJ0S zxe75l=vv%#9b6Kou?Gw0hZ8n3ZvV3)2EH5Mhp(eiWALIdb96P?J?JBYbHZ%9V5f9$ z9;(BeC*0V;+c?tMH|c8KL6=VFH%PkLna8%@n(fm0E2j~@H18U>xf%ERX7qtpuy zc+Tq^CM7B14Bz7sF5)?^&mtutJOS{HL;6E@giCnl_8}*y;368?xy(fxf5=*^3-_|~ z8`UeP37*=umD6f!C{LEJtJNJTo^7qYuy$0*L->7$U((u9B^ToN5PqNGmtCUsuYPdm zq5j)OxmK^XKA>L}=}Yudq%X0KtnU;I^$o|+n>c~@!GxUD)KU6w!y)U8hir4g1)#cFc?*%&&QqTh_B1sD%5Q} zy8f2V=5b0K?oc9|0C~fztP>oi&G}xJ6Ig=&GSTOnWG=_dDB*NrzO{S=AF*J42I25q zsgVC7whZGTZ(<(4VND@zCA~xcQ7%DNNmA@OWGqhs4(tyCei2rfS;gZD;#O|J>v
=zQ0B^B&>Z@q+LqLe3MOJH14BG7Yh=@z&O%^QUQI&s1V{()M4O<*sd0a}G4r zy7#~i(M!4WN6)2ip`&@(#*S-KkF`9Dyncapf=L7#l5htD8^yL~OJ&&Onb1-;-{mmu z86n`SNMDkSP#4CjW%H*gp=TmgC(R7@jK0M=v%PKw z$I1b4_)O-M2$p9C!P0qraZWMhO}<(FNa%|Hfai`A@Q9q6&w*!x*S%aWQPF?EGWP^5 za+zKR7R&-EScd)wERzPoazC(Gz3(ZUIn;9^ceR{J>FY!P`_Uw{FRTmdd^>Lw?85Zs z+bgHZxnbHj%wUg&H-kyQjyZX+Q1p7N2!ZK`r#RE!4|laX@v z@idH3SRk#Ad;%xiarzW&YV)Yk`2-OPz0mt2PqWxzYG!tL5P%oNnF;;6VBOohLMysr z`DcOcN8GajCZ}I78Su>PC+?A_fz4Wmksne2oQ8|JedDBOF;7HywkM-5?6_-OhN{y* zS^6TOf6#>XAGav5PiR7q9H$(YdHr``tPPCAaPOob27HO5vM~~1Hu47xg_iNO55|Sw z$kPhqeZEWun%OG=eHE{-p`&VeKG_^YqY}1?hZXR!zwxk$7MaIAS%~8W;OAW6d8$|T zCbD4!-5+|OuRrwm@k@W)75aBr=A;dhm<>sEHjk3@fLPu)6`bRznh9?3zc*);Bu(gPYOPGvgpT8!wW+mY;kAOZ{S-dS?dFxF@9XBtzW#M9me`U8Uy^S`tlkZU^T=Xow zeu*7>;L&$qe2X~e`s;39xCAgXzMi|h@|v^f+_vzx>uU_OT56Zp-%_Sz-a-+YZY`eX1u@dIPcPJQnMcG1NTJLmYiAE_5ZbaMwD10^wa_B42ukv-n`t)mg_uE)SChc8}z|ij#oEI z##_Yk-rIva)_5A)$FK9ORbZD60DDW%YSc#=tWGMEth;3Gx2PvwT8?rYNz{4nQ83Kn z7%WO|Sr~Cpue#XFR**NiSHW_-rUV!Cbbt4C=#D;FcNIc+&4%u}viTBNxM_irQW`8_ ze?uDj7ng&zX2T=Og7Q=5IE^jjNaq&v(>26M!JnqeJaHoi;oI|Dxle%bhuesNzoZ|a;Gm$9iA zPn|vOGI8$I67R(`FPu5;GA5tp@wk;lHw_JVW!t1V~@6n5Ix|N<~C2sMOg-fnq%rzm`nAZ@} z-5K&(LSnMPZ1wc=x+l4CclRl!KF&)`9?95y8aN#4#e9J+-xNqDn}XkZK=&)bW?D&e z!EDs$KM8ggu-P+3)6*fG9VxfLgB-KSB|M}1M+G-LvA|K@7jWGFcLMHx3hu_kH7agV z!QGDe!qh;Km=gF>!S@Bn*SJ!q^sjv;SU*wwD5cIANadE03zokj(E5`x9adgA^(k{{ zDz}sVzr8PkkD|!_ubvr_&OtH>0R|Y7&H)UNz=X?yKqe;{2oOj>@JxUpQ6Lcl21PR* zVh~y5jiQ3?uIsr3SX^1fgcTL99}|(4<)zQ^eAshTW7=Db;0yhifU7@Jyp_Mz;d|v1I*wlO$UpyaBY0YWf zFXnX4dDyMw^o*L*(>y1On$y@{nbY+DkdqWcGM#fiujaH`&1n_SiS{}x+7o|eUebTa zD?!bxM9r&6&1;^T7dmZT?w_2$Xi52K@SO96o65?z%~M)6+b&dI=bTAueiPOFveo<~ zHNPi+mS4>_Z{28<<5q8u%f9`W^K_G93BzFtBVh?sYe&&8Om6eAiwZW+Y!zYibXfZq zmkgB?0Mo&K4Wu|@e;&sqytQ1?NA3$)CzCJgSWRbo9c&r2>iD1;E7^P| zg11w5>3N(Ua}SE`C1;P4+BmWmG$$jwKx3?&3&iKchSB`U?D`44!@MRDvj-Y;b^$*v zs)cO^Kb>%21#!^`i+XQ!qdM9Q!H7M(HeRNdsgK=q?oZ*=rz*XXzbn}bf5i(w=WK#K zChQa3icmj!&UuQ%!eYM}zhe|pNQ#aG^gDN?O5sb6OLVDKDd`XSq_0)eA0FSD`aL&k zcOM^#McF?_-|BdSdb$Al1M9(&VH?Ej*;YTFUaza^^nRK-5^o=H+C4dMe*|qNACw9H z=J@5Dzn;-?;N&s)Yy8x(?ie#s>{~n)%`MJ3D>z3Hv0KJh@)Q_F$k-Kym^E7Zm&w75|Up*Lm=PTj+iY->%aes;g@i-Z%ay-Z|BcoT|cmhFi($4+`Ic!uKei zmp=9(AAYHq6r&?zSGDqs{QJ1Cm&=jA#x#JBiS)7e@-zzdZYrInaS8?m9j)Hrz51rDpV>#jTY2< zKeYQ6XQi7-W7Jk~HCllmcH&bju%Z>{_=waqdmPGB3Tj&%3r_FgvrBz!GUt> zI30`8t}?e}(Pe;%szf6>9%0>r)%#&ytR9(!Rj*PT!m*T=FukQ)R?1z%$rOAgDCp@8 z9p0kdDVPFksWuK&F{w;aT4P>mh3qytKE0;NSGSkl<{Dn;e#o8oy@=gK;g#P##k`2dVlur^&8R{4eO8G+n^ z8WqCF&mo8lt;8v4-g2>X`et+36Z|XFvYLR_QOsT+ym#B+u`<6(DLP~W-SyYDKf|{v ze6(}UX>IoOpcmt#%16$>wxMqWAIv9*3-`TuG|>o#`sj=0@VHM7%Gt^nmUO+3r0d#n zV)+%4e%ka)k_uQEYt>g{hHt zFsw(f+Ai|-B&|tz^jbVEkuzW!^zt?ElkJ#BFeAQfRc*&2yt~U$ZO0_o4u8|#sIe2U z{z(=j2NvXOm+#DkW>9z+p;{0NYV1rtztzWP^7ct;9`W-%6#e<~?J^>5br2ejR7s|EId7BMqou=+f;_HrAc5ACY~i z3ekx&>P=Oc~3rv6<_3w_l3x4+?+S`*dci&62^;wmo{ zPc8P$?#P-c_R&*|fBNfk)Z)8ZM3WYyx)!IhR&^S+Q8X>*J=rO|E8V2_*gx@l7S8LL zNv(S)`G_hUYv|{kkt*z%igzvQV+4nJ>e>;Ehcu|c;jp>$5$nPzGOThkMp>R3NN0jz ze#yT=mibyd*<*^YVZF?-bg{M137NF_7304~-+J7NBgFbuhCMmeC}dLK_AX|nidApT z)ayVK$cn zW9ZYv7Li7j@j@XqfRm=%j29eU%xsQHBZev16|lyOr;Hemc=6_OJY~!1qwa6LJQIIK@_j>q>*Ad6x zw|4c8u1r$B^HtsxdU~@YP*g@_^d>kH@s%w@efUfCN=q}YuCc>;zZi-BvmW#R2z=k$ zDobA#Hw&^5Zh{Z)BA#nkb;dS?r=REE_4NVgX7!zSca%#m%4Kow47m%qVy4bV`=EAA z3z4>lsv6KWlKrsY%bKhuH^~9;YfYUG^-{4qsaU5Pw1j08fR!yP^E?_~(by>vbG>}n z5!$=%z%ys^)I1tj<;~2=7^P0oxL=*5Ij5N?C3-mFBdb1J>Np7Q%?&KOoM9Q#kd`J+>~tw&wEf8cVo}=ZsaDQW}I=ZQB&9Q z)JZ(`y)A!7>bwx!Ru;Vj^5sDvRPrDB;4DG9t)TYaR|lLgwR=AwQ5!0U%VF|7J*<{v2k)c1#=gdLqxG74=UA0X1xD*m z_0C}`YzN1qcU|?)0WE(4=YgS~cTs=y;n=9IBy^2cQYf;9wakSCR#gJeifZTD2jw#8 zh}K({Qps>DqQSfJ#i$AQ$+rQfg#|69IO9UV$b!ztbGdvA+78_m_!28Pqh(KH-#P3f zzTNoLS=Hp&{seANc!`CENgi`3L*{Fo*jm6mEI@j>`e{}A!O~6|?Ivc(|G2d2Z$3BN>tR4m9E0=z?%Rv)&D9C+q+gX{g zjN=*Q+c}g@RFKT2pgkfmTwdgX3B?>MKwjX1;M`v2{B2sDY<51(E!BDFby)LBfaC-n zh_VbZrSY=FNo$UM7~3eTzSn^Y?*4ISlUMeuHaQ7L2eiXSif3m48QT6i;XlyF+{f|B`#rAS2Y#Ur1D^hq*jtFvv|>hg3?i$DS1POTs<*m#;Bn~#(^ZuELw=206b;<#d9w2A?YoF(nH?H;~4IH z%UUu6bs*&~ss~i3{q?u{)alGd+jgqUGtSegok~5N<5LgYo*sRJic=B{QFiOY-kJM|PcXmCG_l^iroCS3;)Re;O zq6KwvEnl-B`%C*#P!|J6|EwkkHV=hnhFTwVy`--?85Y%A4-)`4U!WeIYHF>AG|E

%|-=4bQKwYq*E_lxDw8Nip+?D2^8IoCv zlf%2otPja@XAkX3zb@L7x-P7;XIZR&kC2moh7f&hz0=+>&-l(ZeZmj8$7;{E^o;Kg z@A}@gitWI=TdR0G?z6(ZN%-RM_T9J7iB6d%NLutfR5!*qV<$A{MQ0LgCp+ZmfFj!O z4qr@Ifj{<55`^}=D-haijNRwhp<2SaKyvIq$Np1+g~5+CO1{H11TgG8wFCp!Ig7q& zrCqAhS)0Unsp31AVC-i-@4UWovV-LdR@+E1U%#uOj>)wD)a^dkqBpZR{f_g_FYrCm z2Wgs>CF7Lc)`EApb&I;&nqg0K060Box|d