From e36b851783c72a4ff6a284dce5d0ec4fd339b002 Mon Sep 17 00:00:00 2001 From: khristolyubov Date: Mon, 19 Aug 2024 22:44:04 +0700 Subject: [PATCH] ready to alpha MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit подготовка к альфа-тестированию --- boards.txt | 23 + bootloaders/ace-uno/bootloader.hex | 247 +++ .../elbear_fw_bootloader_qpi_xip_cshigh_0.hex | 247 +++ cores/arduino/Arduino.h | 57 + cores/arduino/HardwareSerial.cpp | 186 +++ cores/arduino/HardwareSerial.h | 103 ++ cores/arduino/Print.cpp | 267 +++ cores/arduino/Print.h | 96 ++ cores/arduino/Printable.h | 39 + cores/arduino/Stream.cpp | 318 ++++ cores/arduino/Stream.h | 129 ++ cores/arduino/Tone.cpp | 158 ++ cores/arduino/Tone.h | 23 + cores/arduino/WCharacter.h | 168 ++ cores/arduino/WInterrupts.c | 132 ++ cores/arduino/WInterrupts.h | 26 + cores/arduino/WMath.cpp | 65 + cores/arduino/WMath.h | 33 + cores/arduino/WString.cpp | 751 +++++++++ cores/arduino/WString.h | 230 +++ cores/arduino/abi.cpp | 36 + cores/arduino/avr/dtostrf.c | 91 + cores/arduino/avr/dtostrf.h | 33 + cores/arduino/avr/pgmspace.h | 130 ++ cores/arduino/binary.h | 541 ++++++ cores/arduino/board.cpp | 36 + cores/arduino/board.h | 8 + cores/arduino/itoa.cpp | 174 ++ cores/arduino/itoa.h | 47 + cores/arduino/main.cpp | 17 + cores/arduino/mik32/hal/.gitignore | 1 + cores/arduino/mik32/hal/README.md | 1 + .../hal/core/Include/mik32_hal_scr1_timer.h | 105 ++ .../hal/core/Include/put here h files.txt | 0 .../hal/core/Source/mik32_hal_scr1_timer.c | 125 ++ .../hal/core/Source/put here c files.txt | 0 .../mik32/hal/peripherals/Include/mik32_hal.h | 34 + .../hal/peripherals/Include/mik32_hal_adc.h | 360 ++++ .../hal/peripherals/Include/mik32_hal_crc32.h | 347 ++++ .../peripherals/Include/mik32_hal_crypto.h | 120 ++ .../hal/peripherals/Include/mik32_hal_dac.h | 251 +++ .../hal/peripherals/Include/mik32_hal_def.h | 24 + .../hal/peripherals/Include/mik32_hal_dma.h | 210 +++ .../peripherals/Include/mik32_hal_eeprom.h | 118 ++ .../hal/peripherals/Include/mik32_hal_gpio.h | 391 +++++ .../hal/peripherals/Include/mik32_hal_i2c.h | 615 +++++++ .../hal/peripherals/Include/mik32_hal_irq.h | 333 ++++ .../hal/peripherals/Include/mik32_hal_otp.h | 71 + .../hal/peripherals/Include/mik32_hal_pcc.h | 280 ++++ .../hal/peripherals/Include/mik32_hal_rtc.h | 485 ++++++ .../hal/peripherals/Include/mik32_hal_spi.h | 484 ++++++ .../hal/peripherals/Include/mik32_hal_spifi.h | 234 +++ .../peripherals/Include/mik32_hal_timer16.h | 318 ++++ .../peripherals/Include/mik32_hal_timer32.h | 265 +++ .../hal/peripherals/Include/mik32_hal_tsens.h | 158 ++ .../hal/peripherals/Include/mik32_hal_wdt.h | 120 ++ .../peripherals/Include/put here h files.txt | 0 .../mik32/hal/peripherals/Source/mik32_hal.c | 15 + .../hal/peripherals/Source/mik32_hal_adc.c | 201 +++ .../hal/peripherals/Source/mik32_hal_crc32.c | 143 ++ .../hal/peripherals/Source/mik32_hal_crypto.c | 336 ++++ .../hal/peripherals/Source/mik32_hal_dac.c | 125 ++ .../hal/peripherals/Source/mik32_hal_dma.c | 284 ++++ .../hal/peripherals/Source/mik32_hal_eeprom.c | 197 +++ .../hal/peripherals/Source/mik32_hal_gpio.c | 260 +++ .../hal/peripherals/Source/mik32_hal_i2c.c | 1396 ++++++++++++++++ .../hal/peripherals/Source/mik32_hal_irq.c | 56 + .../hal/peripherals/Source/mik32_hal_otp.c | 388 +++++ .../hal/peripherals/Source/mik32_hal_pcc.c | 399 +++++ .../hal/peripherals/Source/mik32_hal_rtc.c | 271 +++ .../hal/peripherals/Source/mik32_hal_spi.c | 628 +++++++ .../hal/peripherals/Source/mik32_hal_spifi.c | 127 ++ .../peripherals/Source/mik32_hal_timer16.c | 1028 ++++++++++++ .../peripherals/Source/mik32_hal_timer32.c | 495 ++++++ .../hal/peripherals/Source/mik32_hal_tsens.c | 364 ++++ .../hal/peripherals/Source/mik32_hal_wdt.c | 203 +++ .../peripherals/Source/put here c files.txt | 0 .../utilities/Include/mik32_hal_spifi_w25.h | 103 ++ .../hal/utilities/Include/mik32_hal_ssd1306.h | 59 + .../utilities/Include/put here h files.txt | 0 .../utilities/Source/mik32_hal_spifi_w25.c | 257 +++ .../hal/utilities/Source/mik32_hal_ssd1306.c | 241 +++ .../hal/utilities/Source/put here c files.txt | 0 cores/arduino/mik32/shared/.gitignore | 52 + cores/arduino/mik32/shared/README.md | 13 + cores/arduino/mik32/shared/include/csr.h | 119 ++ .../mik32/shared/include/mcu32_memory_map.h | 250 +++ .../mik32/shared/include/riscv_csr_encoding.h | 1481 +++++++++++++++++ .../mik32/shared/include/scr1_csr_encoding.h | 88 + .../mik32/shared/include/scr1_specific.h | 35 + .../arduino/mik32/shared/ldscripts/eeprom.ld | 92 + .../mik32/shared/ldscripts/link_boot_spifi.ld | 98 ++ cores/arduino/mik32/shared/ldscripts/ram.ld | 91 + cores/arduino/mik32/shared/ldscripts/ram2.ld | 92 + cores/arduino/mik32/shared/ldscripts/spifi.ld | 92 + .../mik32/shared/ldscripts/spifi_cpp.ld | 114 ++ cores/arduino/mik32/shared/libs/dma_lib.c | 133 ++ cores/arduino/mik32/shared/libs/dma_lib.h | 54 + cores/arduino/mik32/shared/libs/rtc_lib.c | 132 ++ cores/arduino/mik32/shared/libs/rtc_lib.h | 170 ++ cores/arduino/mik32/shared/libs/spi_lib.c | 105 ++ cores/arduino/mik32/shared/libs/spi_lib.h | 28 + cores/arduino/mik32/shared/libs/uart_lib.c | 149 ++ cores/arduino/mik32/shared/libs/uart_lib.h | 135 ++ cores/arduino/mik32/shared/libs/xprintf.c | 447 +++++ cores/arduino/mik32/shared/libs/xprintf.h | 49 + .../mik32/shared/periphery/analog_reg.h | 145 ++ cores/arduino/mik32/shared/periphery/boot.h | 25 + cores/arduino/mik32/shared/periphery/crc.h | 57 + cores/arduino/mik32/shared/periphery/crypto.h | 57 + .../mik32/shared/periphery/dma_config.h | 117 ++ cores/arduino/mik32/shared/periphery/eeprom.h | 120 ++ cores/arduino/mik32/shared/periphery/epic.h | 72 + cores/arduino/mik32/shared/periphery/gpio.h | 42 + .../arduino/mik32/shared/periphery/gpio_irq.h | 39 + cores/arduino/mik32/shared/periphery/i2c.h | 175 ++ cores/arduino/mik32/shared/periphery/otp.h | 98 ++ .../mik32/shared/periphery/pad_config.h | 36 + .../mik32/shared/periphery/power_manager.h | 123 ++ .../mik32/shared/periphery/pvd_control.h | 52 + cores/arduino/mik32/shared/periphery/rtc.h | 119 ++ .../mik32/shared/periphery/scr1_timer.h | 35 + cores/arduino/mik32/shared/periphery/spi_.h | 123 ++ cores/arduino/mik32/shared/periphery/spifi.h | 137 ++ .../arduino/mik32/shared/periphery/timer16.h | 178 ++ .../arduino/mik32/shared/periphery/timer32.h | 123 ++ cores/arduino/mik32/shared/periphery/uart.h | 158 ++ cores/arduino/mik32/shared/periphery/wakeup.h | 110 ++ cores/arduino/mik32/shared/periphery/wdt.h | 72 + .../arduino/mik32/shared/periphery/wdt_bus.h | 30 + cores/arduino/mik32/shared/runtime/crt0.S | 136 ++ cores/arduino/mik32/shared/syscalls.c | 288 ++++ cores/arduino/trap_handler.c | 33 + cores/arduino/wiring.h | 58 + cores/arduino/wiring_analog.c | 188 +++ cores/arduino/wiring_analog.h | 54 + cores/arduino/wiring_constants.h | 98 ++ cores/arduino/wiring_digital.c | 155 ++ cores/arduino/wiring_digital.h | 65 + cores/arduino/wiring_pulse.cpp | 60 + cores/arduino/wiring_pulse.h | 34 + cores/arduino/wiring_shift.c | 57 + cores/arduino/wiring_shift.h | 37 + cores/arduino/wiring_time.c | 93 ++ cores/arduino/wiring_time.h | 73 + .../ADC_read_write_registers.ino | 79 + libraries/SPI/keywords.txt | 37 + libraries/SPI/library.properties | 10 + libraries/SPI/src/SPI.cpp | 339 ++++ libraries/SPI/src/SPI.h | 133 ++ libraries/Wire/examples/ds1307/ds1307.ino | 122 ++ .../Wire/examples/i2c_master/i2c_master.ino | 92 + .../Wire/examples/i2c_scanner/i2c_scanner.ino | 48 + .../Wire/examples/i2c_slave/i2c_slave.ino | 91 + libraries/Wire/keywords.txt | 29 + libraries/Wire/library.properties | 9 + libraries/Wire/src/Wire.cpp | 318 ++++ libraries/Wire/src/Wire.h | 69 + libraries/Wire/src/utility/twi.c | 384 +++++ libraries/Wire/src/utility/twi.h | 41 + platform.txt | 81 + programmers.txt | 6 + variants/standart/pins_arduino.h | 125 ++ variants/standart/variant.c | 211 +++ 164 files changed, 27352 insertions(+) create mode 100644 boards.txt create mode 100644 bootloaders/ace-uno/bootloader.hex create mode 100644 bootloaders/ace-uno/elbear_fw_bootloader_qpi_xip_cshigh_0.hex create mode 100644 cores/arduino/Arduino.h create mode 100644 cores/arduino/HardwareSerial.cpp create mode 100644 cores/arduino/HardwareSerial.h create mode 100644 cores/arduino/Print.cpp create mode 100644 cores/arduino/Print.h create mode 100644 cores/arduino/Printable.h create mode 100644 cores/arduino/Stream.cpp create mode 100644 cores/arduino/Stream.h create mode 100644 cores/arduino/Tone.cpp create mode 100644 cores/arduino/Tone.h create mode 100644 cores/arduino/WCharacter.h create mode 100644 cores/arduino/WInterrupts.c create mode 100644 cores/arduino/WInterrupts.h create mode 100644 cores/arduino/WMath.cpp create mode 100644 cores/arduino/WMath.h create mode 100644 cores/arduino/WString.cpp create mode 100644 cores/arduino/WString.h create mode 100644 cores/arduino/abi.cpp create mode 100644 cores/arduino/avr/dtostrf.c create mode 100644 cores/arduino/avr/dtostrf.h create mode 100644 cores/arduino/avr/pgmspace.h create mode 100644 cores/arduino/binary.h create mode 100644 cores/arduino/board.cpp create mode 100644 cores/arduino/board.h create mode 100644 cores/arduino/itoa.cpp create mode 100644 cores/arduino/itoa.h create mode 100644 cores/arduino/main.cpp create mode 100644 cores/arduino/mik32/hal/.gitignore create mode 100644 cores/arduino/mik32/hal/README.md create mode 100644 cores/arduino/mik32/hal/core/Include/mik32_hal_scr1_timer.h create mode 100644 cores/arduino/mik32/hal/core/Include/put here h files.txt create mode 100644 cores/arduino/mik32/hal/core/Source/mik32_hal_scr1_timer.c create mode 100644 cores/arduino/mik32/hal/core/Source/put here c files.txt create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_adc.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_crc32.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_crypto.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_dac.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_def.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_dma.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_eeprom.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_i2c.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_irq.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_otp.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_pcc.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_rtc.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spi.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spifi.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_tsens.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/mik32_hal_wdt.h create mode 100644 cores/arduino/mik32/hal/peripherals/Include/put here h files.txt create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_adc.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_crc32.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_crypto.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_dac.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_dma.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_eeprom.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_i2c.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_irq.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_otp.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_pcc.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_rtc.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spi.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spifi.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_tsens.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/mik32_hal_wdt.c create mode 100644 cores/arduino/mik32/hal/peripherals/Source/put here c files.txt create mode 100644 cores/arduino/mik32/hal/utilities/Include/mik32_hal_spifi_w25.h create mode 100644 cores/arduino/mik32/hal/utilities/Include/mik32_hal_ssd1306.h create mode 100644 cores/arduino/mik32/hal/utilities/Include/put here h files.txt create mode 100644 cores/arduino/mik32/hal/utilities/Source/mik32_hal_spifi_w25.c create mode 100644 cores/arduino/mik32/hal/utilities/Source/mik32_hal_ssd1306.c create mode 100644 cores/arduino/mik32/hal/utilities/Source/put here c files.txt create mode 100644 cores/arduino/mik32/shared/.gitignore create mode 100644 cores/arduino/mik32/shared/README.md create mode 100644 cores/arduino/mik32/shared/include/csr.h create mode 100644 cores/arduino/mik32/shared/include/mcu32_memory_map.h create mode 100644 cores/arduino/mik32/shared/include/riscv_csr_encoding.h create mode 100644 cores/arduino/mik32/shared/include/scr1_csr_encoding.h create mode 100644 cores/arduino/mik32/shared/include/scr1_specific.h create mode 100644 cores/arduino/mik32/shared/ldscripts/eeprom.ld create mode 100644 cores/arduino/mik32/shared/ldscripts/link_boot_spifi.ld create mode 100644 cores/arduino/mik32/shared/ldscripts/ram.ld create mode 100644 cores/arduino/mik32/shared/ldscripts/ram2.ld create mode 100644 cores/arduino/mik32/shared/ldscripts/spifi.ld create mode 100644 cores/arduino/mik32/shared/ldscripts/spifi_cpp.ld create mode 100644 cores/arduino/mik32/shared/libs/dma_lib.c create mode 100644 cores/arduino/mik32/shared/libs/dma_lib.h create mode 100644 cores/arduino/mik32/shared/libs/rtc_lib.c create mode 100644 cores/arduino/mik32/shared/libs/rtc_lib.h create mode 100644 cores/arduino/mik32/shared/libs/spi_lib.c create mode 100644 cores/arduino/mik32/shared/libs/spi_lib.h create mode 100644 cores/arduino/mik32/shared/libs/uart_lib.c create mode 100644 cores/arduino/mik32/shared/libs/uart_lib.h create mode 100644 cores/arduino/mik32/shared/libs/xprintf.c create mode 100644 cores/arduino/mik32/shared/libs/xprintf.h create mode 100644 cores/arduino/mik32/shared/periphery/analog_reg.h create mode 100644 cores/arduino/mik32/shared/periphery/boot.h create mode 100644 cores/arduino/mik32/shared/periphery/crc.h create mode 100644 cores/arduino/mik32/shared/periphery/crypto.h create mode 100644 cores/arduino/mik32/shared/periphery/dma_config.h create mode 100644 cores/arduino/mik32/shared/periphery/eeprom.h create mode 100644 cores/arduino/mik32/shared/periphery/epic.h create mode 100644 cores/arduino/mik32/shared/periphery/gpio.h create mode 100644 cores/arduino/mik32/shared/periphery/gpio_irq.h create mode 100644 cores/arduino/mik32/shared/periphery/i2c.h create mode 100644 cores/arduino/mik32/shared/periphery/otp.h create mode 100644 cores/arduino/mik32/shared/periphery/pad_config.h create mode 100644 cores/arduino/mik32/shared/periphery/power_manager.h create mode 100644 cores/arduino/mik32/shared/periphery/pvd_control.h create mode 100644 cores/arduino/mik32/shared/periphery/rtc.h create mode 100644 cores/arduino/mik32/shared/periphery/scr1_timer.h create mode 100644 cores/arduino/mik32/shared/periphery/spi_.h create mode 100644 cores/arduino/mik32/shared/periphery/spifi.h create mode 100644 cores/arduino/mik32/shared/periphery/timer16.h create mode 100644 cores/arduino/mik32/shared/periphery/timer32.h create mode 100644 cores/arduino/mik32/shared/periphery/uart.h create mode 100644 cores/arduino/mik32/shared/periphery/wakeup.h create mode 100644 cores/arduino/mik32/shared/periphery/wdt.h create mode 100644 cores/arduino/mik32/shared/periphery/wdt_bus.h create mode 100644 cores/arduino/mik32/shared/runtime/crt0.S create mode 100644 cores/arduino/mik32/shared/syscalls.c create mode 100644 cores/arduino/trap_handler.c create mode 100644 cores/arduino/wiring.h create mode 100644 cores/arduino/wiring_analog.c create mode 100644 cores/arduino/wiring_analog.h create mode 100644 cores/arduino/wiring_constants.h create mode 100644 cores/arduino/wiring_digital.c create mode 100644 cores/arduino/wiring_digital.h create mode 100644 cores/arduino/wiring_pulse.cpp create mode 100644 cores/arduino/wiring_pulse.h create mode 100644 cores/arduino/wiring_shift.c create mode 100644 cores/arduino/wiring_shift.h create mode 100644 cores/arduino/wiring_time.c create mode 100644 cores/arduino/wiring_time.h create mode 100644 libraries/SPI/examples/ADC_read_write_registers/ADC_read_write_registers.ino create mode 100644 libraries/SPI/keywords.txt create mode 100644 libraries/SPI/library.properties create mode 100644 libraries/SPI/src/SPI.cpp create mode 100644 libraries/SPI/src/SPI.h create mode 100644 libraries/Wire/examples/ds1307/ds1307.ino create mode 100644 libraries/Wire/examples/i2c_master/i2c_master.ino create mode 100644 libraries/Wire/examples/i2c_scanner/i2c_scanner.ino create mode 100644 libraries/Wire/examples/i2c_slave/i2c_slave.ino create mode 100644 libraries/Wire/keywords.txt create mode 100644 libraries/Wire/library.properties create mode 100644 libraries/Wire/src/Wire.cpp create mode 100644 libraries/Wire/src/Wire.h create mode 100644 libraries/Wire/src/utility/twi.c create mode 100644 libraries/Wire/src/utility/twi.h create mode 100644 platform.txt create mode 100644 programmers.txt create mode 100644 variants/standart/pins_arduino.h create mode 100644 variants/standart/variant.c diff --git a/boards.txt b/boards.txt new file mode 100644 index 0000000..64e542e --- /dev/null +++ b/boards.txt @@ -0,0 +1,23 @@ +# See: https://arduino.github.io/arduino-cli/latest/platform-specification/ +############################################################## +aceUno8Mb.name=Elbear Ace-Uno 8Mb + +# tool for firmware update +aceUno8Mb.upload.tool=elbear_uploader +aceUno8Mb.upload.protocol=elbear_uploader +aceUno8Mb.upload.maximum_size=8388608 +aceUno8Mb.upload.maximum_data_size=16384 + +# tool for bootloader update +aceUno8Mb.bootloader.tool=mik32_upload +aceUno8Mb.bootloader.tool.default=mik32_upload +aceUno8Mb.bootloader.file=ace-uno/bootloader.hex + +# build options +aceUno8Mb.build.mcu=MIK32_Amur +aceUno8Mb.build.f_cpu=32000000UL +aceUno8Mb.build.board=ACE_UNO_8Mb +aceUno8Mb.build.core=arduino +aceUno8Mb.build.variant=standart +aceUno8Mb.build.extra_flags= +aceUno8Mb.build.flags= diff --git a/bootloaders/ace-uno/bootloader.hex b/bootloaders/ace-uno/bootloader.hex new file mode 100644 index 0000000..f0462b5 --- /dev/null +++ b/bootloaders/ace-uno/bootloader.hex @@ -0,0 +1,247 @@ +:020000040100F9 +:10000000FD62938202400100FD12E39E02FE374131 +:10001000000213010100B701000293810100B7152E +:100020000001938505F137160001130606F4B706A3 +:1000300000029386060039A083A2050023A0560083 +:1000400091059106E3EAC5FEB7150001938505F415 +:1000500037160001130606F4B7060002938606263B +:1000600039A083A2050023A0560091059106E3EA7A +:10007000C5FEB70500029385050337060002130687 +:10008000062621A023A005009105E3EDC5FEB700DB +:100090000001E780C00AB7000001E780C00AB7008E +:1000A0000001E780007273005010F5BF82800000ED +:1000B0000000000000000000000000000000000040 +:1000C0006F004000197106C20AC40EC612C816CAD3 +:1000D0001ACC1ECE22D026D22AD42ED632D836DA48 +:1000E0003ADC3EDEC2C0C6C2CAC4CEC6D2C8D6CA78 +:1000F000DACCDECEE2D0E6D2EAD4EED6F2D8F6DA28 +:10010000FADCFEDE970000009380E00482909240CB +:100110002241B2414242D2426243F24302549254DB +:100120002255B2554256D2566257F2570648964863 +:100130002649B649464AD64A664BF64B065C965C5B +:10014000265DB65D465ED65E665FF65F096173004A +:10015000203001A03D432A876373C3029377F700E1 +:10016000BDEFADE5937606FF3D8ABA960CC34CC34E +:100170000CC74CC74107E36BD7FE11E28280B30680 +:10018000C3408A069702000096966780A600230760 +:10019000B700A306B7002306B700A305B7002305E1 +:1001A000B700A304B7002304B700A303B7002303D9 +:1001B000B700A302B7002302B700A301B7002301D1 +:1001C000B700A300B7002300B700828093F5F50FB6 +:1001D00093968500D58D93960501D58D61B793963D +:1001E00027009702000096968682E78086FA96801E +:1001F000C1171D8F3E96E374C3F8A5B7B707050076 +:100200000947D8CFB7170500938707C0984385667D +:1002100093860640558F98C3B71708009387074009 +:1002200023A0070023A2070023A407001307A008A8 +:10023000D8C77D57D8CF354798C3D84F9356570165 +:100240008D8AE5DE8280B71708009387074023A0D8 +:10025000070023A2070023A4070023A607007D5759 +:10026000D8CF23A40702B7170500938707C0984388 +:10027000F1769386F63F758F98C3B7070500D84F80 +:1002800023AE07008280B71708009387074088D7FE +:10029000D84F137707046DDF828037070002B71548 +:1002A000080037460F0023200704814781469385C5 +:1002B000054013061624C84D137505020DC991CECD +:1002C0002320F70437470F00130707246397E7003D +:1002D000B707000205472383E700B7170800938795 +:1002E0000740C8534205418182808546E9B78507AA +:1002F000E39DC7FEFDD2B7470F0093870724232055 +:10030000F704F9B74111B707000222C413870700A9 +:1003100006C6834667000547138407006390E6021C +:100320001305000F8D37B717080093870740D84F84 +:10033000218B09C7D84F13678700D8CF2303040048 +:10034000B240224441018280411106C622C426C225 +:10035000AA84EF009013E1689388086A01488147F6 +:10036000014781460146B70520C726853794980086 +:10037000EF000077130414687D1419E40D45B240B2 +:10038000224492444101828085452685EF00501128 +:1003900005897DF10145E5B7411122C4370400020A +:1003A000930704008C43B70700804AC0BE95B70787 +:1003B000000223ACB70206C626C293974501130478 +:1003C00004003709000289E713058900EF00701A5D +:1003D0000C40B70400029386440413060010130572 +:1003E0008900EF0050141C40370700028356470372 +:1003F000938707101CC013060010B68763F4C6006D +:1004000093070010138444041305F400938707F046 +:100410001306100F814513040410231AF7021D3B25 +:10042000A285138544043D46EF00F0182320040004 +:1004300023220400232404002316040023070400BD +:10044000B240224492440249410182805D71130608 +:1004500080028145280886C6F539BD47230CF10086 +:100460008947230EF1003ED2E177938707082C08D5 +:100470000A85231AF1021923B640616182805D71F9 +:10048000A2C4370400021305840086C6A6C2652BE9 +:1004900013058400E525894513058400EF0050000D +:1004A0009377250085E3AA84854513058400EF0032 +:1004B000207F13E62400AA851376F60F1305840027 +:1004C000EF007001E1689388086A0148814701479D +:1004D00081460146B7052038130584001125E168DF +:1004E00038009388086A1308000285468147014650 +:1004F000B70599EB1305840023040100D523B71534 +:10050000000151469385C5EF6800EF00D00A9304BF +:1005100084009C406C0051463ED085473ED2681016 +:10052000C1673ED4EF003009B70607009C42370789 +:10053000F1FF7D17F98F08109CC2812BB64026442D +:10054000964461618280411106C6F5390D3FB707B7 +:10055000008073905730B70000808290B240410114 +:100560008280411106C622C426C24AC08347350094 +:1005700005476383E70811472A846389E7008DCF25 +:10058000B24022449244024941018280B7070002EE +:1005900083D7470391C30935834744000347540079 +:1005A000E2074207BA9737070002232EF702370700 +:1005B00000022320F700E9B73709000283544903FA +:1005C0000346050093054500370500021305450461 +:1005D0002695EF00407E83470400BE94C204C1808C +:1005E000231A99029307F00FE3FC97F82244B240D4 +:1005F0009244024941014DB33D457131B7070002B4 +:1006000083D7470391C3493B2244B24092440249F5 +:10061000410115BF3707000293070700B705000225 +:1006200003DE470083A705043716080037450F008F +:1006300037480F00B708000201438146130707003F +:10064000130606401305152413080824938848153B +:1006500063EEC6016304030023A0F504834767002B +:10066000A9E73705000213054515E5BD81470323BA +:10067000C60113730302631F03008507E399A7FEF6 +:10068000B7470F009387072423A0F504854723036A +:10069000F7008280E38607FF832E46023383D8006B +:1006A00085062300D301054365B78280011122CC62 +:1006B0003704000226CA4AC84EC652C406CE1304E6 +:1006C0000400930400061309E00FB7090002130A9F +:1006D0000003E136834764001375F50FA303A400FC +:1006E00099C30D31FDB7630F950063042503E31231 +:1006F00045FF3D45493E553605052312A4003D45BD +:100700005936C1BF3D454136313783476400F1FB5F +:10071000FDB7138589000D397DD11305000FCDB7C5 +:10072000011106CE22CC1D333704000213058400CC +:10073000192E130584009921E1689388086A0148FD +:100740008147780085460146B705D9EB130584003B +:10075000230601007126E168814701478146014671 +:10076000B70538FF9388086A0148130584008D2E69 +:10077000713437070002B715080037460F002320F1 +:100780000704814781469385054013061624C84D0A +:100790001375050211CD85CA2320F70437470F00D2 +:1007A000130707246391E702793B01A08546C5B78B +:1007B0008507E39DC7FE81CAB7470F0093870724CB +:1007C0002320F704D5B7DD350547AA876305E50281 +:1007D00009476300E506054591EBB7060600DC4ACC +:1007E0007D771307F73FF98FDCCA014582807D17BB +:1007F00019EB0D4582809306004037A707001307C9 +:100800000712B7050500905D7D8E75D2370606008C +:100810005C4A7D771307F73FF98FD58F41115CCA8A +:1008200002C613073006B2476359F700014541017C +:100830008280856693860680C9B7B24785073EC623 +:10084000DDB791476307F50263EAA7008547630AAE +:10085000F50489476309F50405458280A147E31D36 +:10086000F5FE0947094501A8FD1781EFC8D20D45DE +:10087000828005470D45B7A7070093870712B70683 +:100880000500905E798E6DD28A05C98D4111CCD25A +:1008900002C613073006B247635AF700014541010B +:1008A00082801147C9BF21470145F1B7B24785078B +:1008B0003EC6D5B70547AA876305E5020947630227 +:1008C000E506054591EBB70606009C4A7D771307C0 +:1008D000F73FF98F9CCA014582807D1719EB0D45C2 +:1008E00082809306004037A7070013070712B70559 +:1008F0000500905D7D8E75D2370706001C4B7D7616 +:100900001306F63FF18FD58F1CCB85471CCF4111C5 +:1009100002C613073006B2476359F700014541018B +:1009200082808566938606807DBFB24785073EC676 +:10093000DDB711C98547630DF50205458280FD17B6 +:1009400091EB0D4582800946B7A7070093870712F0 +:10095000B7060500985E718F7DD34111C8D602C6D7 +:1009600013073006B2476357F70001454101828003 +:100970000546D9BFB24785073EC6EDB7011126CA65 +:10098000B7040600DC4806CE22CC4AC84EC652C484 +:1009900056C2F19BDCC89C482A89C845F19B9CC87B +:1009A00083C7C5012E848A07DCC883C7D5018A079F +:1009B0009CC8193D0C44AA8A03454400593518487F +:1009C000B70705002A8A98C358480850D8C3184C5E +:1009D00098C7CD35AA894850A93F834704002A8784 +:1009E00093F6170089E6D44893E62600D4C893F618 +:1009F000270099E637060600544A93E6160054CAC3 +:100A000093F6470099E637060600144A93E6260057 +:100A100014CAA18B99E7B70606009C4A93E7170012 +:100A20009CCAF24062442320590123224901232415 +:100A300039012326E900D244B249224A924A4A8522 +:100A4000424905618280011106CE22CC02C402C651 +:100A50002147B707050037550800D8C705448D471B +:100A60008A85130505803EC022C2292A3755080011 +:100A70009307C0038A851305058022C222C43EC0A5 +:100A80001122F240624405618280411122C406C6EF +:100A90002A84553F18405C4F93E707015CCF1C4404 +:100AA0001CCB5C4085CB1C43B7061000D58F1CC304 +:100AB000144C5C48B240D606CE07D58F834604015D +:100AC000C206D58F8346C4012244E206D58F1CCFCF +:100AD000410182801C43B706F0FFFD16F58FC1BFB0 +:100AE000032305002A8E0325C30113650502232E67 +:100AF000A3002324C3001396260149824D8E23268A +:100B000003012322C300139605016354060299C210 +:100B10000545B1CB01476346D700639C08020D45EC +:100B200082803386E700034606000507230AC300D8 +:100B3000DDB799C2054505CB8147E3D0D7FE032633 +:100B40000E00034546013306F70085072300A60083 +:100B5000EDB783270E00FD18DC4F93F70702D5DFB2 +:100B600011656D8D11E18280B707070083C74701CA +:100B700013F585001D8D3335A00082801C4141474F +:100B8000D8CF8280B7470800938707402A8863043C +:100B9000F508B7570800938707806304F50A3747BD +:100BA0000800630DE50A05458280331E1F01337678 +:100BB000DE0129C683A345008843139318003396AA +:100BC0006F001346F6FF13F43300718D3314640085 +:100BD000418D88C3638B5302638C0302084303AEC9 +:100BE000C500718D331E6E003365C50108C3884290 +:100BF000698E884533156500498E90C2850833D5C6 +:100C00001E0145F53244410182802326C801F9B70F +:100C10002324C801E1B7B716050037170500B71739 +:100C20000500938646C1130707C19387C7C083AEEB +:100C300005008148054F8D4F914233D51E0105EDCA +:100C40008280B716050037170500B7170500938691 +:100C500006C21307C7C1938787C1D1BFB716050066 +:100C600037170500B7170500938686C0130747C0DE +:100C7000938707C06DBF331E1F013376DE0119E273 +:100C8000850865BF411122C635B7E1689388086AB7 +:100C900001488147014781460146B705200689B5CD +:100CA000011106CEA307010089476393F502B7053A +:100CB0002035E1681307F1009388086A01488147ED +:100CC00085460146313DF2400345F10005618280D1 +:100CD000B7052005F9BF011106CE22CC26CA23068E +:100CE000B100AA84A306C1004D37E1689388086A61 +:100CF00001487C00014789460146B78520012685C9 +:100D00000964F93B130414717D1419E40D45F24094 +:100D10006244D24405618280854526855137058924 +:100D200065F50145EDB7011106CE22CC26CA2E8409 +:100D30004AC8AA84328936C6893FB247E16822860A +:100D40009388086A01480147CA86B78580022685CC +:100D5000616479331304146A7D1411C485452685B2 +:100D60008137058975F9F2406244D24442490561F0 +:100D70008280011106CE22CC26CA2EC6AA84313723 +:100D80003246E1689388086A0148814701478146F5 +:100D9000B705802026856164A1331304146A7D148D +:100DA00011C485452685ED3D058975F9F2406244FB +:100DB000D24405618280B3C7A5008D8BB308C500FE +:100DC000B1E78D4763F4C704937735002A87B9EB01 +:100DD00013F6C8FFB306E6409307000263C8D706C0 +:100DE000AE86BA876371C70203A806009107910611 +:100DF00023AE07FFE3EAC7FE9307F6FF998FF19B47 +:100E000091073E97BE956366170182802A87637EAD +:100E1000150383C7050005078505A30FF7FEE39AB1 +:100E2000E8FE828083C60500050793773700A30F8D +:100E3000D7FE8505D1DF83C6050005079377370008 +:100E4000A30FD7FE8505F9FF61B78280411122C645 +:100E50001304000283A3050083A2450083AF85002D +:100E600003AFC50083AE050103AE450103A38501B1 +:100E700003A8C501945113074702B307E640232E88 +:100E800077FC232057FE2322F7FF2324E7FF2326A6 +:100E9000D7FF2328C7FF232A67FE232C07FF232E13 +:100EA000D7FE93854502E347F4FAAE86BA876371AD +:100EB000C70203A806009107910623AE07FFE3EAE5 +:100EC000C7FE9307F6FF998FF19B91073E97BE955A +:100ED0006365170132444101828083C7050005071D +:100EE0008505A30FF7FEE387E8FE83C70500050726 +:100EF0008505A30FF7FEE392E8FEE9BF200000009E +:100F0000010000000300000006000000EB000000EC +:100F10000000008000010000000007000000000049 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:0400000501000000F6 +:00000001FF diff --git a/bootloaders/ace-uno/elbear_fw_bootloader_qpi_xip_cshigh_0.hex b/bootloaders/ace-uno/elbear_fw_bootloader_qpi_xip_cshigh_0.hex new file mode 100644 index 0000000..f0462b5 --- /dev/null +++ b/bootloaders/ace-uno/elbear_fw_bootloader_qpi_xip_cshigh_0.hex @@ -0,0 +1,247 @@ +:020000040100F9 +:10000000FD62938202400100FD12E39E02FE374131 +:10001000000213010100B701000293810100B7152E +:100020000001938505F137160001130606F4B706A3 +:1000300000029386060039A083A2050023A0560083 +:1000400091059106E3EAC5FEB7150001938505F415 +:1000500037160001130606F4B7060002938606263B +:1000600039A083A2050023A0560091059106E3EA7A +:10007000C5FEB70500029385050337060002130687 +:10008000062621A023A005009105E3EDC5FEB700DB +:100090000001E780C00AB7000001E780C00AB7008E +:1000A0000001E780007273005010F5BF82800000ED +:1000B0000000000000000000000000000000000040 +:1000C0006F004000197106C20AC40EC612C816CAD3 +:1000D0001ACC1ECE22D026D22AD42ED632D836DA48 +:1000E0003ADC3EDEC2C0C6C2CAC4CEC6D2C8D6CA78 +:1000F000DACCDECEE2D0E6D2EAD4EED6F2D8F6DA28 +:10010000FADCFEDE970000009380E00482909240CB +:100110002241B2414242D2426243F24302549254DB +:100120002255B2554256D2566257F2570648964863 +:100130002649B649464AD64A664BF64B065C965C5B +:10014000265DB65D465ED65E665FF65F096173004A +:10015000203001A03D432A876373C3029377F700E1 +:10016000BDEFADE5937606FF3D8ABA960CC34CC34E +:100170000CC74CC74107E36BD7FE11E28280B30680 +:10018000C3408A069702000096966780A600230760 +:10019000B700A306B7002306B700A305B7002305E1 +:1001A000B700A304B7002304B700A303B7002303D9 +:1001B000B700A302B7002302B700A301B7002301D1 +:1001C000B700A300B7002300B700828093F5F50FB6 +:1001D00093968500D58D93960501D58D61B793963D +:1001E00027009702000096968682E78086FA96801E +:1001F000C1171D8F3E96E374C3F8A5B7B707050076 +:100200000947D8CFB7170500938707C0984385667D +:1002100093860640558F98C3B71708009387074009 +:1002200023A0070023A2070023A407001307A008A8 +:10023000D8C77D57D8CF354798C3D84F9356570165 +:100240008D8AE5DE8280B71708009387074023A0D8 +:10025000070023A2070023A4070023A607007D5759 +:10026000D8CF23A40702B7170500938707C0984388 +:10027000F1769386F63F758F98C3B7070500D84F80 +:1002800023AE07008280B71708009387074088D7FE +:10029000D84F137707046DDF828037070002B71548 +:1002A000080037460F0023200704814781469385C5 +:1002B000054013061624C84D137505020DC991CECD +:1002C0002320F70437470F00130707246397E7003D +:1002D000B707000205472383E700B7170800938795 +:1002E0000740C8534205418182808546E9B78507AA +:1002F000E39DC7FEFDD2B7470F0093870724232055 +:10030000F704F9B74111B707000222C413870700A9 +:1003100006C6834667000547138407006390E6021C +:100320001305000F8D37B717080093870740D84F84 +:10033000218B09C7D84F13678700D8CF2303040048 +:10034000B240224441018280411106C622C426C225 +:10035000AA84EF009013E1689388086A01488147F6 +:10036000014781460146B70520C726853794980086 +:10037000EF000077130414687D1419E40D45B240B2 +:10038000224492444101828085452685EF00501128 +:1003900005897DF10145E5B7411122C4370400020A +:1003A000930704008C43B70700804AC0BE95B70787 +:1003B000000223ACB70206C626C293974501130478 +:1003C00004003709000289E713058900EF00701A5D +:1003D0000C40B70400029386440413060010130572 +:1003E0008900EF0050141C40370700028356470372 +:1003F000938707101CC013060010B68763F4C6006D +:1004000093070010138444041305F400938707F046 +:100410001306100F814513040410231AF7021D3B25 +:10042000A285138544043D46EF00F0182320040004 +:1004300023220400232404002316040023070400BD +:10044000B240224492440249410182805D71130608 +:1004500080028145280886C6F539BD47230CF10086 +:100460008947230EF1003ED2E177938707082C08D5 +:100470000A85231AF1021923B640616182805D71F9 +:10048000A2C4370400021305840086C6A6C2652BE9 +:1004900013058400E525894513058400EF0050000D +:1004A0009377250085E3AA84854513058400EF0032 +:1004B000207F13E62400AA851376F60F1305840027 +:1004C000EF007001E1689388086A0148814701479D +:1004D00081460146B7052038130584001125E168DF +:1004E00038009388086A1308000285468147014650 +:1004F000B70599EB1305840023040100D523B71534 +:10050000000151469385C5EF6800EF00D00A9304BF +:1005100084009C406C0051463ED085473ED2681016 +:10052000C1673ED4EF003009B70607009C42370789 +:10053000F1FF7D17F98F08109CC2812BB64026442D +:10054000964461618280411106C6F5390D3FB707B7 +:10055000008073905730B70000808290B240410114 +:100560008280411106C622C426C24AC08347350094 +:1005700005476383E70811472A846389E7008DCF25 +:10058000B24022449244024941018280B7070002EE +:1005900083D7470391C30935834744000347540079 +:1005A000E2074207BA9737070002232EF702370700 +:1005B00000022320F700E9B73709000283544903FA +:1005C0000346050093054500370500021305450461 +:1005D0002695EF00407E83470400BE94C204C1808C +:1005E000231A99029307F00FE3FC97F82244B240D4 +:1005F0009244024941014DB33D457131B7070002B4 +:1006000083D7470391C3493B2244B24092440249F5 +:10061000410115BF3707000293070700B705000225 +:1006200003DE470083A705043716080037450F008F +:1006300037480F00B708000201438146130707003F +:10064000130606401305152413080824938848153B +:1006500063EEC6016304030023A0F504834767002B +:10066000A9E73705000213054515E5BD81470323BA +:10067000C60113730302631F03008507E399A7FEF6 +:10068000B7470F009387072423A0F504854723036A +:10069000F7008280E38607FF832E46023383D8006B +:1006A00085062300D301054365B78280011122CC62 +:1006B0003704000226CA4AC84EC652C406CE1304E6 +:1006C0000400930400061309E00FB7090002130A9F +:1006D0000003E136834764001375F50FA303A400FC +:1006E00099C30D31FDB7630F950063042503E31231 +:1006F00045FF3D45493E553605052312A4003D45BD +:100700005936C1BF3D454136313783476400F1FB5F +:10071000FDB7138589000D397DD11305000FCDB7C5 +:10072000011106CE22CC1D333704000213058400CC +:10073000192E130584009921E1689388086A0148FD +:100740008147780085460146B705D9EB130584003B +:10075000230601007126E168814701478146014671 +:10076000B70538FF9388086A0148130584008D2E69 +:10077000713437070002B715080037460F002320F1 +:100780000704814781469385054013061624C84D0A +:100790001375050211CD85CA2320F70437470F00D2 +:1007A000130707246391E702793B01A08546C5B78B +:1007B0008507E39DC7FE81CAB7470F0093870724CB +:1007C0002320F704D5B7DD350547AA876305E50281 +:1007D00009476300E506054591EBB7060600DC4ACC +:1007E0007D771307F73FF98FDCCA014582807D17BB +:1007F00019EB0D4582809306004037A707001307C9 +:100800000712B7050500905D7D8E75D2370606008C +:100810005C4A7D771307F73FF98FD58F41115CCA8A +:1008200002C613073006B2476359F700014541017C +:100830008280856693860680C9B7B24785073EC623 +:10084000DDB791476307F50263EAA7008547630AAE +:10085000F50489476309F50405458280A147E31D36 +:10086000F5FE0947094501A8FD1781EFC8D20D45DE +:10087000828005470D45B7A7070093870712B70683 +:100880000500905E798E6DD28A05C98D4111CCD25A +:1008900002C613073006B247635AF700014541010B +:1008A00082801147C9BF21470145F1B7B24785078B +:1008B0003EC6D5B70547AA876305E5020947630227 +:1008C000E506054591EBB70606009C4A7D771307C0 +:1008D000F73FF98F9CCA014582807D1719EB0D45C2 +:1008E00082809306004037A7070013070712B70559 +:1008F0000500905D7D8E75D2370706001C4B7D7616 +:100900001306F63FF18FD58F1CCB85471CCF4111C5 +:1009100002C613073006B2476359F700014541018B +:1009200082808566938606807DBFB24785073EC676 +:10093000DDB711C98547630DF50205458280FD17B6 +:1009400091EB0D4582800946B7A7070093870712F0 +:10095000B7060500985E718F7DD34111C8D602C6D7 +:1009600013073006B2476357F70001454101828003 +:100970000546D9BFB24785073EC6EDB7011126CA65 +:10098000B7040600DC4806CE22CC4AC84EC652C484 +:1009900056C2F19BDCC89C482A89C845F19B9CC87B +:1009A00083C7C5012E848A07DCC883C7D5018A079F +:1009B0009CC8193D0C44AA8A03454400593518487F +:1009C000B70705002A8A98C358480850D8C3184C5E +:1009D00098C7CD35AA894850A93F834704002A8784 +:1009E00093F6170089E6D44893E62600D4C893F618 +:1009F000270099E637060600544A93E6160054CAC3 +:100A000093F6470099E637060600144A93E6260057 +:100A100014CAA18B99E7B70606009C4A93E7170012 +:100A20009CCAF24062442320590123224901232415 +:100A300039012326E900D244B249224A924A4A8522 +:100A4000424905618280011106CE22CC02C402C651 +:100A50002147B707050037550800D8C705448D471B +:100A60008A85130505803EC022C2292A3755080011 +:100A70009307C0038A851305058022C222C43EC0A5 +:100A80001122F240624405618280411122C406C6EF +:100A90002A84553F18405C4F93E707015CCF1C4404 +:100AA0001CCB5C4085CB1C43B7061000D58F1CC304 +:100AB000144C5C48B240D606CE07D58F834604015D +:100AC000C206D58F8346C4012244E206D58F1CCFCF +:100AD000410182801C43B706F0FFFD16F58FC1BFB0 +:100AE000032305002A8E0325C30113650502232E67 +:100AF000A3002324C3001396260149824D8E23268A +:100B000003012322C300139605016354060299C210 +:100B10000545B1CB01476346D700639C08020D45EC +:100B200082803386E700034606000507230AC300D8 +:100B3000DDB799C2054505CB8147E3D0D7FE032633 +:100B40000E00034546013306F70085072300A60083 +:100B5000EDB783270E00FD18DC4F93F70702D5DFB2 +:100B600011656D8D11E18280B707070083C74701CA +:100B700013F585001D8D3335A00082801C4141474F +:100B8000D8CF8280B7470800938707402A8863043C +:100B9000F508B7570800938707806304F50A3747BD +:100BA0000800630DE50A05458280331E1F01337678 +:100BB000DE0129C683A345008843139318003396AA +:100BC0006F001346F6FF13F43300718D3314640085 +:100BD000418D88C3638B5302638C0302084303AEC9 +:100BE000C500718D331E6E003365C50108C3884290 +:100BF000698E884533156500498E90C2850833D5C6 +:100C00001E0145F53244410182802326C801F9B70F +:100C10002324C801E1B7B716050037170500B71739 +:100C20000500938646C1130707C19387C7C083AEEB +:100C300005008148054F8D4F914233D51E0105EDCA +:100C40008280B716050037170500B7170500938691 +:100C500006C21307C7C1938787C1D1BFB716050066 +:100C600037170500B7170500938686C0130747C0DE +:100C7000938707C06DBF331E1F013376DE0119E273 +:100C8000850865BF411122C635B7E1689388086AB7 +:100C900001488147014781460146B705200689B5CD +:100CA000011106CEA307010089476393F502B7053A +:100CB0002035E1681307F1009388086A01488147ED +:100CC00085460146313DF2400345F10005618280D1 +:100CD000B7052005F9BF011106CE22CC26CA23068E +:100CE000B100AA84A306C1004D37E1689388086A61 +:100CF00001487C00014789460146B78520012685C9 +:100D00000964F93B130414717D1419E40D45F24094 +:100D10006244D24405618280854526855137058924 +:100D200065F50145EDB7011106CE22CC26CA2E8409 +:100D30004AC8AA84328936C6893FB247E16822860A +:100D40009388086A01480147CA86B78580022685CC +:100D5000616479331304146A7D1411C485452685B2 +:100D60008137058975F9F2406244D24442490561F0 +:100D70008280011106CE22CC26CA2EC6AA84313723 +:100D80003246E1689388086A0148814701478146F5 +:100D9000B705802026856164A1331304146A7D148D +:100DA00011C485452685ED3D058975F9F2406244FB +:100DB000D24405618280B3C7A5008D8BB308C500FE +:100DC000B1E78D4763F4C704937735002A87B9EB01 +:100DD00013F6C8FFB306E6409307000263C8D706C0 +:100DE000AE86BA876371C70203A806009107910611 +:100DF00023AE07FFE3EAC7FE9307F6FF998FF19B47 +:100E000091073E97BE956366170182802A87637EAD +:100E1000150383C7050005078505A30FF7FEE39AB1 +:100E2000E8FE828083C60500050793773700A30F8D +:100E3000D7FE8505D1DF83C6050005079377370008 +:100E4000A30FD7FE8505F9FF61B78280411122C645 +:100E50001304000283A3050083A2450083AF85002D +:100E600003AFC50083AE050103AE450103A38501B1 +:100E700003A8C501945113074702B307E640232E88 +:100E800077FC232057FE2322F7FF2324E7FF2326A6 +:100E9000D7FF2328C7FF232A67FE232C07FF232E13 +:100EA000D7FE93854502E347F4FAAE86BA876371AD +:100EB000C70203A806009107910623AE07FFE3EAE5 +:100EC000C7FE9307F6FF998FF19B91073E97BE955A +:100ED0006365170132444101828083C7050005071D +:100EE0008505A30FF7FEE387E8FE83C70500050726 +:100EF0008505A30FF7FEE392E8FEE9BF200000009E +:100F0000010000000300000006000000EB000000EC +:100F10000000008000010000000007000000000049 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:0400000501000000F6 +:00000001FF diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h new file mode 100644 index 0000000..62e562a --- /dev/null +++ b/cores/arduino/Arduino.h @@ -0,0 +1,57 @@ +/* + Arduino.h - Main include file for the Arduino SDK + Copyright (c) 2005-2013 Arduino Team. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Arduino_h +#define Arduino_h + +#ifndef GCC_VERSION +#define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) +#endif +#if GCC_VERSION < 60300 + #error "GCC version 6.3 or higher is required" +#endif + +#ifdef __IN_ECLIPSE__ + // #include "SrcWrapper.h" +#endif + +#include "wiring.h" + +// void ErrorMsgHandler(const char * msg); + +/* sketch */ +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +extern void setup(void) ; +extern void loop(void) ; + +// void yield(void) + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +// Include pins variant +#include "pins_arduino.h" + +#endif // Arduino_h diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp new file mode 100644 index 0000000..9dc60ec --- /dev/null +++ b/cores/arduino/HardwareSerial.cpp @@ -0,0 +1,186 @@ +/* + HardwareSerial.cpp - Hardware serial library for Wiring +*/ + +#include "HardwareSerial.h" +#include +#include "mik32_hal_irq.h" + +// объект класса HardwareSerial для использования в arduino ide +HardwareSerial Serial; +void serialEvent() __attribute__((weak)); +bool Serial0_available() __attribute__((weak)); + +void serialEventRun(void) +{ + if (Serial0_available && serialEvent && Serial0_available()) + serialEvent(); +} + + +// Public Methods +void HardwareSerial::begin(unsigned long baud, uint8_t config) +{ + // find the frequency divider (F_CPU is in the preprocessor defines) + uint32_t brr = (uint32_t)(F_CPU/baud); + if (brr < 16) // the driver says that the divisor must be at least 16 + brr = 16; + + // parse config + uint32_t reg1config = UART_CONTROL1_RE_M | UART_CONTROL1_TE_M | UART_CONTROL1_RXNEIE_M; + uint32_t reg2config = 0; + uint32_t reg3config = 0; + + // first look at parity, because the parity bit is included in the data length + bool useParity = true; + if ((config >> 4) == 0) // no - everything is zero, don't set anything in reg1config + useParity = false; + else if ((config >> 4) == 2) // even + reg1config |= UART_CONTROL1_PCE_M; + else if ((config >> 4) == 3) // odd + reg1config |= (UART_CONTROL1_PCE_M | UART_CONTROL1_PS_M); + + // data length + if (((config & 0x07) == 4) && (useParity == false)) // 7 bit + no parity + // 7 bits without parity - configure 7 bits + reg1config |= UART_CONTROL1_M_7BIT_M; + else if (((config & 0x07) == 6) && (useParity == true)) // 8 bit + parity + // 8 bits with parity - configure 9 bits + reg1config |= UART_CONTROL1_M_9BIT_M; + // if 7 bits with parity or 8 bits without parity - do not change anything, + // leaving the data length selected as 8 bits + + // stop bit // stop bit = 1 - everything is zero, don't set anything + if ((config >> 3) & (0x01 == 1)) // stop bit = 2 + reg2config |= UART_CONTROL2_STOP_1_M; + + // turn on the receiver and transmitter, apply the parsed config + UART_Init(UART_0, brr, reg1config, reg2config, reg3config); + // Enable level-based interrupts for the EPIC_UART_0 line, we have only receive interrupt enabled + HAL_EPIC_MaskLevelSet(HAL_EPIC_UART_0_MASK); + + isInited = true; +} + +void HardwareSerial::end() +{ + if (isInited) + { + // wait for the data to be sent if necessary + flush(); + + // disable clock + __HAL_PCC_UART_0_CLK_DISABLE(); + HAL_EPIC_MaskLevelClear(HAL_EPIC_UART_0_MASK); + + // reconfigure pins to z state + GPIO_InitTypeDef GPIO_InitStruct; + memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct)); + GPIO_InitStruct.Pin = (HAL_PinsTypeDef)(GPIO_PIN_5 | GPIO_PIN_6); + GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + // reset buffer indices + _rx_buffer_head = _rx_buffer_tail = 0; + + isInited = false; + } +} + +int HardwareSerial::available(void) +{ + // free space in buffer + return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE; +} + +int HardwareSerial::availableForWrite(void) +{ + // don't use buffer + return -1; +} + +void HardwareSerial::rx_complete_irq(void) +{ + // find next index in buffer with upper limit + uint8_t i = (uint8_t)(_rx_buffer_head + 1)%SERIAL_RX_BUFFER_SIZE; + unsigned char c; + // while there is something to receive, put the data into the buffer + // and edit the buffer index + while (!UART_IsRxFifoEmpty(UART_0)) + { + c = UART_ReadByte(UART_0); + if (i != _rx_buffer_tail) + { + // write if there is space in the buffer + _rx_buffer[_rx_buffer_head] = c; + _rx_buffer_head = i; + } + } +} + +// wrapper for use in С-files +extern "C" void serial_handler_wrapper(void) +{ + Serial.rx_complete_irq(); +} + +int HardwareSerial::peek(void) +{ + if (_rx_buffer_head == _rx_buffer_tail) // nothing to read + return -1; + else + return _rx_buffer[_rx_buffer_tail]; // return first element +} + +int HardwareSerial::read(void) +{ + // if there is nothing to read, return -1 + if (_rx_buffer_head == _rx_buffer_tail) + return -1; + else + { + // return first element and edit the buffer index + unsigned char c = _rx_buffer[_rx_buffer_tail]; + _rx_buffer_tail = (uint8_t)(_rx_buffer_tail + 1)%SERIAL_RX_BUFFER_SIZE; + return (int)c; + } +} + +// write byte +size_t HardwareSerial::write(uint8_t c) +{ + if (isInited) + { + UART_WriteByte(UART_0, c); + UART_WaitTransmission(UART_0); + return 1; + } + else + return 0; +} + +// write bytes buffer +size_t HardwareSerial::write(const uint8_t *buffer, size_t size) +{ + if (isInited) + { + size_t n = 0; + while (size--) + { + if (HardwareSerial::write(*buffer++)) + n++; + else + break; + } + return n; + } + else + return 0; +} + +void HardwareSerial::flush() +{ + // wait for the data transfer complete + while((UART_0->FLAGS & UART_FLAGS_TC_M) == 0) + ; +} diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h new file mode 100644 index 0000000..2847de9 --- /dev/null +++ b/cores/arduino/HardwareSerial.h @@ -0,0 +1,103 @@ +/* + HardwareSerial.h - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 28 September 2010 by Mark Sproul + Modified 14 August 2012 by Alarus + Modified 3 December 2013 by Matthijs Kooijman +*/ + +#ifndef HardwareSerial_h +#define HardwareSerial_h + +#include +#include "stdint.h" +#include "Stream.h" + +// Define constants and variables for buffering incoming serial data. We're +// using a ring buffer (I think), in which head is the index of the location +// to which to write the next incoming character and tail is the index of the +// location from which to read. +// NOTE: a "power of 2" buffer size is recommended to dramatically +// optimize all the modulo operations for ring buffers. +// WARNING: When buffer sizes are increased to > 256, the buffer index +// variables are automatically increased in size, but the extra +// atomicity guards needed for that are not implemented. This will +// often work, but occasionally a race condition can occur that makes +// Serial behave erratically. See https://github.com/arduino/Arduino/issues/2405 + +#define SERIAL_RX_BUFFER_SIZE 64 + +// Define config for Serial.begin(baud, config); +// parity: 7...4 bits = 0 (no), 2 (even), 3 (odd) +// stop bit: 3 bit = 0 (1 bit), 1 (2 bits) +// data width: 2...0 bits = 4 (7 bit), 6 (8 bit) +// ------- No parity (N) ------- +// 1stop bit +#define SERIAL_7N1 0x04 // 00000100 +#define SERIAL_8N1 0x06 // 00000110 +// 2stop bits +#define SERIAL_7N2 0x0C // 00001100 +#define SERIAL_8N2 0x0E // 00001110 +// ------- Even parity ------- +#define SERIAL_7E1 0x24 // 00100100 +#define SERIAL_8E1 0x26 // 00100110 +#define SERIAL_7E2 0x2C // 00101100 +#define SERIAL_8E2 0x2E // 00101110 +// ------- Odd parity ------- +#define SERIAL_7O1 0x34 // 00110100 +#define SERIAL_8O1 0x36 // 00110110 +#define SERIAL_7O2 0x3C // 00111100 +#define SERIAL_8O2 0x3E // 00111110 + +class HardwareSerial : public Stream +{ + protected: + volatile uint8_t _rx_buffer_head; + volatile uint8_t _rx_buffer_tail; + unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE]; + + private: + bool isInited = false; + + public: + inline HardwareSerial(){}; + + void begin(unsigned long baud) { begin(baud, SERIAL_8N1); } + void begin(unsigned long, uint8_t); + void end(); + virtual int available(void); + virtual int availableForWrite(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void); + size_t write(uint8_t) override; + inline size_t write(unsigned long n) { return write((uint8_t)n); } + inline size_t write(long n) { return write((uint8_t)n); } + inline size_t write(unsigned int n) { return write((uint8_t)n); } + inline size_t write(int n) { return write((uint8_t)n); } + size_t write(const uint8_t *buffer, size_t size); + using Print::write; // pull in write(str) + operator bool() { return isInited; } + + void rx_complete_irq(void); +}; + +extern HardwareSerial Serial; +extern void serialEventRun(void) __attribute__((weak)); + +#endif diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp new file mode 100644 index 0000000..9023995 --- /dev/null +++ b/cores/arduino/Print.cpp @@ -0,0 +1,267 @@ +/* + Print.cpp - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + Modified 03 August 2015 by Chuck Todd + */ + +#include +#include +#include +#include +#include "Arduino.h" + +#include "Print.h" + +// Public Methods ////////////////////////////////////////////////////////////// + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) + { + if (write(*buffer++)) n++; + else break; + } + return n; +} + +size_t Print::print(const __FlashStringHelper *ifsh) +{ + PGM_P p = reinterpret_cast(ifsh); + size_t n = 0; + while (1) { + unsigned char c = pgm_read_byte(p++); + if (c == 0) break; + if (write(c)) n++; + else break; + } + return n; +} + +size_t Print::print(const String &s) +{ + return write(s.c_str(), s.length()); +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(unsigned char b, int base) +{ + return print((unsigned long) b, base); +} + +size_t Print::print(int n, int base) +{ + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + +size_t Print::print(const Printable& x) +{ + return x.printTo(*this); +} + +size_t Print::println(void) +{ + return write("\r\n"); +} + +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + +size_t Print::println(const Printable& x) +{ + size_t n = print(x); + n += println(); + return n; +} + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) +{ + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + char c = n % base; + n /= base; + + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return write(str); +} + +size_t Print::printFloat(double number, uint8_t digits) +{ + size_t n = 0; + + if (isnan(number)) return print("nan"); + if (isinf(number)) return print("inf"); + if (number > 4294967040.0) return print ("ovf"); // constant determined empirically + if (number <-4294967040.0) return print ("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) + { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i=0; i 0) { + n += print('.'); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + unsigned int toPrint = (unsigned int)(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h new file mode 100644 index 0000000..ac6d90c --- /dev/null +++ b/cores/arduino/Print.h @@ -0,0 +1,96 @@ +/* + Print.h - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Print_h +#define Print_h + +#include +#include // for size_t + +#include "WString.h" +#include "string.h" +#include "Printable.h" + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar +#undef BIN +#endif +#define BIN 2 + +class Print +{ + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { write_error = err; } + public: + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) + { + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); + } + size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) + { + return write((const uint8_t *)buffer, size); + } + + // default to zero, meaning "a single write may block" + // should be overridden by subclasses with buffering + virtual int availableForWrite() { return 0; } + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); + + virtual void flush() { /* Empty implementation for backward compatibility */ } +}; + +#endif diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h new file mode 100644 index 0000000..a1dc796 --- /dev/null +++ b/cores/arduino/Printable.h @@ -0,0 +1,39 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Printable_h +#define Printable_h + +#include + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable { + public: + virtual size_t printTo(Print &p) const = 0; +}; + +#endif + diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp new file mode 100644 index 0000000..9eff663 --- /dev/null +++ b/cores/arduino/Stream.cpp @@ -0,0 +1,318 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + + findMulti/findUntil routines written by Jim Leonard/Xuth + */ + +#include "Arduino.h" +#include "Stream.h" + +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait + +// protected method to read stream with timeout +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// protected method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do { + c = peek(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal) +{ + int c; + while (1) { + c = timedPeek(); + + if( c < 0 || + c == '-' || + (c >= '0' && c <= '9') || + (detectDecimal && c == '.')) return c; + + switch( lookahead ){ + case SKIP_NONE: return -1; // Fail code. + case SKIP_WHITESPACE: + switch( c ){ + case ' ': + case '\t': + case '\r': + case '\n': break; + default: return -1; // Fail code. + } + case SKIP_ALL: + break; + } + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + + // find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, strlen(target), NULL, 0); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + if (terminator == NULL) { + MultiTarget t[1] = {{target, targetLen, 0}}; + return findMulti(t, 1) == 0 ? true : false; + } else { + MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; + return findMulti(t, 2) == 0 ? true : false; + } +} + +// returns the first valid (long) integer value from the current position. +// lookahead determines how parseInt looks ahead in the stream. +// See LookaheadMode enumeration at the top of the file. +// Lookahead is terminated by the first character that is not a valid part of an integer. +// Once parsing commences, 'ignore' will be skipped in the stream. +long Stream::parseInt(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + long value = 0; + int c; + + c = peekNextDigit(lookahead, false); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == ignore) + ; // ignore this character + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == ignore ); + + if(isNegative) + value = -value; + return value; +} + +// as parseInt but returns a floating point value +float Stream::parseFloat(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + bool isFraction = false; + long value = 0; + int c; + float fraction = 1.0; + + c = peekNextDigit(lookahead, true); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == ignore) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') { // is c a digit? + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1; + } + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore ); + + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::readBytes(char *buffer, size_t length) +{ + size_t count = 0; + while (count < length) { + int c = timedRead(); + if (c < 0) break; + *buffer++ = (char)c; + count++; + } + return count; +} + + +// as readBytes with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + size_t index = 0; + while (index < length) { + int c = timedRead(); + if (c < 0 || c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { + // any zero length target string automatically matches and would make + // a mess of the rest of the algorithm. + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + if (t->len <= 0) + return t - targets; + } + + while (1) { + int c = timedRead(); + if (c < 0) + return -1; + + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + // the simple case is if we match, deal with that first. + if (c == t->str[t->index]) { + if (++t->index == t->len) + return t - targets; + else + continue; + } + + // if not we need to walk back and see if we could have matched further + // down the stream (ie '1112' doesn't match the first position in '11112' + // but it will match the second position so we can't just reset the current + // index to 0 when we find a mismatch. + if (t->index == 0) + continue; + + int origIndex = t->index; + do { + --t->index; + // first check if current char works against the new current index + if (c != t->str[t->index]) + continue; + + // if it's the only char then we're good, nothing more to check + if (t->index == 0) { + t->index++; + break; + } + + // otherwise we need to check the rest of the found string + int diff = origIndex - t->index; + size_t i; + for (i = 0; i < t->index; ++i) { + if (t->str[i] != t->str[i + diff]) + break; + } + + // if we successfully got through the previous loop then our current + // index is good. + if (i == t->index) { + t->index++; + break; + } + + // otherwise we just try the next index + } while (t->index); + } + } + // unreachable + return -1; +} diff --git a/cores/arduino/Stream.h b/cores/arduino/Stream.h new file mode 100644 index 0000000..21a247a --- /dev/null +++ b/cores/arduino/Stream.h @@ -0,0 +1,129 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#ifndef Stream_h +#define Stream_h + +#include +#include "Print.h" + +// compatibility macros for testing +/* +#define getInt() parseInt() +#define getInt(ignore) parseInt(ignore) +#define getFloat() parseFloat() +#define getFloat(ignore) parseFloat(ignore) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + +// This enumeration provides the lookahead options for parseInt(), parseFloat() +// The rules set out here are used until either the first valid character is found +// or a time out occurs due to lack of input. +enum LookaheadMode{ + SKIP_ALL, // All invalid characters are ignored. + SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. + SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. +}; + +#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field + +class Stream : public Print +{ + protected: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // read stream with timeout + int timedPeek(); // peek stream with timeout + int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout + + public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + + Stream() {_timeout=1000;} + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + unsigned long getTimeout(void) { return _timeout; } + + bool find(char *target); // reads data from the stream until the target string is found + bool find(uint8_t *target) { return find ((char *)target); } + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } + // returns true if target string is found, false if timed out + + bool find(char target) { return find (&target, 1); } + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } + + long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // returns the first valid (long) integer value from the current position. + // lookahead determines how parseInt looks ahead in the stream. + // See LookaheadMode enumeration at the top of the file. + // Lookahead is terminated by the first character that is not a valid part of an integer. + // Once parsing commences, 'ignore' will be skipped in the stream. + + float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + + protected: + long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } + float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } + // These overload exists for compatibility with any class that has derived + // Stream and used parseFloat/Int with a custom ignore character. To keep + // the public API simple, these overload remains protected. + + struct MultiTarget { + const char *str; // string you're searching for + size_t len; // length of string you're searching for + size_t index; // index used by the search routine. + }; + + // This allows you to search for an arbitrary number of strings. + // Returns index of the target that is found first or -1 if timeout occurs. + int findMulti(struct MultiTarget *targets, int tCount); +}; + +#undef NO_IGNORE_CHAR +#endif diff --git a/cores/arduino/Tone.cpp b/cores/arduino/Tone.cpp new file mode 100644 index 0000000..4977133 --- /dev/null +++ b/cores/arduino/Tone.cpp @@ -0,0 +1,158 @@ +#include "Arduino.h" +#include "pins_arduino.h" + +#include "mik32_hal_timer16.h" +#include "mik32_hal_irq.h" + +#define PRESCALERS_QTY 7 +typedef struct +{ + unsigned int frequency; + uint8_t prescaler; + uint32_t period_ticks; +}FrequencyParams_t; +FrequencyParams_t frequencyParams = {0, 0, 0}; + +// timer handler +Timer16_HandleTypeDef htimer16_1; + +// timer_toggle_count: +// > 0 - duration specified +// = 0 - stopped +// < 0 - infinitely (until noTone() called) +volatile long timer_toggle_count; + +// tone pin params +volatile int8_t timer_pin = -1; +volatile GPIO_TypeDef* timer_pin_port = 0; +volatile HAL_PinsTypeDef timer_pin_mask = (HAL_PinsTypeDef)0; + +bool timerIsOn = false; + +static void Timer16_Init(uint8_t prescaler) +{ + htimer16_1.Instance = TIMER16_1; + htimer16_1.Clock.Source = TIMER16_SOURCE_INTERNAL_SYSTEM; + // prescaler depends on required frequency + htimer16_1.Clock.Prescaler = prescaler; + htimer16_1.CountMode = TIMER16_COUNTMODE_INTERNAL; + htimer16_1.ActiveEdge = TIMER16_ACTIVEEDGE_RISING; + htimer16_1.Preload = TIMER16_PRELOAD_AFTERWRITE; + htimer16_1.Trigger.Source = 0; + // timer triggers by software + htimer16_1.Trigger.ActiveEdge = TIMER16_TRIGGER_ACTIVEEDGE_SOFTWARE; + htimer16_1.Trigger.TimeOut = TIMER16_TIMEOUT_DISABLE; + htimer16_1.Filter.ExternalClock = TIMER16_FILTER_NONE; + htimer16_1.Filter.Trigger = TIMER16_FILTER_NONE; + htimer16_1.Waveform.Enable = TIMER16_WAVEFORM_GENERATION_ENABLE; + htimer16_1.Waveform.Polarity = TIMER16_WAVEFORM_POLARITY_NONINVERTED; + htimer16_1.EncoderMode = TIMER16_ENCODER_DISABLE; + HAL_Timer16_Init(&htimer16_1); +} + +// calculate prescaler and period in timer ticks for required frequancy +static void calcFrequencyParams(FrequencyParams_t* params, unsigned int newFrequency) +{ + // limit the frequency to an acceptable range + if (newFrequency < TONE_MIN_FREQUENCY_HZ) newFrequency = TONE_MIN_FREQUENCY_HZ; + if (newFrequency > TONE_MAX_FREQUENCY_HZ) newFrequency = TONE_MAX_FREQUENCY_HZ; + + // go through the prescalers possible values ​to find the appropriate one. + // prescaler is set to a value from 0 to 7 + uint32_t tempPeriod; + for (uint8_t prescaler = 0; prescaler < PRESCALERS_QTY; prescaler++) + { + // timer frequency is 2 times greater than the required signal frequency + tempPeriod = F_CPU / ((1 << prescaler) * 2 * newFrequency); + if (tempPeriod <= UINT16_MAX) + { + // if period is suitable save the current prescaler and period + params->frequency = newFrequency; + params->prescaler = prescaler; + params->period_ticks = tempPeriod; + break; + } + } +} + +// start tone with frequency (in hertz) and duration (in milliseconds) +void tone(uint8_t pin, unsigned int frequency, unsigned long duration) +{ + if (!timerIsOn) // if tone is not generated at the moment + { + // calculate the parameters necessary to ensure a given frequency if the frequency has changed + if (frequencyParams.frequency != frequency) + calcFrequencyParams(&frequencyParams, frequency); + + // Calculate the toggle count + if (duration > 0) + timer_toggle_count = (duration * (F_CPU/(frequencyParams.period_ticks*(1<CLEAR = timer_pin_mask; + + HAL_Timer16_Counter_Start_IT(&htimer16_1, frequencyParams.period_ticks); + timerIsOn = true; + } + // if tone is generated, but the same pin that works now is specified + else if (timerIsOn && (pin == timer_pin)) + { + // change frequency if necessary + if (frequency != frequencyParams.frequency) + { + calcFrequencyParams(&frequencyParams, frequency); + htimer16_1.Clock.Prescaler = frequencyParams.prescaler; // update value in common structure + HAL_Timer16_SetPrescaler(&htimer16_1, frequencyParams.prescaler); // the timer is turned off inside the function + HAL_Timer16_Counter_Start_IT(&htimer16_1, frequencyParams.period_ticks); // start with a new period + } + } +} + +// stop tone +void noTone(uint8_t pin) +{ + if (timerIsOn) + { + timer_pin_port->CLEAR = timer_pin_mask; // pin to 0 + htimer16_1.Instance->CR &= ~TIMER16_CR_ENABLE_M; // disable timer + HAL_EPIC_MaskLevelClear(HAL_EPIC_TIMER16_1_MASK); + pinMode(pin, INPUT); // deinit pin + timer_pin = -1; // reset to default + timerIsOn = false; + } +} + +// irq handler +extern "C" void tone_interrupt_handler(void) +{ + if ((htimer16_1.Instance->ISR & htimer16_1.Instance->IER) & TIMER16_ISR_ARR_MATCH_M) + { + // timer period has passed, change the pin state + if (timer_toggle_count != 0) + { + timer_pin_port->OUTPUT_ ^= timer_pin_mask; + + if (timer_toggle_count > 0) + timer_toggle_count--; + } + else + { + // turn off if the specified duration has passed + timer_pin_port->CLEAR = timer_pin_mask; + noTone(timer_pin); + } + } + // reset timer interrupt flags + htimer16_1.Instance->ICR = 0xFFFFFFFF; +} \ No newline at end of file diff --git a/cores/arduino/Tone.h b/cores/arduino/Tone.h new file mode 100644 index 0000000..b9175b2 --- /dev/null +++ b/cores/arduino/Tone.h @@ -0,0 +1,23 @@ +#ifndef _TONE_H_ +#define _TONE_H_ + +#include "stdint.h" + +#define TONE_MIN_FREQUENCY_HZ 4 +#define TONE_MAX_FREQUENCY_HZ 40000 + +/* +* \brief +* Start tone on specified pin with frequency in range +* TONE_MIN_FREQUENCY_HZ...TONE_MAX_FREQUENCY_HZ. +* If duration = 0, tone won't stop until noTone() has called +*/ +void tone(uint8_t pin, unsigned int frequency, unsigned long duration = 0); + +/* +* \brief +* Stop tone on specified pin +*/ +void noTone(uint8_t pin); + +#endif /* _TONE_H_ */ diff --git a/cores/arduino/WCharacter.h b/cores/arduino/WCharacter.h new file mode 100644 index 0000000..4ce89ee --- /dev/null +++ b/cores/arduino/WCharacter.h @@ -0,0 +1,168 @@ +/* + WCharacter.h - Character utility functions for Wiring & Arduino + Copyright (c) 2010 Hernando Barragan. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef Character_h +#define Character_h + +#include + +// WCharacter.h prototypes +inline bool isAlphaNumeric(int c) __attribute__((always_inline)); +inline bool isAlpha(int c) __attribute__((always_inline)); +inline bool isAscii(int c) __attribute__((always_inline)); +inline bool isWhitespace(int c) __attribute__((always_inline)); +inline bool isControl(int c) __attribute__((always_inline)); +inline bool isDigit(int c) __attribute__((always_inline)); +inline bool isGraph(int c) __attribute__((always_inline)); +inline bool isLowerCase(int c) __attribute__((always_inline)); +inline bool isPrintable(int c) __attribute__((always_inline)); +inline bool isPunct(int c) __attribute__((always_inline)); +inline bool isSpace(int c) __attribute__((always_inline)); +inline bool isUpperCase(int c) __attribute__((always_inline)); +inline bool isHexadecimalDigit(int c) __attribute__((always_inline)); +inline int toAscii(int c) __attribute__((always_inline)); +inline int toLowerCase(int c) __attribute__((always_inline)); +inline int toUpperCase(int c)__attribute__((always_inline)); + + +// Checks for an alphanumeric character. +// It is equivalent to (isalpha(c) || isdigit(c)). +inline bool isAlphaNumeric(int c) +{ + return ( isalnum(c) == 0 ? false : true); +} + + +// Checks for an alphabetic character. +// It is equivalent to (isupper(c) || islower(c)). +inline bool isAlpha(int c) +{ + return ( isalpha(c) == 0 ? false : true); +} + + +// Checks whether c is a 7-bit unsigned char value +// that fits into the ASCII character set. +inline bool isAscii(int c) +{ + return ( isascii (c) == 0 ? false : true); +} + + +// Checks for a blank character, that is, a space or a tab. +inline bool isWhitespace(int c) +{ + return ( isblank (c) == 0 ? false : true); +} + + +// Checks for a control character. +inline bool isControl(int c) +{ + return ( iscntrl (c) == 0 ? false : true); +} + + +// Checks for a digit (0 through 9). +inline bool isDigit(int c) +{ + return ( isdigit (c) == 0 ? false : true); +} + + +// Checks for any printable character except space. +inline bool isGraph(int c) +{ + return ( isgraph (c) == 0 ? false : true); +} + + +// Checks for a lower-case character. +inline bool isLowerCase(int c) +{ + return (islower (c) == 0 ? false : true); +} + + +// Checks for any printable character including space. +inline bool isPrintable(int c) +{ + return ( isprint (c) == 0 ? false : true); +} + + +// Checks for any printable character which is not a space +// or an alphanumeric character. +inline bool isPunct(int c) +{ + return ( ispunct (c) == 0 ? false : true); +} + + +// Checks for white-space characters. For the avr-libc library, +// these are: space, formfeed ('\f'), newline ('\n'), carriage +// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). +inline bool isSpace(int c) +{ + return ( isspace (c) == 0 ? false : true); +} + + +// Checks for an uppercase letter. +inline bool isUpperCase(int c) +{ + return ( isupper (c) == 0 ? false : true); +} + + +// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 +// 8 9 a b c d e f A B C D E F. +inline bool isHexadecimalDigit(int c) +{ + return ( isxdigit (c) == 0 ? false : true); +} + + +// Converts c to a 7-bit unsigned char value that fits into the +// ASCII character set, by clearing the high-order bits. +inline int toAscii(int c) +{ + return toascii (c); +} + + +// Warning: +// Many people will be unhappy if you use this function. +// This function will convert accented letters into random +// characters. + +// Converts the letter c to lower case, if possible. +inline int toLowerCase(int c) +{ + return tolower (c); +} + + +// Converts the letter c to upper case, if possible. +inline int toUpperCase(int c) +{ + return toupper (c); +} + +#endif \ No newline at end of file diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c new file mode 100644 index 0000000..d69071f --- /dev/null +++ b/cores/arduino/WInterrupts.c @@ -0,0 +1,132 @@ +#include +#include "mik32_hal_irq.h" + +#include "pins_arduino.h" +#include "wiring_digital.h" +#include "WInterrupts.h" + +extern void ErrorMsgHandler(const char * msg); + +typedef void (*voidFuncPtr)(void); + +// empty irq handler +static void nothing(void) +{ + ; +} + +// enable global interrupts +void interrupts(void) +{ + HAL_IRQ_EnableInterrupts(); +} + +// disable global interrupts +void noInterrupts(void) +{ + HAL_IRQ_DisableInterrupts(); +} + +// we can provide no more than 8 interrupts on gpio at the same time +static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS] = +{ +#if EXTERNAL_NUM_INTERRUPTS > 7 + nothing, +#endif +#if EXTERNAL_NUM_INTERRUPTS > 6 + nothing, +#endif +#if EXTERNAL_NUM_INTERRUPTS > 5 + nothing, +#endif +#if EXTERNAL_NUM_INTERRUPTS > 4 + nothing, +#endif +#if EXTERNAL_NUM_INTERRUPTS > 3 + nothing, +#endif +#if EXTERNAL_NUM_INTERRUPTS > 2 + nothing, +#endif + nothing, + nothing, +}; + +void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) +{ + // if the interrupt number does not exceed the total number + if(interruptNum < EXTERNAL_NUM_INTERRUPTS) + { + intFunc[interruptNum] = userFunc; // save pointer to irq handler + + // init pin as input without pullups + pinMode(interruptToDigitalPin(interruptNum), INPUT); + + // interrupt line initialization + HAL_GPIO_InterruptMode halMode; + if (mode == LOW) halMode = GPIO_INT_MODE_LOW; + else if (mode == HIGH) halMode = GPIO_INT_MODE_HIGH; + else if (mode == CHANGE) halMode = GPIO_INT_MODE_CHANGE; + else if (mode == FALLING) halMode = GPIO_INT_MODE_FALLING; + else if (mode == RISING) halMode = GPIO_INT_MODE_RISING; + else return; + HAL_GPIO_InitInterruptLine(interruptToGpioIntMux(interruptNum), halMode); + + // turn on the mask in EPIC + if ((halMode == GPIO_INT_MODE_LOW) || (halMode == GPIO_INT_MODE_HIGH)) + // by level + HAL_EPIC_MaskLevelSet(HAL_EPIC_GPIO_IRQ_MASK); + else + // by edge + HAL_EPIC_MaskEdgeSet(HAL_EPIC_GPIO_IRQ_MASK); + } + else + ErrorMsgHandler("attachInterrupt(): incorrect interrupt number\n\r"); +} + +void detachInterrupt(uint8_t interruptNum) +{ + if(interruptNum < EXTERNAL_NUM_INTERRUPTS) + { + // disable the interrupt in line + HAL_GPIO_DeInitInterruptLine(interruptToGpioIntLine(interruptNum)); + intFunc[interruptNum] = nothing; + + // we don't change anything in the EPIC controller, in case there are still configured lines left + } +} + +// disable single interrupt +void disableInterrupt(uint8_t interruptNum) +{ + if(interruptNum < EXTERNAL_NUM_INTERRUPTS) + { + int irq_line_num = interruptToGpioIntLine(interruptNum) >> GPIO_IRQ_LINE_S; + // disable gpio interrupt line + GPIO_IRQ->ENABLE_CLEAR = (1 << irq_line_num); + } +} + +// enable single interrupt +void enableInterrupt(uint8_t interruptNum) +{ + if(interruptNum < EXTERNAL_NUM_INTERRUPTS) + { + int irq_line_num = interruptToGpioIntLine(interruptNum) >> GPIO_IRQ_LINE_S; + // enable gpio interrupt line + GPIO_IRQ->ENABLE_SET = (1 << irq_line_num); + } +} + +// common gpio interrupt handler +void gpio_interrupts_handler(void) +{ + // go through all the interrupts and call the handler for the triggered line + for (uint8_t i = 0; i < EXTERNAL_NUM_INTERRUPTS; i++) + { + if (HAL_GPIO_LineInterruptState(interruptToGpioIntLine(i))) + intFunc[i](); + } + + HAL_GPIO_ClearInterrupts(); +} \ No newline at end of file diff --git a/cores/arduino/WInterrupts.h b/cores/arduino/WInterrupts.h new file mode 100644 index 0000000..4bab44e --- /dev/null +++ b/cores/arduino/WInterrupts.h @@ -0,0 +1,26 @@ +#ifndef _WIRING_INTERRUPTS_ +#define _WIRING_INTERRUPTS_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +// enable/disable interrupts +void interrupts(void); +void noInterrupts(void); + +// attach/detach interrupt to pin +void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode); +void detachInterrupt(uint8_t interruptNum); + +// enable/disable single external interrupt by it's number +void disableInterrupt(uint8_t interruptNum); +void enableInterrupt(uint8_t interruptNum); + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_INTERRUPTS_ */ diff --git a/cores/arduino/WMath.cpp b/cores/arduino/WMath.cpp new file mode 100644 index 0000000..8cdb3dc --- /dev/null +++ b/cores/arduino/WMath.cpp @@ -0,0 +1,65 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +extern "C" { +#include "stdlib.h" +#include "stdint.h" +} +#include "WMath.h" + +void randomSeed(uint32_t dwSeed) +{ + if (dwSeed != 0) { + srand(dwSeed) ; + } +} + +long random(long howbig) +{ + if (howbig == 0) { + return 0 ; + } + + return rand() % howbig; +} + +long random(long howsmall, long howbig) +{ + if (howsmall >= howbig) { + return howsmall; + } + + long diff = howbig - howsmall; + + return random(diff) + howsmall; +} + +long map(long x, long in_min, long in_max, long out_min, long out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +uint16_t makeWord(uint16_t w) +{ + return w ; +} + +uint16_t makeWord(uint8_t h, uint8_t l) +{ + return (h << 8) | l ; +} diff --git a/cores/arduino/WMath.h b/cores/arduino/WMath.h new file mode 100644 index 0000000..ceea081 --- /dev/null +++ b/cores/arduino/WMath.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_MATH_ +#define _WIRING_MATH_ + +long random(long); +long random(long, long); +void randomSeed(uint32_t dwSeed); +long map(long, long, long, long, long); + +uint16_t makeWord(uint16_t w); +uint16_t makeWord(uint8_t h, uint8_t l); + +#define word(...) makeWord(__VA_ARGS__) + + +#endif /* _WIRING_MATH_ */ diff --git a/cores/arduino/WString.cpp b/cores/arduino/WString.cpp new file mode 100644 index 0000000..eb17895 --- /dev/null +++ b/cores/arduino/WString.cpp @@ -0,0 +1,751 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "WString.h" +#include "itoa.h" + +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) +{ + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const String &value) +{ + init(); + *this = value; +} + +String::String(const __FlashStringHelper *pstr) +{ + init(); + *this = pstr; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String::String(String &&rval) +{ + init(); + move(rval); +} +String::String(StringSumHelper &&rval) +{ + init(); + move(rval); +} +#endif + +String::String(char c) +{ + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +String::String(unsigned char value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned char)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(int value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned int)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(long value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(float value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::String(double value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::~String() +{ + if (buffer) free(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) +{ + buffer = NULL; + capacity = 0; + len = 0; +} + +void String::invalidate(void) +{ + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; +} + +unsigned char String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +unsigned char String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; +} + +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy_P(buffer, (PGM_P)pstr); + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +void String::move(String &rhs) +{ + if (buffer) { + if (rhs && capacity >= rhs.len) { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } else { + free(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String & String::operator = (String &&rval) +{ + if (this != &rval) move(rval); + return *this; +} + +String & String::operator = (StringSumHelper &&rval) +{ + if (this != &rval) move(rval); + return *this; +} +#endif + +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +String & String::operator = (const __FlashStringHelper *pstr) +{ + if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +unsigned char String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +unsigned char String::concat(const char *cstr, unsigned int length) +{ + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +unsigned char String::concat(const char *cstr) +{ + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +unsigned char String::concat(char c) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +unsigned char String::concat(unsigned char num) +{ + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(int num) +{ + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned int num) +{ + char buf[1 + 3 * sizeof(unsigned int)]; + utoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(long num) +{ + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned long num) +{ + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(float num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(double num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(const __FlashStringHelper * str) +{ + if (!str) return 0; + int length = strlen_P((const char *) str); + if (length == 0) return 1; + unsigned int newlen = len + length; + if (!reserve(newlen)) return 0; + strcpy_P(buffer + len, (const char *) str); + len = newlen; + return 1; +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, float num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, double num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +unsigned char String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +unsigned char String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +unsigned char String::operator<(const String &rhs) const +{ + return compareTo(rhs) < 0; +} + +unsigned char String::operator>(const String &rhs) const +{ + return compareTo(rhs) > 0; +} + +unsigned char String::operator<=(const String &rhs) const +{ + return compareTo(rhs) <= 0; +} + +unsigned char String::operator>=(const String &rhs) const +{ + return compareTo(rhs) >= 0; +} + +unsigned char String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +unsigned char String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +unsigned char String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +unsigned char String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left >= len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char replace) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = replace; + } +} + +void String::replace(const String& find, const String& replace) +{ + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + if (diff == 0) { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } else if (diff < 0) { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } else { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } +} + +void String::remove(unsigned int index){ + // Pass the biggest integer as the count. The remove method + // below will take care of truncating it at the end of the + // string. + remove(index, (unsigned int)-1); +} + +void String::remove(unsigned int index, unsigned int count){ + if (index >= len) { return; } + if (count <= 0) { return; } + if (count > len - index) { count = len - index; } + char *writeTo = buffer + index; + len = len - count; + strncpy(writeTo, buffer + index + count,len - index); + buffer[len] = 0; +} + +void String::toLowerCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } +} + +void String::trim(void) +{ + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memcpy(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + +float String::toFloat(void) const +{ + return float(toDouble()); +} + +double String::toDouble(void) const +{ + if (buffer) return atof(buffer); + return 0; +} diff --git a/cores/arduino/WString.h b/cores/arduino/WString.h new file mode 100644 index 0000000..db98095 --- /dev/null +++ b/cores/arduino/WString.h @@ -0,0 +1,230 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef String_class_h +#define String_class_h +#ifdef __cplusplus + +#include +#include +#include +#include +#include + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const String &str); + String(const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String(String &&rval); + String(StringSumHelper &&rval); + #endif + explicit String(char c); + explicit String(unsigned char, unsigned char base=10); + explicit String(int, unsigned char base=10); + explicit String(unsigned int, unsigned char base=10); + explicit String(long, unsigned char base=10); + explicit String(unsigned long, unsigned char base=10); + explicit String(float, unsigned char decimalPlaces=2); + explicit String(double, unsigned char decimalPlaces=2); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + inline unsigned int length(void) const {return len;} + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); + #endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsuccessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) {concat(rhs); return (*this);} + String & operator += (const char *cstr) {concat(cstr); return (*this);} + String & operator += (char c) {concat(c); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (int num) {concat(num); return (*this);} + String & operator += (unsigned int num) {concat(num); return (*this);} + String & operator += (long num) {concat(num); return (*this);} + String & operator += (unsigned long num) {concat(num); return (*this);} + String & operator += (float num) {concat(num); return (*this);} + String & operator += (double num) {concat(num); return (*this);} + String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const {return equals(rhs);} + unsigned char operator == (const char *cstr) const {return equals(cstr);} + unsigned char operator != (const String &rhs) const {return !equals(rhs);} + unsigned char operator != (const char *cstr) const {return !equals(cstr);} + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character access + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const + { getBytes((unsigned char *)buf, bufsize, index); } + const char* c_str() const { return buffer; } + char* begin() { return buffer; } + char* end() { return buffer + length(); } + const char* begin() const { return c_str(); } + const char* end() const { return c_str() + length(); } + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void remove(unsigned int index); + void remove(unsigned int index, unsigned int count); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + float toFloat(void) const; + double toDouble(void) const; + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') +protected: + void init(void); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + void move(String &rhs); + #endif +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h diff --git a/cores/arduino/abi.cpp b/cores/arduino/abi.cpp new file mode 100644 index 0000000..6e1b0f8 --- /dev/null +++ b/cores/arduino/abi.cpp @@ -0,0 +1,36 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); +extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); + +namespace std { + [[gnu::weak, noreturn]] void terminate() { + abort(); + } +} + +void __cxa_pure_virtual(void) { + std::terminate(); +} + +void __cxa_deleted_virtual(void) { + std::terminate(); +} diff --git a/cores/arduino/avr/dtostrf.c b/cores/arduino/avr/dtostrf.c new file mode 100644 index 0000000..7b0a2fe --- /dev/null +++ b/cores/arduino/avr/dtostrf.c @@ -0,0 +1,91 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2013 Arduino. All rights reserved. + Written by Cristian Maglie + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include + +char *dtostrf (double val, signed char width, unsigned char prec, char *sout) { + //Commented code is the original version + /*char fmt[20]; + sprintf(fmt, "%%%d.%df", width, prec); + sprintf(sout, fmt, val); + return sout;*/ + + // Handle negative numbers + unsigned int negative = 0; + if (val < 0.0) + { + negative = 1; + val = -val; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (int i=0; i + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef __DTOSTRF_H_ +#define __DTOSTRF_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +char *dtostrf (double val, signed char width, unsigned char prec, char *sout); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cores/arduino/avr/pgmspace.h b/cores/arduino/avr/pgmspace.h new file mode 100644 index 0000000..511a32a --- /dev/null +++ b/cores/arduino/avr/pgmspace.h @@ -0,0 +1,130 @@ +/* Simple compatibility headers for AVR code used with ARM chips + * Copyright (c) 2015 Paul Stoffregen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __PGMSPACE_H_ +#define __PGMSPACE_H_ 1 + +#include + +#define PROGMEM +#define PGM_P const char * +#define PSTR(str) (str) + +#define _SFR_BYTE(n) (n) + +typedef void prog_void; +typedef char prog_char; +typedef unsigned char prog_uchar; +typedef int8_t prog_int8_t; +typedef uint8_t prog_uint8_t; +typedef int16_t prog_int16_t; +typedef uint16_t prog_uint16_t; +typedef int32_t prog_int32_t; +typedef uint32_t prog_uint32_t; +typedef int64_t prog_int64_t; +typedef uint64_t prog_uint64_t; + +#define memchr_P(str, c, len) memchr((str), (c), (len)) +#define memcmp_P(a, b, n) memcmp((a), (b), (n)) +#define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) +#define memmem_P(a, alen, b, blen) memmem((a), (alen), (b), (blen)) +#define memrchr_P(str, val, len) memrchr((str), (val), (len)) +#define strcat_P(dest, src) strcat((dest), (src)) +#define strchr_P(str, c) strchr((str), (c)) +#define strchrnul_P(str, c) strchrnul((str), (c)) +#define strcmp_P(a, b) strcmp((a), (b)) +#define strcpy_P(dest, src) strcpy((dest), (src)) +#define strcasecmp_P(a, b) strcasecmp((a), (b)) +#define strcasestr_P(a, b) strcasestr((a), (b)) +#define strlcat_P(dest, src, len) strlcat((dest), (src), (len)) +#define strlcpy_P(dest, src, len) strlcpy((dest), (src), (len)) +#define strlen_P(s) strlen((const char *)(s)) +#define strnlen_P(str, len) strnlen((str), (len)) +#define strncmp_P(a, b, n) strncmp((a), (b), (n)) +#define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n)) +#define strncat_P(a, b, n) strncat((a), (b), (n)) +#define strncpy_P(a, b, n) strncpy((a), (b), (n)) +#define strpbrk_P(str, chrs) strpbrk((str), (chrs)) +#define strrchr_P(str, c) strrchr((str), (c)) +#define strsep_P(strp, delim) strsep((strp), (delim)) +#define strspn_P(str, chrs) strspn((str), (chrs)) +#define strstr_P(a, b) strstr((a), (b)) +#define sprintf_P(s, ...) sprintf((s), __VA_ARGS__) +#define vfprintf_P(fp, s, ...) vfprintf((fp), (s), __VA_ARGS__) +#define printf_P(...) printf(__VA_ARGS__) +#define snprintf_P(s, n, ...) snprintf((s), (n), __VA_ARGS__) +#define vsprintf_P(s, ...) vsprintf((s), __VA_ARGS__) +#define vsnprintf_P(s, n, ...) vsnprintf((s), (n), __VA_ARGS__) +#define fprintf_P(fp, ...) fprintf((fp), __VA_ARGS__) +#define strlen_PF(a) strlen((a)) +#define strnlen_PF(src, len) strnlen((src), (len)) +#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len)) +#define strcpy_PF(dest, src) strcpy((dest), (src)) +#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len)) +#define strcat_PF(dest, src) strcat((dest), (src)) +#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len)) +#define strncat_PF(dest, src, len) strncat((dest), (src), (len)) +#define strcmp_PF(s1, s2) strcmp((s1), (s2)) +#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n)) +#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2)) +#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n)) +#define strstr_PF(s1, s2) strstr((s1), (s2)) +#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n)) +#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n)) + + +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#if 0 +#define pgm_read_word(addr) (*(const unsigned short *)(addr)) +#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#define pgm_read_float(addr) (*(const float *)(addr)) +#else +#define pgm_read_word(addr) ({ \ + typeof(addr) _addr = (addr); \ + *(const unsigned short *)(_addr); \ +}) +#define pgm_read_dword(addr) ({ \ + typeof(addr) _addr = (addr); \ + *(const unsigned long *)(_addr); \ +}) +#define pgm_read_float(addr) ({ \ + typeof(addr) _addr = (addr); \ + *(const float *)(_addr); \ +}) +#define pgm_read_ptr(addr) ({ \ + typeof(addr) _addr = (addr); \ + *(void * const *)(_addr); \ +}) +#endif + +#define pgm_read_byte_near(addr) pgm_read_byte(addr) +#define pgm_read_word_near(addr) pgm_read_word(addr) +#define pgm_read_dword_near(addr) pgm_read_dword(addr) +#define pgm_read_float_near(addr) pgm_read_float(addr) +#define pgm_read_ptr_near(addr) pgm_read_ptr(addr) +#define pgm_read_byte_far(addr) pgm_read_byte(addr) +#define pgm_read_word_far(addr) pgm_read_word(addr) +#define pgm_read_dword_far(addr) pgm_read_dword(addr) +#define pgm_read_float_far(addr) pgm_read_float(addr) +#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) + +#endif diff --git a/cores/arduino/binary.h b/cores/arduino/binary.h new file mode 100644 index 0000000..f40f952 --- /dev/null +++ b/cores/arduino/binary.h @@ -0,0 +1,541 @@ +/* + binary.h - Definitions for binary constants + Copyright (c) 2006 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Binary_h +#define Binary_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define B0 0 +#define B00 0 +#define B000 0 +#define B0000 0 +#define B00000 0 +#define B000000 0 +#define B0000000 0 +#define B00000000 0 +#define B1 1 +#define B01 1 +#define B001 1 +#define B0001 1 +#define B00001 1 +#define B000001 1 +#define B0000001 1 +#define B00000001 1 +#define B10 2 +#define B010 2 +#define B0010 2 +#define B00010 2 +#define B000010 2 +#define B0000010 2 +#define B00000010 2 +#define B11 3 +#define B011 3 +#define B0011 3 +#define B00011 3 +#define B000011 3 +#define B0000011 3 +#define B00000011 3 +#define B100 4 +#define B0100 4 +#define B00100 4 +#define B000100 4 +#define B0000100 4 +#define B00000100 4 +#define B101 5 +#define B0101 5 +#define B00101 5 +#define B000101 5 +#define B0000101 5 +#define B00000101 5 +#define B110 6 +#define B0110 6 +#define B00110 6 +#define B000110 6 +#define B0000110 6 +#define B00000110 6 +#define B111 7 +#define B0111 7 +#define B00111 7 +#define B000111 7 +#define B0000111 7 +#define B00000111 7 +#define B1000 8 +#define B01000 8 +#define B001000 8 +#define B0001000 8 +#define B00001000 8 +#define B1001 9 +#define B01001 9 +#define B001001 9 +#define B0001001 9 +#define B00001001 9 +#define B1010 10 +#define B01010 10 +#define B001010 10 +#define B0001010 10 +#define B00001010 10 +#define B1011 11 +#define B01011 11 +#define B001011 11 +#define B0001011 11 +#define B00001011 11 +#define B1100 12 +#define B01100 12 +#define B001100 12 +#define B0001100 12 +#define B00001100 12 +#define B1101 13 +#define B01101 13 +#define B001101 13 +#define B0001101 13 +#define B00001101 13 +#define B1110 14 +#define B01110 14 +#define B001110 14 +#define B0001110 14 +#define B00001110 14 +#define B1111 15 +#define B01111 15 +#define B001111 15 +#define B0001111 15 +#define B00001111 15 +#define B10000 16 +#define B010000 16 +#define B0010000 16 +#define B00010000 16 +#define B10001 17 +#define B010001 17 +#define B0010001 17 +#define B00010001 17 +#define B10010 18 +#define B010010 18 +#define B0010010 18 +#define B00010010 18 +#define B10011 19 +#define B010011 19 +#define B0010011 19 +#define B00010011 19 +#define B10100 20 +#define B010100 20 +#define B0010100 20 +#define B00010100 20 +#define B10101 21 +#define B010101 21 +#define B0010101 21 +#define B00010101 21 +#define B10110 22 +#define B010110 22 +#define B0010110 22 +#define B00010110 22 +#define B10111 23 +#define B010111 23 +#define B0010111 23 +#define B00010111 23 +#define B11000 24 +#define B011000 24 +#define B0011000 24 +#define B00011000 24 +#define B11001 25 +#define B011001 25 +#define B0011001 25 +#define B00011001 25 +#define B11010 26 +#define B011010 26 +#define B0011010 26 +#define B00011010 26 +#define B11011 27 +#define B011011 27 +#define B0011011 27 +#define B00011011 27 +#define B11100 28 +#define B011100 28 +#define B0011100 28 +#define B00011100 28 +#define B11101 29 +#define B011101 29 +#define B0011101 29 +#define B00011101 29 +#define B11110 30 +#define B011110 30 +#define B0011110 30 +#define B00011110 30 +#define B11111 31 +#define B011111 31 +#define B0011111 31 +#define B00011111 31 +#define B100000 32 +#define B0100000 32 +#define B00100000 32 +#define B100001 33 +#define B0100001 33 +#define B00100001 33 +#define B100010 34 +#define B0100010 34 +#define B00100010 34 +#define B100011 35 +#define B0100011 35 +#define B00100011 35 +#define B100100 36 +#define B0100100 36 +#define B00100100 36 +#define B100101 37 +#define B0100101 37 +#define B00100101 37 +#define B100110 38 +#define B0100110 38 +#define B00100110 38 +#define B100111 39 +#define B0100111 39 +#define B00100111 39 +#define B101000 40 +#define B0101000 40 +#define B00101000 40 +#define B101001 41 +#define B0101001 41 +#define B00101001 41 +#define B101010 42 +#define B0101010 42 +#define B00101010 42 +#define B101011 43 +#define B0101011 43 +#define B00101011 43 +#define B101100 44 +#define B0101100 44 +#define B00101100 44 +#define B101101 45 +#define B0101101 45 +#define B00101101 45 +#define B101110 46 +#define B0101110 46 +#define B00101110 46 +#define B101111 47 +#define B0101111 47 +#define B00101111 47 +#define B110000 48 +#define B0110000 48 +#define B00110000 48 +#define B110001 49 +#define B0110001 49 +#define B00110001 49 +#define B110010 50 +#define B0110010 50 +#define B00110010 50 +#define B110011 51 +#define B0110011 51 +#define B00110011 51 +#define B110100 52 +#define B0110100 52 +#define B00110100 52 +#define B110101 53 +#define B0110101 53 +#define B00110101 53 +#define B110110 54 +#define B0110110 54 +#define B00110110 54 +#define B110111 55 +#define B0110111 55 +#define B00110111 55 +#define B111000 56 +#define B0111000 56 +#define B00111000 56 +#define B111001 57 +#define B0111001 57 +#define B00111001 57 +#define B111010 58 +#define B0111010 58 +#define B00111010 58 +#define B111011 59 +#define B0111011 59 +#define B00111011 59 +#define B111100 60 +#define B0111100 60 +#define B00111100 60 +#define B111101 61 +#define B0111101 61 +#define B00111101 61 +#define B111110 62 +#define B0111110 62 +#define B00111110 62 +#define B111111 63 +#define B0111111 63 +#define B00111111 63 +#define B1000000 64 +#define B01000000 64 +#define B1000001 65 +#define B01000001 65 +#define B1000010 66 +#define B01000010 66 +#define B1000011 67 +#define B01000011 67 +#define B1000100 68 +#define B01000100 68 +#define B1000101 69 +#define B01000101 69 +#define B1000110 70 +#define B01000110 70 +#define B1000111 71 +#define B01000111 71 +#define B1001000 72 +#define B01001000 72 +#define B1001001 73 +#define B01001001 73 +#define B1001010 74 +#define B01001010 74 +#define B1001011 75 +#define B01001011 75 +#define B1001100 76 +#define B01001100 76 +#define B1001101 77 +#define B01001101 77 +#define B1001110 78 +#define B01001110 78 +#define B1001111 79 +#define B01001111 79 +#define B1010000 80 +#define B01010000 80 +#define B1010001 81 +#define B01010001 81 +#define B1010010 82 +#define B01010010 82 +#define B1010011 83 +#define B01010011 83 +#define B1010100 84 +#define B01010100 84 +#define B1010101 85 +#define B01010101 85 +#define B1010110 86 +#define B01010110 86 +#define B1010111 87 +#define B01010111 87 +#define B1011000 88 +#define B01011000 88 +#define B1011001 89 +#define B01011001 89 +#define B1011010 90 +#define B01011010 90 +#define B1011011 91 +#define B01011011 91 +#define B1011100 92 +#define B01011100 92 +#define B1011101 93 +#define B01011101 93 +#define B1011110 94 +#define B01011110 94 +#define B1011111 95 +#define B01011111 95 +#define B1100000 96 +#define B01100000 96 +#define B1100001 97 +#define B01100001 97 +#define B1100010 98 +#define B01100010 98 +#define B1100011 99 +#define B01100011 99 +#define B1100100 100 +#define B01100100 100 +#define B1100101 101 +#define B01100101 101 +#define B1100110 102 +#define B01100110 102 +#define B1100111 103 +#define B01100111 103 +#define B1101000 104 +#define B01101000 104 +#define B1101001 105 +#define B01101001 105 +#define B1101010 106 +#define B01101010 106 +#define B1101011 107 +#define B01101011 107 +#define B1101100 108 +#define B01101100 108 +#define B1101101 109 +#define B01101101 109 +#define B1101110 110 +#define B01101110 110 +#define B1101111 111 +#define B01101111 111 +#define B1110000 112 +#define B01110000 112 +#define B1110001 113 +#define B01110001 113 +#define B1110010 114 +#define B01110010 114 +#define B1110011 115 +#define B01110011 115 +#define B1110100 116 +#define B01110100 116 +#define B1110101 117 +#define B01110101 117 +#define B1110110 118 +#define B01110110 118 +#define B1110111 119 +#define B01110111 119 +#define B1111000 120 +#define B01111000 120 +#define B1111001 121 +#define B01111001 121 +#define B1111010 122 +#define B01111010 122 +#define B1111011 123 +#define B01111011 123 +#define B1111100 124 +#define B01111100 124 +#define B1111101 125 +#define B01111101 125 +#define B1111110 126 +#define B01111110 126 +#define B1111111 127 +#define B01111111 127 +#define B10000000 128 +#define B10000001 129 +#define B10000010 130 +#define B10000011 131 +#define B10000100 132 +#define B10000101 133 +#define B10000110 134 +#define B10000111 135 +#define B10001000 136 +#define B10001001 137 +#define B10001010 138 +#define B10001011 139 +#define B10001100 140 +#define B10001101 141 +#define B10001110 142 +#define B10001111 143 +#define B10010000 144 +#define B10010001 145 +#define B10010010 146 +#define B10010011 147 +#define B10010100 148 +#define B10010101 149 +#define B10010110 150 +#define B10010111 151 +#define B10011000 152 +#define B10011001 153 +#define B10011010 154 +#define B10011011 155 +#define B10011100 156 +#define B10011101 157 +#define B10011110 158 +#define B10011111 159 +#define B10100000 160 +#define B10100001 161 +#define B10100010 162 +#define B10100011 163 +#define B10100100 164 +#define B10100101 165 +#define B10100110 166 +#define B10100111 167 +#define B10101000 168 +#define B10101001 169 +#define B10101010 170 +#define B10101011 171 +#define B10101100 172 +#define B10101101 173 +#define B10101110 174 +#define B10101111 175 +#define B10110000 176 +#define B10110001 177 +#define B10110010 178 +#define B10110011 179 +#define B10110100 180 +#define B10110101 181 +#define B10110110 182 +#define B10110111 183 +#define B10111000 184 +#define B10111001 185 +#define B10111010 186 +#define B10111011 187 +#define B10111100 188 +#define B10111101 189 +#define B10111110 190 +#define B10111111 191 +#define B11000000 192 +#define B11000001 193 +#define B11000010 194 +#define B11000011 195 +#define B11000100 196 +#define B11000101 197 +#define B11000110 198 +#define B11000111 199 +#define B11001000 200 +#define B11001001 201 +#define B11001010 202 +#define B11001011 203 +#define B11001100 204 +#define B11001101 205 +#define B11001110 206 +#define B11001111 207 +#define B11010000 208 +#define B11010001 209 +#define B11010010 210 +#define B11010011 211 +#define B11010100 212 +#define B11010101 213 +#define B11010110 214 +#define B11010111 215 +#define B11011000 216 +#define B11011001 217 +#define B11011010 218 +#define B11011011 219 +#define B11011100 220 +#define B11011101 221 +#define B11011110 222 +#define B11011111 223 +#define B11100000 224 +#define B11100001 225 +#define B11100010 226 +#define B11100011 227 +#define B11100100 228 +#define B11100101 229 +#define B11100110 230 +#define B11100111 231 +#define B11101000 232 +#define B11101001 233 +#define B11101010 234 +#define B11101011 235 +#define B11101100 236 +#define B11101101 237 +#define B11101110 238 +#define B11101111 239 +#define B11110000 240 +#define B11110001 241 +#define B11110010 242 +#define B11110011 243 +#define B11110100 244 +#define B11110101 245 +#define B11110110 246 +#define B11110111 247 +#define B11111000 248 +#define B11111001 249 +#define B11111010 250 +#define B11111011 251 +#define B11111100 252 +#define B11111101 253 +#define B11111110 254 +#define B11111111 255 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cores/arduino/board.cpp b/cores/arduino/board.cpp new file mode 100644 index 0000000..bf1dc01 --- /dev/null +++ b/cores/arduino/board.cpp @@ -0,0 +1,36 @@ +#include "board.h" +#include "mik32_hal_pcc.h" +#include "Arduino.h" + +// --------------------- init --------------------- // +// called before setup() +void pre_init(void) +{ + HAL_Init(); + + // gpio clock + __HAL_PCC_GPIO_0_CLK_ENABLE(); + __HAL_PCC_GPIO_1_CLK_ENABLE(); + __HAL_PCC_GPIO_2_CLK_ENABLE(); + __HAL_PCC_GPIO_IRQ_CLK_ENABLE(); + + // for delays + SysTick_Init(); +} + +// called after setup() +void post_init(void) +{ + // enable global interrupts by default + interrupts(); +} + +// --------------------- other --------------------- // +// print text if Serial is enabled +extern "C" void ErrorMsgHandler(const char * msg) +{ + if(Serial) + Serial.println(msg); +} + + diff --git a/cores/arduino/board.h b/cores/arduino/board.h new file mode 100644 index 0000000..ad1ae06 --- /dev/null +++ b/cores/arduino/board.h @@ -0,0 +1,8 @@ +#ifndef _BOARD_H_ +#define _BOARD_H_ + +// functions for init called before and after setup() +void pre_init(void) ; +void post_init(void); + +#endif /* _BOARD_H_ */ diff --git a/cores/arduino/itoa.cpp b/cores/arduino/itoa.cpp new file mode 100644 index 0000000..ee74f82 --- /dev/null +++ b/cores/arduino/itoa.cpp @@ -0,0 +1,174 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "itoa.h" +#include + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +#if 0 +/* reverse: reverse string s in place */ +static void reverse( char s[] ) +{ + int i, j ; + char c ; + + for ( i = 0, j = strlen(s)-1 ; i < j ; i++, j-- ) + { + c = s[i] ; + s[i] = s[j] ; + s[j] = c ; + } +} + +/* itoa: convert n to characters in s */ +extern void itoa( int n, char s[] ) +{ + int i, sign ; + + if ( (sign = n) < 0 ) /* record sign */ + { + n = -n; /* make n positive */ + } + + i = 0; + do + { /* generate digits in reverse order */ + s[i++] = n % 10 + '0'; /* get next digit */ + } while ((n /= 10) > 0) ; /* delete it */ + + if (sign < 0 ) + { + s[i++] = '-'; + } + + s[i] = '\0'; + + reverse( s ) ; +} + +#else + +extern char* itoa( int value, char *string, int radix ) +{ + return ltoa( value, string, radix ) ; +} + +extern char* ltoa( long value, char *string, int radix ) +{ + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v; + int sign; + char *sp; + + if ( string == NULL ) + { + return 0 ; + } + + if (radix > 36 || radix <= 1) + { + return 0 ; + } + + sign = (radix == 10 && value < 0); + if (sign) + { + v = -value; + } + else + { + v = (unsigned long)value; + } + + while (v || tp == tmp) + { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i+'0'; + else + *tp++ = i + 'a' - 10; + } + + sp = string; + + if (sign) + *sp++ = '-'; + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + + return string; +} +#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 9 || \ + (__GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ > 2))) +extern char* utoa( unsigned value, char *string, int radix ) +#else +extern char* utoa( unsigned long value, char *string, int radix ) +#endif +{ + return ultoa( value, string, radix ) ; +} + +extern char* ultoa( unsigned long value, char *string, int radix ) +{ + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v = value; + char *sp; + + if ( string == NULL ) + { + return 0; + } + + if (radix > 36 || radix <= 1) + { + return 0; + } + + while (v || tp == tmp) + { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i+'0'; + else + *tp++ = i + 'a' - 10; + } + + sp = string; + + + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + + return string; +} +#endif /* 0 */ + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/cores/arduino/itoa.h b/cores/arduino/itoa.h new file mode 100644 index 0000000..b88204c --- /dev/null +++ b/cores/arduino/itoa.h @@ -0,0 +1,47 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _ITOA_ +#define _ITOA_ + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +#if 0 + +extern void itoa( int n, char s[] ) ; + +#else + +extern char* itoa( int value, char *string, int radix ) ; +extern char* ltoa( long value, char *string, int radix ) ; +#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 9 || \ + (__GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ > 2))) +extern char* utoa( unsigned value, char *string, int radix ) ; +#else +extern char* utoa( unsigned long value, char *string, int radix ) ; +#endif +extern char* ultoa( unsigned long value, char *string, int radix ) ; +#endif /* 0 */ + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // _ITOA_ diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp new file mode 100644 index 0000000..b85dab3 --- /dev/null +++ b/cores/arduino/main.cpp @@ -0,0 +1,17 @@ +#define ARDUINO_MAIN + +#include "Arduino.h" + +int main() +{ + pre_init(); + setup(); + post_init(); + + while (1) + { + loop(); + } +} + + diff --git a/cores/arduino/mik32/hal/.gitignore b/cores/arduino/mik32/hal/.gitignore new file mode 100644 index 0000000..600d2d3 --- /dev/null +++ b/cores/arduino/mik32/hal/.gitignore @@ -0,0 +1 @@ +.vscode \ No newline at end of file diff --git a/cores/arduino/mik32/hal/README.md b/cores/arduino/mik32/hal/README.md new file mode 100644 index 0000000..e1f4b5d --- /dev/null +++ b/cores/arduino/mik32/hal/README.md @@ -0,0 +1 @@ +# mcu32-hal diff --git a/cores/arduino/mik32/hal/core/Include/mik32_hal_scr1_timer.h b/cores/arduino/mik32/hal/core/Include/mik32_hal_scr1_timer.h new file mode 100644 index 0000000..c4d08a2 --- /dev/null +++ b/cores/arduino/mik32/hal/core/Include/mik32_hal_scr1_timer.h @@ -0,0 +1,105 @@ +#ifndef MIK32_HAL_SCR1_TIMER +#define MIK32_HAL_SCR1_TIMER + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mcu32_memory_map.h" +#include "power_manager.h" +#include "inttypes.h" + +// #include "csr.h" +// #include "scr1_csr_encoding.h" +#include "scr1_timer.h" + + + +#define MIK32_FREQ 32000000 /* Входная частота, Гц */ +#define MIK32_FREQ_MHZ 32 /* Входная частота, МГц */ + +/* Источник тактированя */ +#define SCR1_TIMER_CLKSRC_INTERNAL 0 /* Тактирование от ядра */ +#define SCR1_TIMER_CLKSRC_EXTERNAL_RTC 1 /* Тактирование от внешнего RTC */ + + + +typedef struct +{ + SCR1_TIMER_TypeDef *Instance; /* Базовый адрес регистров SCR1_TIMER */ + + uint8_t ClockSource; /* Источник тактирования */ + uint16_t Divider; /* Делитель частоты 10-битное число */ + +} SCR1_TIMER_HandleTypeDef; + + +void HAL_SCR1_Timer_Enable(SCR1_TIMER_HandleTypeDef *hscr1_timer); +void HAL_SCR1_Timer_Disable(SCR1_TIMER_HandleTypeDef *hscr1_timer); +void HAL_SCR1_Timer_SetClockSource(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint8_t ClockSource); +void HAL_SCR1_Timer_SetDivider(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint16_t Divider); +void HAL_SCR1_Timer_Init(SCR1_TIMER_HandleTypeDef *hscr1_timer); +void HAL_SCR1_Timer_Start(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds); +int HAL_SCR1_Timer_GetFlagCMP(SCR1_TIMER_HandleTypeDef *hscr1_timer); + +uint64_t HAL_SCR1_Timer_Get_Ticks(SCR1_TIMER_HandleTypeDef *hscr1_timer); + +/* Время задержки должено быть не больше 134217 мс */ +void HAL_DelayMs(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds); + +#ifdef __cplusplus +} +#endif + +#endif + +/* +* uint32_t TIMER_CTRL; +* uint32_t TIMER_DIV; +* uint32_t MTIME; +* uint32_t MTIMEH; +* uint32_t MTIMECMP; +* uint32_t MTIMECMPH; +*/ + +/* + +Регистр TIMER_CTRL +------------------------------------------------------------------------------------------------ +Обозначение | Биты | По умолчанию | Описание | Доступ +------------------------------------------------------------------------------------------------ +ENABLE | 0 | X | Включение таймера | RW +------------------------------------------------------------------------------------------------ +CLKSRC | 1 | 0x0 | Источник тактирования | RW + | | | 0 - Тактирования ядра | + | | | 1 - Внешний RTC | +------------------------------------------------------------------------------------------------ +Reserved | 31:2 | | RZ +------------------------------------------------------------------------------------------------ + + +Регистр TIMER_DIV +------------------------------------------------------------------------------------------------ +Обозначение | Биты | По умолчанию | Описание | Доступ +------------------------------------------------------------------------------------------------ +DIV | 9:0 | X | Делитель | RW + | Счет идет каждые DIV+1 | + | такта частоты | +------------------------------------------------------------------------------------------------ +Reserved | 31:10 | X | RZ +------------------------------------------------------------------------------------------------ + + +По умолчанию, MTIME и MTIMEH равны нулю после перезагрузки ядра (которая также +начинает подсчет). Другим вариантом начала счета для MTIME/MTIMEH является запись некоторого значения в +MTIME/MTIMEH. + +MTIME - Счетчик таймера. 64-битне число. MTIMEH - старшее слово, MTIME - младшее слово. +MTIMECMP - Регистр сравнения. 64-битное число. MTIMECMPH - старшее слово, MTIMECMP - младшее слово. + +Прерывание машинного таймера становится ожидающим всякий раз, когда mtime содержит значение, большее или равное mtimecmp, +обрабатывая значения как целые числа без знака. Прерывание сохраняется до тех пор, пока mtimecmp не станет больше +mtime (обычно в результате записи mtimecmp). Прерывание будет принято только в том случае, если +включены прерывания и бит MTIE установлен в регистре mie. + +*/ diff --git a/cores/arduino/mik32/hal/core/Include/put here h files.txt b/cores/arduino/mik32/hal/core/Include/put here h files.txt new file mode 100644 index 0000000..e69de29 diff --git a/cores/arduino/mik32/hal/core/Source/mik32_hal_scr1_timer.c b/cores/arduino/mik32/hal/core/Source/mik32_hal_scr1_timer.c new file mode 100644 index 0000000..89ca363 --- /dev/null +++ b/cores/arduino/mik32/hal/core/Source/mik32_hal_scr1_timer.c @@ -0,0 +1,125 @@ +#include "mik32_hal_scr1_timer.h" +#include "mik32_hal.h" + + +void HAL_SCR1_Timer_Enable(SCR1_TIMER_HandleTypeDef *hscr1_timer) +{ + hscr1_timer->Instance->TIMER_CTRL |= SCR1_TIMER_CTRL_ENABLE_M; +} + +void HAL_SCR1_Timer_Disable(SCR1_TIMER_HandleTypeDef *hscr1_timer) +{ + hscr1_timer->Instance->TIMER_CTRL &= ~SCR1_TIMER_CTRL_ENABLE_M; + + hscr1_timer->Instance->MTIME = 0; + hscr1_timer->Instance->MTIMEH = 0; +} + +void HAL_SCR1_Timer_SetClockSource(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint8_t ClockSource) +{ + hscr1_timer->ClockSource = ClockSource; + + switch (ClockSource) + { + case SCR1_TIMER_CLKSRC_INTERNAL: + hscr1_timer->Instance->TIMER_CTRL &= SCR1_TIMER_CTRL_CLKSRC_INTERNAL_M; + break; + + case SCR1_TIMER_CLKSRC_EXTERNAL_RTC: + hscr1_timer->Instance->TIMER_CTRL |= SCR1_TIMER_CTRL_CLKSRC_RTC_M; + break; + } +} + +void HAL_SCR1_Timer_SetDivider(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint16_t Divider) +{ + /* Divider 10-битное число */ + if(Divider > 1023) + { + Divider = 1023; + } + hscr1_timer->Divider = Divider; + hscr1_timer->Instance->TIMER_DIV = Divider; +} + +void HAL_SCR1_Timer_Init(SCR1_TIMER_HandleTypeDef *hscr1_timer) +{ + hscr1_timer->Instance->TIMER_CTRL = 0; + + /* Настройка источника тактирования */ + HAL_SCR1_Timer_SetClockSource(hscr1_timer, hscr1_timer->ClockSource); + + /* Настройка делителя */ + HAL_SCR1_Timer_SetDivider(hscr1_timer, hscr1_timer->Divider); + + HAL_SCR1_Timer_Start(hscr1_timer, 134217); + +} + +void HAL_SCR1_Timer_Start(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds) +{ + uint8_t AHBMDivider = PM->DIV_AHB; /* Делитель частоты */ + uint32_t Milliseconds_max_32bit = 134217; /* 134217 - максимальное число миллисекунд для того чтобы при расчете количества тактов не превысить 32 бита */ + + if (Milliseconds > Milliseconds_max_32bit) + { + Milliseconds = Milliseconds_max_32bit; /* Задержка равна предельному значению 134217, мс */ + } + + uint32_t Ticks = Milliseconds * (MIK32_FREQ/1000); /* Количество тактов системного таймера для достижения значения Milliseconds */ + Ticks = Ticks / (AHBMDivider + 1); + Ticks = Ticks / (hscr1_timer->Divider + 1); + + #ifdef MIK32_SCR1_TIMER_DEBUG + xprintf("Milliseconds = %u\n", Milliseconds); + xprintf("Ticks = %u\n", Ticks); + #endif + + + hscr1_timer->Instance->MTIME = 0; + hscr1_timer->Instance->MTIMEH = 0; + + hscr1_timer->Instance->MTIMECMP = Ticks; + hscr1_timer->Instance->MTIMECMPH = 0; + + HAL_SCR1_Timer_Enable(hscr1_timer); +} + +uint64_t HAL_SCR1_Timer_Get_Ticks(SCR1_TIMER_HandleTypeDef *hscr1_timer) +{ + return ((uint64_t)hscr1_timer->Instance->MTIMEH)<<32 | hscr1_timer->Instance->MTIME; +} + + +int HAL_SCR1_Timer_GetFlagCMP(SCR1_TIMER_HandleTypeDef *hscr1_timer) +{ + uint32_t MTIME = hscr1_timer->Instance->MTIME; + uint32_t MTIMEH = hscr1_timer->Instance->MTIMEH; + uint32_t MTIMECMP = hscr1_timer->Instance->MTIMECMP; + uint32_t MTIMECMPH = hscr1_timer->Instance->MTIMECMPH; + + if( ((MTIMEH == MTIMECMPH) && (MTIME > MTIMECMP)) || (MTIMEH > MTIMECMPH) ) + { + HAL_SCR1_Timer_Disable(hscr1_timer); + return 1; + } + else + { + return 0; + } +} + + +void HAL_DelayMs(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds) +{ + + HAL_SCR1_Timer_Start(hscr1_timer, Milliseconds); + + while (HAL_SCR1_Timer_GetFlagCMP(hscr1_timer) == 0); + + HAL_SCR1_Timer_Disable(hscr1_timer); + +} + + + diff --git a/cores/arduino/mik32/hal/core/Source/put here c files.txt b/cores/arduino/mik32/hal/core/Source/put here c files.txt new file mode 100644 index 0000000..e69de29 diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal.h new file mode 100644 index 0000000..e1d7281 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal.h @@ -0,0 +1,34 @@ +#ifndef MIK32_HAL +#define MIK32_HAL + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_def.h" +#include "mik32_hal_pcc.h" + +#ifndef OSC_SYSTEM_VALUE + #define OSC_SYSTEM_VALUE ((uint32_t)32000000U) // Значение частоты основного внешнего источника по умолчанию. +#endif + +#ifndef OSC_CLOCK_VALUE + #define OSC_CLOCK_VALUE ((uint32_t)32768U) // Значение частоты часового внешнего источника по умолчанию. +#endif + +#ifndef HSI_VALUE + #define HSI_VALUE ((uint32_t)32000000U) // Значение частоты основного внутреннего источника по умолчанию. +#endif + +#ifndef LSI_VALUE + #define LSI_VALUE ((uint32_t)32768U) // Значение частоты часового внутреннего источника по умолчанию. +#endif + +void HAL_MspInit(); +HAL_StatusTypeDef HAL_Init(); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_adc.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_adc.h new file mode 100644 index 0000000..ae5d697 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_adc.h @@ -0,0 +1,360 @@ +#ifndef MIK32_HAL_ADC +#define MIK32_HAL_ADC + +#ifdef __cplusplus +extern "C" { +#endif + +#include "analog_reg.h" +#include "pad_config.h" +#include "stdbool.h" +#include "mik32_hal_pcc.h" +#include "mik32_hal_gpio.h" +#include "mcu32_memory_map.h" + + +/* Title: Макросы */ + +/* + * Defines: Каналы АЦП + * + * ADC_CHANNEL0 - Канал АЦП0 (PORT_1_5) + * ADC_CHANNEL1 - Канал АЦП1 (PORT_1_7) + * ADC_CHANNEL2 - Канал АЦП2 (PORT_0_2) + * ADC_CHANNEL3 - Канал АЦП3 (PORT_0_4) + * ADC_CHANNEL4 - Канал АЦП4 (PORT_0_7) + * ADC_CHANNEL5 - Канал АЦП5 (PORT_0_9) + * ADC_CHANNEL6 - Канал АЦП6 (PORT_0_11) + * ADC_CHANNEL7 - Канал АЦП7 (PORT_0_13) + * + */ +#define ADC_CHANNEL0 0 /* Канал АЦП0 - PORT_1_5 */ +#define ADC_CHANNEL1 1 /* Канал АЦП1 - PORT_1_7 */ +#define ADC_CHANNEL2 2 /* Канал АЦП2 - PORT_0_2 */ +#define ADC_CHANNEL3 3 /* Канал АЦП3 - PORT_0_4 */ +#define ADC_CHANNEL4 4 /* Канал АЦП4 - PORT_0_7 */ +#define ADC_CHANNEL5 5 /* Канал АЦП5 - PORT_0_9 */ +#define ADC_CHANNEL6 6 /* Канал АЦП6 - PORT_0_11 */ +#define ADC_CHANNEL7 7 /* Канал АЦП7 - PORT_0_13 */ + +/* + * Defines: Выбор ИОН + * + * Выбор источника опорного напряжения. + * + * ADC_EXTREF_OFF - Встроенный источник опорного напряжения 1,2 В + * ADC_EXTREF_ON - Внешний источник опорного напряжения + * + */ +#define ADC_EXTREF_OFF 0 /* Встроенный источник опорного напряжения 1,2 В */ +#define ADC_EXTREF_ON 1 /* Внешний источник опорного напряжения */ + +/* + * Defines: Выбор внешнего ИОН + * + * Выбор внешнего источника опорного напряжения по отношению к встроенному в АЦП ИОН. + * + * ADC_EXTCLB_CLBREF - Настраиваемый ОИН + * ADC_EXTCLB_ADCREF - Внешний вывод + * + */ +#define ADC_EXTCLB_CLBREF 0 /* Настраиваемый ОИН */ +#define ADC_EXTCLB_ADCREF 1 /* Внешний вывод */ + +/* + * Defines: Входы АЦП + * + * Номера выводов каналов АЦП и ADC_REF + * + * ADC_PORT_AS_FUNC3 - Четвертая функция вывода (аналоговый сигнал) + * ADC_CHANNEL0_PORT_1_5 - Канал АЦП0 - PORT_1_5 + * ADC_CHANNEL1_PORT_1_7 - Канал АЦП1 - PORT_1_7 + * ADC_CHANNEL2_PORT_0_2 - Канал АЦП2 - PORT_0_2 + * ADC_CHANNEL3_PORT_0_4 - Канал АЦП3 - PORT_0_4 + * ADC_CHANNEL4_PORT_0_7 - Канал АЦП4 - PORT_0_7 + * ADC_CHANNEL5_PORT_0_9 - Канал АЦП5 - PORT_0_9 + * ADC_CHANNEL6_PORT_0_11 - Канал АЦП6 - PORT_0_11 + * ADC_CHANNEL7_PORT_0_13 - Канал АЦП7 - PORT_0_13 + * ADC_REF_PORT_1_10 - Внешний опорный сигнал - PORT_1_10 + * + */ +#define ADC_PORT_AS_FUNC3 0b11 /* Четвертая функция вывода (аналоговый сигнал) */ +#define ADC_CHANNEL0_PORT_1_5 5 /* Канал АЦП0 - PORT_1_5 */ +#define ADC_CHANNEL1_PORT_1_7 7 /* Канал АЦП1 - PORT_1_7 */ +#define ADC_CHANNEL2_PORT_0_2 2 /* Канал АЦП2 - PORT_0_2 */ +#define ADC_CHANNEL3_PORT_0_4 4 /* Канал АЦП3 - PORT_0_4 */ +#define ADC_CHANNEL4_PORT_0_7 7 /* Канал АЦП4 - PORT_0_7 */ +#define ADC_CHANNEL5_PORT_0_9 9 /* Канал АЦП5 - PORT_0_9 */ +#define ADC_CHANNEL6_PORT_0_11 11 /* Канал АЦП6 - PORT_0_11 */ +#define ADC_CHANNEL7_PORT_0_13 13 /* Канал АЦП7 - PORT_0_13 */ +#define ADC_REF_PORT_1_10 10 /* Внешний опорный сигнал - PORT_1_10 */ + + +/* Title: Структуры */ + +/* + * Struct: ADC_InitTypeDef + * + * Настройки АЦП при инициализации + * + */ +typedef struct +{ + /* + * Variable: Sel + * Выбор канала АЦП + * + * Этот параметр должен быть одним из значений: + * + * - ; + * - ; + * - ; + * - ; + * - ; + * - ; + * - ; + * - . + * + */ + uint8_t Sel; + + /* + * Variable: EXTRef + * Выбор источника опорного напряжения + * + * Этот параметр должен быть одним из значений: + * + * - ; + * - . + * + */ + uint8_t EXTRef; + + /* + * Variable: EXTClb + * Выбор внешнего источника опорного напряжения + * + * Этот параметр должен быть одним из значений: + * + * - ; + * - . + * + */ + uint8_t EXTClb; + +} ADC_InitTypeDef; + +/* + * Struct: ADC_HandleTypeDef + * Настройки АЦП + * + */ +typedef struct +{ + /* + * Variable: Instance + * Базоый адрес регистров ADC. + * + */ + ANALOG_REG_TypeDef *Instance; + + /* + * Variable: Init + * Настройки АЦП при инициализации + * + */ + ADC_InitTypeDef Init; + +} ADC_HandleTypeDef; + + +/* Сменить канал АЦП */ +#ifdef MIK32V0 + #define ADC_SEL_CHANNEL(adc_instance, channel_selection) ((adc_instance)->ADC_CONFIG = (((adc_instance)->ADC_CONFIG & (~ADC_CONFIG_SEL_M)) | ((channel_selection) << ADC_CONFIG_SEL_S))) +#else // MIK32V2 + #define ADC_SEL_CHANNEL(adc_instance, channel_selection) ((adc_instance)->ADC_CONFIG = (((adc_instance)->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) & (~ADC_CONFIG_SEL_M)) | (((adc_instance)->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) | ((channel_selection) << ADC_CONFIG_SEL_S)) +#endif // MIK32V0 + +/* Запустить однократное преобразование */ +#define HAL_ADC_SINGLE(adc_instance) ((adc_instance)->ADC_SINGLE = 1) + +#define HAL_ADC_SINGLE_AND_SET_CH(adc_instance, adc_channel) ({(adc_instance)->ADC_SINGLE = 1; ADC_SEL_CHANNEL((adc_instance), (adc_channel));}) /* Запустить однократное преобразование */ + + +/* Title: Функции */ + +void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc); + +/* + * Включить калибруемый ИОН + */ +void HAL_ADC_CLBEnable(ADC_HandleTypeDef *hadc); + +/* + * Выключить калибруемый ИОН + */ +void HAL_ADC_CLBDisable(ADC_HandleTypeDef *hadc); + +/* + * Задать коэфициент настройки ОИН + */ +void HAL_ADC_VCLBSet(ADC_HandleTypeDef *hadc, uint8_t v_coef); + +/* + * Задать коэфициент настройки опорного источника тока + */ +void HAL_ADC_ICLBSet(ADC_HandleTypeDef *hadc, uint8_t i_coef); + +/* + * Function: HAL_ADC_ResetEnable + * Установить бит Rn, управление сбросом АЦП, в 1. + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * void + */ +void HAL_ADC_ResetEnable(ADC_HandleTypeDef *hadc); + +/* + * Function: HAL_ADC_ResetDisable + * Сбросить бит Rn, управление сбросом АЦП, в 0. + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * void + */ +void HAL_ADC_ResetDisable(ADC_HandleTypeDef *hadc); + +/* + * Function: HAL_ADC_Disable + * Выключть питание АЦП + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * void + */ +void HAL_ADC_Disable(ADC_HandleTypeDef *hadc); + +/* + * Function: HAL_ADC_Enable + * Включть питание АЦП + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * void + */ +void HAL_ADC_Enable(ADC_HandleTypeDef *hadc); + +/* + * Function: HAL_ADC_ChannelSet + * Задать активный канал АЦП и перевести соответсвующий вывод в аналоговую функцию. + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * void + */ +void HAL_ADC_ChannelSet(ADC_HandleTypeDef *hadc); + +/* + * Function: HAL_ADC_Init + * Инициализировать АЦП в соответсвии с настройками в hadc. + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * void + */ +void HAL_ADC_Init(ADC_HandleTypeDef *hadc); + +/* + * Function: HAL_ADC_Single + * Запустить однократное измерение АЦП. + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * void. + */ +void HAL_ADC_Single(ADC_HandleTypeDef *hadc); + +/* + * Function: HAL_ADC_ContiniusDisabled + * Выключить непрерывное измерение АЦП. + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * void + */ +void HAL_ADC_ContinuousDisabled(ADC_HandleTypeDef *hadc); + +/* + * Function: HAL_ADC_ContiniusEnable + * Выключить непрерывное измерение АЦП. + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * void + */ +void HAL_ADC_ContinuousEnable(ADC_HandleTypeDef *hadc); + +/* + * Function: HAL_ADC_WaitValid + * Ожидать установку флага актуальных данных. + * + * Флаг VALID - Признак наличия актуальных данных. + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * void + */ +void HAL_ADC_WaitValid(ADC_HandleTypeDef *hadc); + +/* + * Function: HAL_ADC_GetValue + * Получить результат преобразовния АЦП. + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * (uint16_t ) - Результат преобразования АЦП. + * + */ +uint16_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc); + +/* + * Function: HAL_ADC_WaitAndGetValue + * Ожидать актуальный результат преобразования АЦП и получить его значение. + * + * Parameters: + * hadc - Указатель на структуру с настройками ADC. + * + * Returns: + * (uint16_t ) - Результат преобразования АЦП. + * + */ +uint16_t HAL_ADC_WaitAndGetValue(ADC_HandleTypeDef *hadc); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_crc32.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_crc32.h new file mode 100644 index 0000000..81606b5 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_crc32.h @@ -0,0 +1,347 @@ +#ifndef MIK32_HAL_CRC32 +#define MIK32_HAL_CRC32 + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_pcc.h" +#include "crc.h" +#include "mcu32_memory_map.h" + + + +/* Title: Макросы */ + +/* + * Defines: Перестановка битов/байтов данных + * + * CRC_REVERSE_OFF - Перестановка выключена + * CRC_REVERSE_BITS - Биты в байтах перестанавливаются, байты не перестанавливаются + * CRC_REVERSE_BITS_BYTES - Перестанавливаются и биты, и байты + * CRC_REVERSE_BYTES - Биты в байтах не перестанавливаются, байты перестанавливаются + * + */ +#define CRC_REVERSE_OFF 0 // Перестановка выключена +#define CRC_REVERSE_BITS 1 // Биты в байтах перестанавливаются, байты не перестанавливаются +#define CRC_REVERSE_BITS_BYTES 2 // Перестанавливаются и биты, и байты +#define CRC_REVERSE_BYTES 3 // Биты в байтах не перестанавливаются, байты перестанавливаются + + +/* Модификаторы */ +/* + * Defines: Флаг RefIn + * + * Флаг RefIn, указывающий на начало и направление вычислений. + * + * Перестановка битов/байтов входных данных. + * + * Существует два варианта: + * + * - CRC_REFIN_FALSE начиная со старшего значащего бита (MSB-first); + * - CRC_REFIN_TRUE с младшего (LSB-first). + * + * CRC_REFIN_FALSE - Биты в байтах не перестанавливаются, байты перестанавливаются + * CRC_REFIN_TRUE - Перестанавливаются и биты, и байты + * + */ +#define CRC_REFIN_FALSE CRC_REVERSE_BYTES // RefIn = false - CRC_REVERSE_BYTES +#define CRC_REFIN_TRUE CRC_REVERSE_BITS_BYTES // RefIn = true - CRC_REVERSE_BITS_BYTES + +/* + * Defines: Флаг RefOut + * + * Флаг RefOut, определяющий, инвертируется ли порядок битов регистра при входе на элемент XOR. + * + * Перестановки битов/байтов выходных данных. + * + * CRC_REFOUT_FALSE - Биты в байтах не перестанавливаются, байты перестанавливаются + * CRC_REFOUT_TRUE - Перестанавливаются и биты, и байты + * + */ +#define CRC_REFOUT_FALSE CRC_REVERSE_OFF // RefOut = false - CRC_REVERSE_OFF +#define CRC_REFOUT_TRUE CRC_REVERSE_BITS_BYTES // RefOUT = true - CRC_REVERSE_BITS_BYTES + +/* + * Defines: Флаг XorOut + * + * Инверсия контрольной суммы. + * Число XorOut = 0xFFFFFFFF, с которым складывается по модулю 2 полученный результат. Побитовая инверсия результата. + * + * CRC_OUTPUTINVERSION_OFF - Инверсия выключена. + * CRC_OUTPUTINVERSION_ON - Инверсия включена (операция XOR выполняется) + * + */ +#define CRC_OUTPUTINVERSION_OFF 0 // Инверсия выключена +#define CRC_OUTPUTINVERSION_ON 1 // Инверсия включена (операция XOR выполняется) + +/* + * Defines: Размер буфера + * + * CRC_MAX_WORDS - Максимальное количество слов в буфере. + * CRC_MAX_BYTES - Максимальное количество байтов в буфере. + * + */ +#define CRC_MAX_WORDS 16 +#define CRC_MAX_BYTES 64 + +/* Title: Структуры */ + +/* + * Struct: CRC_HandleTypeDef + * Настройки CRC + * + */ +typedef struct +{ + /* + * Variable: Instance + * Базоый адрес регистров CRC + * + */ + CRC_TypeDef *Instance; + + /* + * Variable: Poly + * Значение порождающего многочлена. + * + * Этот параметр может быть 32-битным значением. + * + */ + uint32_t Poly; + + /* + * Variable: Init + * Стартовое значение данных. + * + * Этот параметр может быть 32-битным значением. + * + */ + uint32_t Init; + + /* + * Variable: InputReverse + * Перестановка битов/байтов входных данных. + * + * Этот параметр должен быть одним из значений: + * + * - ; + * - . + * + */ + uint8_t InputReverse; + +/* + * Variable: OutputReverse + * Перестановка битов/байтов выходных данных. + * + * Этот параметр должен быть одним из значений: + * + * - ; + * - . + * + */ + uint8_t OutputReverse; + +/* + * Variable: OutputInversion + * Инверсия контрольной суммы. + * + * Этот параметр должен быть одним из значений: + * + * - ; + * - . + * + */ + uint8_t OutputInversion; + +} CRC_HandleTypeDef; + +/* Title: Функции */ + +void HAL_CRC32_MspInit(CRC_HandleTypeDef* hcrc); + +/* + * Function: HAL_CRC_SetInputReverse + * Задать перестановка битов/байтов входных данных в соответствии со значением (RefIn). + * + * Parameters: + * hcrc - Указатель на структуру с настройками CRC. + * + * Returns: + * void + */ +void HAL_CRC_SetInputReverse(CRC_HandleTypeDef *hcrc); + +/* + * Function: HAL_CRC_SetOutputInversion + * Инверсия контрольной суммы в соответсвии со значением (XorOut). + * + * Parameters: + * hcrc - Указатель на структуру с настройками CRC. + * + * Returns: + * void + */ +void HAL_CRC_SetOutputInversion(CRC_HandleTypeDef *hcrc); + +/* + * Function: HAL_CRC_SetOutputReverse + * Перестановки битов/байтов выходных данных в соответствии со значением (RefOut). + * + * Parameters: + * hcrc - Указатель на структуру с настройками CRC. + * + * Returns: + * void + */ +void HAL_CRC_SetOutputReverse(CRC_HandleTypeDef *hcrc); + +/* + * Function: HAL_CRC_SetInit + * Задать начальное значение данных в соответсвии с + * + * Parameters: + * hcrc - Указатель на структуру с настройками CRC. + * + * Returns: + * void + */ +void HAL_CRC_SetInit(CRC_HandleTypeDef *hcrc); + +/* + * Function: HAL_CRC_Init + * Инициализировать CRC в соответствии с настройками *hcrc. + * + * Parameters: + * hcrc - Указатель на структуру с настройками CRC. + * + * Returns: + * void + */ +void HAL_CRC_Init(CRC_HandleTypeDef *hcrc); + +/* + * Function: HAL_CRC_WaitBusy + * Ожидать сброса флага BUSY. Если флаг равен 0, то автомат закончил вычисления. + * + * Parameters: + * hcrc - Указатель на структуру с настройками CRC. + * + * Returns: + * void + */ +void HAL_CRC_WaitBusy(CRC_HandleTypeDef *hcrc); + +/* + * Function: HAL_CRC_WaitBusy + * Записать данные по байтам в буфер CRC. + * + * Parameters: + * hcrc - Указатель на структуру с настройками CRC. + * message - Массив с данными. + * message_length - Количество передаваемых байтов. + * + * Returns: + * void + */ +void HAL_CRC_WriteData(CRC_HandleTypeDef *hcrc, uint8_t message[], uint32_t message_length); + +/* + * Function: HAL_RTC_WriteData32 + * Записать данные по словам в буфер CRC. + * + * Parameters: + * hcrc - Указатель на структуру с настройками CRC. + * message - Массив с данными. + * message_length - Количество передаваемых байтов. + * + * Returns: + * void + */ +void HAL_CRC_WriteData32(CRC_HandleTypeDef *hcrc, uint32_t message[], uint32_t message_length); + +/* + * Function: HAL_RTC_ReadCRC + * Получить значение CRC. + * + * Parameters: + * hcrc - Указатель на структуру с настройками CRC. + * + * Returns: + * (uint32_t ) - Значение CRC. + * + */ +uint32_t HAL_CRC_ReadCRC(CRC_HandleTypeDef *hcrc); + +#ifdef __cplusplus +} +#endif + +#endif + + + +/**************************************CRC-32**************************************/ +// hcrc.Poly = 0x04C11DB7; +// hcrc.Init = 0xFFFFFFFF; +// hcrc.InputReverse = CRC_REFIN_TRUE; +// hcrc.OutputReverse = CRC_REFOUT_TRUE; +// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON; + +/**************************************CRC-32/BZIP2**************************************/ +// hcrc.Poly = 0x04C11DB7; +// hcrc.Init = 0xFFFFFFFF; +// hcrc.InputReverse = CRC_REFIN_FALSE; +// hcrc.OutputReverse = CRC_REFOUT_FALSE; +// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON; + +/*******************************************CRC-32C*******************************************/ +// hcrc.Poly = 0x1EDC6F41; +// hcrc.Init = 0xFFFFFFFF; +// hcrc.InputReverse = CRC_REFIN_TRUE; +// hcrc.OutputReverse = CRC_REFOUT_TRUE; +// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON; + +/*******************************************CRC-32D*******************************************/ +// hcrc.Poly = 0xA833982B; +// hcrc.Init = 0xFFFFFFFF; +// hcrc.InputReverse = CRC_REFIN_TRUE; +// hcrc.OutputReverse = CRC_REFOUT_TRUE; +// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON; + +/****************************************CRC-32/JAMCRC****************************************/ +// hcrc.Poly = 0x04C11DB7; +// hcrc.Init = 0xFFFFFFFF; +// hcrc.InputReverse = CRC_REFIN_TRUE; +// hcrc.OutputReverse = CRC_REFOUT_TRUE; +// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF; + +/****************************************CRC-32/MPEG-2****************************************/ +// hcrc.Poly = 0x04C11DB7; +// hcrc.Init = 0xFFFFFFFF; +// hcrc.InputReverse = CRC_REFIN_FALSE; +// hcrc.OutputReverse = CRC_REFOUT_FALSE; +// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF; + +/*****************************************CRC-32/POSIX*****************************************/ +// hcrc.Poly = 0x04C11DB7; +// hcrc.Init = 0x00000000; +// hcrc.InputReverse = CRC_REFIN_FALSE; +// hcrc.OutputReverse = CRC_REFOUT_FALSE; +// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON; + +/*******************************************CRC-32Q*******************************************/ +// hcrc.Poly = 0x814141AB; +// hcrc.Init = 0x00000000; +// hcrc.InputReverse = CRC_REFIN_FALSE; +// hcrc.OutputReverse = CRC_REFOUT_FALSE; +// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF; + +/*****************************************CRC-32/XFER*****************************************/ +// hcrc.Poly = 0x000000AF; +// hcrc.Init = 0x00000000; +// hcrc.InputReverse = CRC_REFIN_FALSE; +// hcrc.OutputReverse = CRC_REFOUT_FALSE; +// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF; + diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_crypto.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_crypto.h new file mode 100644 index 0000000..f5dff48 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_crypto.h @@ -0,0 +1,120 @@ +#ifndef MIK32_HAL_CRYPTO +#define MIK32_HAL_CRYPTO + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_pcc.h" +#include "crypto.h" +#include "pad_config.h" +#include "mcu32_memory_map.h" + + +/** + * @name Длина вектора инициализации + * @{ + */ +#define IV_LENGTH_KUZNECHIK_CBC 4 /**< Количество слов вектора инициализации в режиме шифрования CBC (Кузнечик). */ +#define IV_LENGTH_MAGMA_CBC 4 /**< Количество слов вектора инициализации в режиме шифрования CBC (Магма). */ +#define IV_LENGTH_AES_CBC 2 /**< Количество слов вектора инициализации в режиме шифрования CBC (AES). */ +#define IV_LENGTH_KUZNECHIK_CTR 2 /**< Количество слов вектора инициализации в режиме шифрования CTR (Кузнечик). */ +#define IV_LENGTH_MAGMA_CTR 2 /**< Количество слов вектора инициализации в режиме шифрования CTR (Магма). */ +#define IV_LENGTH_AES_CTR 1 /**< Количество слов вектора инициализации в режиме шифрования CTR (AES). */ +/** @} */ + +/** + * @name Длина ключа + * @{ + */ +#define CRYPTO_KEY_KUZNECHIK 8 /**< Длина ключа Кузнечик. */ +#define CRYPTO_KEY_MAGMA 8 /**< Длина ключа Магма. */ +#define CRYPTO_KEY_AES 4 /**< Длина ключа AES. */ +/** @} */ + +/** + * @name Длина блока + * @{ + */ +#define CRYPTO_BLOCK_KUZNECHIK 4 /**< Длина блока Кузнечик. */ +#define CRYPTO_BLOCK_MAGMA 2 /**< Длина блока Магма. */ +#define CRYPTO_BLOCK_AES 4 /**< Длина блока AES. */ +/** @} */ + +/** + * @name Алгоритм шифрования + * @{ + */ +#define CRYPTO_ALG_KUZNECHIK 0 /**< Алгоритм шифрования Кузнечик. */ +#define CRYPTO_ALG_MAGMA 1 /**< Алгоритм шифрования Магма. */ +#define CRYPTO_ALG_AES 2 /**< Алгоритм шифрования AES. */ +/** @} */ + +/** + * @name Режим шифрования + * @{ + */ +#define CRYPTO_CIPHER_MODE_ECB 0 /**< Режим шифрования ECB (Electronic Codebook). */ +#define CRYPTO_CIPHER_MODE_CBC 1 /**< Режим шифрования CBC (Cipher Block Chaining). */ +#define CRYPTO_CIPHER_MODE_CTR 2 /**< Режим шифрования CTR (Counter mode). */ +/** @} */ + +/** + * @name Перестановка слова + * @{ + */ +#define CRYPTO_SWAP_MODE_NONE 0 /**< Нет перестановки. */ +#define CRYPTO_SWAP_MODE_HALFWORD 1 /**< Перестановка по полуслову. */ +#define CRYPTO_SWAP_MODE_BYTE 2 /**< Перестановки по байтам. */ +#define CRYPTO_SWAP_MODE_BIT 3 /**< Перестановка по битам. */ +/** @} */ + +/** + * @name Порядок загрузки/выгрузки + * @{ + */ +#define CRYPTO_ORDER_MODE_LSW 0 /**< Порядка загрузки/выгрузки от младшего слова к старшему. */ +#define CRYPTO_ORDER_MODE_MSW 1 /**< Порядка загрузки/выгрузки от старшего слова к младшему. */ +/** @} */ + + +#define MAXIMUM_KEY_LENGTH 8 /**< Максимальная длина ключа. */ + + +/** + * @brief Настройки Crypto. + * + */ +typedef struct __Crypto_HandleTypeDef +{ + CRYPTO_TypeDef *Instance; /**< Базовый адрес регистров Crypto */ + + uint8_t Algorithm; /**< Выбор алгоритма шифрования. Этот параметр должен быть одним из значений: #CRYPTO_ALG_KUZNECHIK, #CRYPTO_ALG_MAGMA, #CRYPTO_ALG_AES.*/ + + uint8_t CipherMode; /**< Выбор режима шифрования. Этот параметр должен быть одним из значений: #CRYPTO_CIPHER_MODE_ECB, #CRYPTO_CIPHER_MODE_CBC, #CRYPTO_CIPHER_MODE_CTR. */ + + uint8_t SwapMode; /**< Перестановка слова. Этот параметр должен быть одним из значений: #CRYPTO_SWAP_MODE_NONE, #CRYPTO_SWAP_MODE_HALFWORD, #CRYPTO_SWAP_MODE_BYTE, #CRYPTO_SWAP_MODE_BIT. */ + + uint8_t OrderMode; /**< Выбор порядка загрузки/выгрузки. Этот параметр должен быть одним из значений: #CRYPTO_ORDER_MODE_LSW, #CRYPTO_ORDER_MODE_MSW. */ + +} Crypto_HandleTypeDef; + + +void HAL_CRYPTO_MspInit(Crypto_HandleTypeDef* hcrypto); +void HAL_Crypto_CounterReset(Crypto_HandleTypeDef *hcrypto); +void HAL_Crypto_WaitReady(Crypto_HandleTypeDef *hcrypto); +void HAL_Crypto_SetAlgorithm(Crypto_HandleTypeDef *hcrypto, uint8_t Algorithm); +void HAL_Crypto_SetCipherMode(Crypto_HandleTypeDef *hcrypto, uint8_t CipherMode); +void HAL_Crypto_SetSwapMode(Crypto_HandleTypeDef *hcrypto, uint8_t SwapMode); +void HAL_Crypto_SetOrderMode(Crypto_HandleTypeDef *hcrypto, uint8_t OrderMode); +void HAL_Crypto_SetIV(Crypto_HandleTypeDef *hcrypto, uint32_t InitVector[], uint32_t IvLength); +void HAL_Crypto_SetKey(Crypto_HandleTypeDef *hcrypto, uint32_t crypto_key[]); +void HAL_Crypto_Init(Crypto_HandleTypeDef *hcrypto); +void HAL_Crypto_Encode(Crypto_HandleTypeDef *hcrypto, uint32_t plain_text[], uint32_t cipher_text[], uint32_t text_length); +void HAL_Crypto_Decode(Crypto_HandleTypeDef *hcrypto, uint32_t cipher_text[], uint32_t plain_text[], uint32_t text_length); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_dac.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_dac.h new file mode 100644 index 0000000..6f1d77d --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_dac.h @@ -0,0 +1,251 @@ +#ifndef MIK32_HAL_DAC +#define MIK32_HAL_DAC + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_pcc.h" +#include "mik32_hal_gpio.h" +#include "analog_reg.h" +#include "pad_config.h" +#include "stdbool.h" +#include "mcu32_memory_map.h" + +/* Title: Макросы */ + +/* + * Defines: Каналы ЦАП + * + * HAL_DAC1 - Канал ЦАП1 (PORT_1_12) + * HAL_DAC2 - Канал ЦАП2 (PORT_1_13) + * + */ +#define HAL_DAC1 &(ANALOG_REG->DAC0) /* Канал DAC1 - PORT_1_12 */ +#define HAL_DAC2 &(ANALOG_REG->DAC1) /* Канал DAC2 - PORT_1_13 */ + +/* + * Defines: Выбор ИОН + * + * Выбор источника опорного напряжения. + * + * DAC_EXTREF_OFF - Встроенный источник опорного напряжения 1,2 В + * DAC_EXTREF_ON - Внешний источник опорного напряжения + * + */ +#define DAC_EXTREF_OFF 0 /* Встроенный источник опорного напряжения 1,2 В */ +#define DAC_EXTREF_ON 1 /* Внешний источник опорного напряжения */ + +/* + * Defines: Выбор внешнего ИОН + * + * Выбор внешнего источника опорного напряжения по отношению к встроенному в АЦП ИОН. + * + * DAC_EXTCLB_CLBREF - Настраиваемый ОИН + * DAC_EXTCLB_DACREF - Внешний вывод + * + */ +#define DAC_EXTCLB_CLBREF 0 /* Настраиваемый ОИН */ +#define DAC_EXTCLB_DACREF 1 /* Внешний вывод */ + +/* Выводы ЦАП */ +/* + * Defines: Входы АЦП + * + * Номера выводов каналов ЦАП и DAC_REF + * + * DAC_PORT_AS_FUNC3 - Четвертая функция вывода (аналоговый сигнал) + * DAC1_PORT_1_12 - ЦАП1 - PORT_1_12 + * DAC2_PORT_1_13 - ЦАП2 - PORT_1_13 + * DAC_REF_PORT_1_11 - Внешний опорный сигнал DAC_REF - PORT_1_11 + * + */ +#define DAC_PORT_AS_FUNC3 0b11 /* Четвертая функция вывода (аналоговый сигнал) */ +#define DAC1_PORT_1_12 12 /* DAC1 - PORT_1_12 */ +#define DAC2_PORT_1_13 13 /* DAC2 - PORT_1_13 */ +#define DAC_REF_PORT_1_11 11 /* Внешний опорный сигнал - PORT_1_11 */ + +/* Title: Структуры */ + +/* + * Struct: DAC_InitTypeDef + * + * Настройки ЦАП при инициализации + * + */ +typedef struct +{ + /* + * Variable: EXTRef + * Выбор источника опорного напряжения + * + * Этот параметр должен быть одним из значений: + * + * - ; + * - . + * + */ + uint8_t EXTRef; + + /* + * Variable: EXTClb + * Выбор внешнего источника опорного напряжения + * + * Этот параметр должен быть одним из значений: + * + * - ; + * - . + * + */ + uint8_t EXTClb; + + /* + * Variable: DIV + * Значение делителя тактового сигнала. + * + * Частота определяется как F_ЦАП = F_IN/(Div+1). + * + * Значением может быть 8-битное число в пределах от 0 до 255 + * + */ + uint8_t DIV; + +} DAC_InitTypeDef; + +/* + * Struct: DAC_HandleTypeDef + * + * Настройки ЦАП + * + */ +typedef struct +{ + /* + * Variable: Instance + * Базоый адрес регистров ANALOG_REG. + * + */ + ANALOG_REG_TypeDef *Instance; + + /* + * Variable: Instance_dac + * Базоый адрес регистров DAC + * + */ + volatile DAC_TypeDef *Instance_dac; + + /* + * Variable: Init + * Настройки ЦАП при инициализации + * + */ + DAC_InitTypeDef Init; + +} DAC_HandleTypeDef; + +/* Title: Функции */ + +void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac); +void HAL_DAC_CLBEnable(DAC_HandleTypeDef *hdac); +void HAL_DAC_CLBDisable(DAC_HandleTypeDef *hdac); +void HAL_DAC_VCLBSet(DAC_HandleTypeDef *hdac, uint8_t v_coef); +void HAL_DAC_ICLBSet(DAC_HandleTypeDef *hdac, uint8_t i_coef); + +/* + * Function: HAL_DAC_SetDiv + * Установить значение делителя тактового сигнала ЦАП. + * + * Частота определяется как F_ЦАП = F_IN/(Div+1). + * + * Значением может быть 8-битное число в пределах от 0 до 255 + * + * Parameters: + * hdac - Указатель на структуру с настройками ЦАП. + * div - Делитель частоты. + * + * Returns: + * void + */ +void HAL_DAC_SetDiv(DAC_HandleTypeDef *hdac, uint8_t div); + +/* + * Function: HAL_DAC_ResetEnable + * Установить бит Rn, управление сбросом ЦАП, в 1. + * + * Parameters: + * hdac - Указатель на структуру с настройками ЦАП. + * + * Returns: + * void + */ +void HAL_DAC_ResetEnable(DAC_HandleTypeDef *hdac); + +/* + * Function: HAL_DAC_ResetDisable + * Сбросить бит Rn, управление сбросом ЦАП, в 0. + * + * Parameters: + * hdac - Указатель на структуру с настройками ЦАП. + * + * Returns: + * void + */ +void HAL_DAC_ResetDisable(DAC_HandleTypeDef *hdac); + +/* + * Function: HAL_DAC_Disable + * Выключть питание ЦАП + * + * Parameters: + * hdac - Указатель на структуру с настройками ЦАП. + * + * Returns: + * void + */ +void HAL_DAC_Disable(DAC_HandleTypeDef *hdac); + +/* + * Function: HAL_ADC_Enable + * Включть питание ЦАП + * + * Parameters: + * hdac - Указатель на структуру с настройками ЦАП. + * + * Returns: + * void + */ +void HAL_DAC_Enable(DAC_HandleTypeDef *hdac); + +/* + * Function: HAL_DAC_Init + * Инициализировать ЦАП в соответсвии с настройками в hdac. + * + * Parameters: + * hdac - Указатель на структуру с настройками ЦАП. + * + * Returns: + * void + */ +void HAL_DAC_Init(DAC_HandleTypeDef *hdac); + +/* + * Function: HAL_DAC_SetValue + * Задать входные данные для преобразования ЦАП. + * + * Входные данные могут быть в пределах от 0 до 4 095. + * + * Parameters: + * hdac - Указатель на структуру с настройками ЦАП. + * DAC_Value - Входные данные для преобразования ЦАП. + * + * Returns: + * void + * + */ +void HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint16_t DAC_Value); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_def.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_def.h new file mode 100644 index 0000000..5887d0a --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_def.h @@ -0,0 +1,24 @@ +#ifndef MIK32_HAL_DEF +#define MIK32_HAL_DEF + +#ifdef __cplusplus +extern "C" { +#endif + + +#define HAL_PIN_MASK 0xFFFF +#define HAL_PORT_S 16 + +typedef enum HAL_StatusTypeDef +{ + HAL_OK = 0x00U, + HAL_ERROR = 0x01U, + HAL_BUSY = 0x02U, + HAL_TIMEOUT = 0x03U +} HAL_StatusTypeDef; + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_dma.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_dma.h new file mode 100644 index 0000000..d64f4fe --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_dma.h @@ -0,0 +1,210 @@ +#ifndef MIK32_HAL_DMA +#define MIK32_HAL_DMA + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_pcc.h" +#include "mik32_hal_gpio.h" +#include "stddef.h" +#include "dma_config.h" +#include "mcu32_memory_map.h" +#include "mik32_hal_def.h" + + + +#define DMA_TIMEOUT_DEFAULT 1000000 /**< Стандартная задержка для ожидания timeout. */ + + +/** + * @brief Разрешить или запретить читать текущий статус канала. + * + * При разрешении чтения текущего статуса канала регистры CHx_DST, CHx_SRC, CHx_LEN возвращают текущие значения, + * а в CHx_CFG при считывании меняются битовые поля. + */ +typedef enum __HAL_DMA_CurrentValueTypeDef +{ + DMA_CURRENT_VALUE_ENABLE = 0, /**< Текущие значения. */ + DMA_CURRENT_VALUE_DISABLE = 1 /**< Значения при настройке. */ +} HAL_DMA_CurrentValueTypeDef; + +/** + * @brief Номер канала. + * + * При совпадении приоритетов каналов меньший номер канала является более приоритетным. + */ +typedef enum __HAL_DMA_ChannelIndexTypeDef +{ + DMA_CHANNEL_0 = 0, + DMA_CHANNEL_1 = 1, + DMA_CHANNEL_2 = 2, + DMA_CHANNEL_3 = 3 +} HAL_DMA_ChannelIndexTypeDef; + +/** + * @brief Приоритет канала. + * + * Арбитраж выбора канала происходит за два такта удержания линии запроса. + * Если одновременно поступают несколько запросов ПДП, то схема арбитража выбирает наиболее + * приоритетную линию запроса в соответствии с программной установкой каждого из каналов. + * При совпадении приоритетов каналов меньший номер канала является более приоритетным. + */ +typedef enum __HAL_DMA_ChannelPriorityTypeDef +{ + DMA_CHANNEL_PRIORITY_LOW = 0b00, /**< Низкий приоритет. */ + DMA_CHANNEL_PRIORITY_MEDIUM = 0b01, /**< Средний приоритет. */ + DMA_CHANNEL_PRIORITY_HIGH = 0b10, /**< Высокий приоритет. */ + DMA_CHANNEL_PRIORITY_VERY_HIGH = 0b11 /**< Высший приоритет. */ +} HAL_DMA_ChannelPriorityTypeDef; + +/** + * @brief Режим адресации источника или назначения. + */ +typedef enum __HAL_DMA_ChannelModeTypeDef +{ + DMA_CHANNEL_MODE_PERIPHERY = 0, /**< Режим адреса - периферия. */ + DMA_CHANNEL_MODE_MEMORY = 1 /**< Режим адреса - память. */ +} HAL_DMA_ChannelModeTypeDef; + + +/** + * @brief Наличие инкремента адреса источника или назначения. + */ +typedef enum __HAL_DMA_ChannelIncTypeDef +{ + DMA_CHANNEL_INC_DISABLE = 0, /* Адрес не инкрементируется. */ + DMA_CHANNEL_INC_ENABLE = 1 /* Адрес инкрементируется. */ +} HAL_DMA_ChannelIncTypeDef; + +/** + * @brief Разрядность адреса источника или назначения. + * @warning Разрядность должна быть кратна количеству байт пересылки (LEN). + */ +typedef enum __HAL_DMA_ChannelSizeTypeDef +{ + DMA_CHANNEL_SIZE_BYTE = 0, /**< Байт. */ + DMA_CHANNEL_SIZE_HALFWORD = 1, /**< Полуслово. */ + DMA_CHANNEL_SIZE_WORD = 2 /**< Слово. */ +} HAL_DMA_ChannelSizeTypeDef; + +/** + * @brief Периферийные линии источника или назначения. + */ +typedef enum __HAL_DMA_ChannelRequestTypeDef +{ + DMA_CHANNEL_USART_0_REQUEST = 0, + DMA_CHANNEL_USART_1_REQUEST = 1, + DMA_CHANNEL_CRYPTO_REQUEST = 2, + DMA_CHANNEL_SPI_0_REQUEST = 3, + DMA_CHANNEL_SPI_1_REQUEST = 4, + DMA_CHANNEL_I2C_0_REQUEST = 5, + DMA_CHANNEL_I2C_1_REQUEST = 6, + DMA_CHANNEL_SPIFI_REQUEST = 7, + DMA_CHANNEL_TIMER32_1_REQUEST = 8, + DMA_CHANNEL_TIMER32_2_REQUEST = 9, + +#ifdef MIK32V0 + DMA_CHANNEL_TIMER32_0_REQUEST = 10 +#else // MIK32V2 + DMA_CHANNEL_DAC_0_REQUEST = 10, + DMA_CHANNEL_DAC_1_REQUEST = 11, + DMA_CHANNEL_TIMER32_0_REQUEST = 12 +#endif // MIK32V0 + +} HAL_DMA_ChannelRequestTypeDef; + +/** + * @brief Разрешение работы логики с откликом для адресата источника и назначения. + * + * Используется при работе с Timer32. При работе логики с откликом пакет данных передается + * каждый раз при переполнении таймера. Если работа с откликом запрещена, то все пакеты передаются сразу после + * первого переполнения таймера. + */ +typedef enum +{ + DMA_CHANNEL_ACK_DISABLE = 0, /**< Работа логики с откликом запрещена. */ + DMA_CHANNEL_ACK_ENABLE = 1 /**< Работа логики с откликом разрешена. */ +} HAL_DMA_ChannelACKTypeDef; + +/** + * @brief Разрешение прерываний. + * + * Используется при настройке глобального прерывания DMA, прерывания DMA при возникновении ошибки и + * локального прерывания при завершении работы канала. + */ +typedef enum +{ + DMA_IRQ_DISABLE = 0, /* Прерывание запрещено. */ + DMA_IRQ_ENABLE = 1 /* Прерывание разрешено. */ +} HAL_DMA_IRQTypeDef; + +/** + * @brief Настройки канала DMA. + */ +typedef struct __DMA_ChannelInitHandleTypeDef +{ + HAL_DMA_ChannelIndexTypeDef Channel; /**< Номер канала. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelIndexTypeDef. */ + HAL_DMA_ChannelPriorityTypeDef Priority; /**< Приоритет канала. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelPriorityTypeDef. */ + + HAL_DMA_ChannelModeTypeDef ReadMode; /**< Режим адресации источника. Данный параметр может иметь значение #DMA_CHANNEL_MODE_PERIPHERY или #DMA_CHANNEL_MODE_MEMORY. */ + HAL_DMA_ChannelIncTypeDef ReadInc; /**< Наличие инкремента адреса источника. Данный параметр может иметь значение #DMA_CHANNEL_INC_DISABLE или #DMA_CHANNEL_INC_ENABLE. */ + HAL_DMA_ChannelSizeTypeDef ReadSize; /**< Разрядность адреса источника. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelSizeTypeDef. @warning Разрядность должна быть кратна количеству байт пересылки (LEN + 1). */ + HAL_DMA_ChannelACKTypeDef ReadAck; /**< Разрешение работы логики с откликом для адресата источника. Данный параметр может иметь значение #DMA_CHANNEL_ACK_DISABLE или #DMA_CHANNEL_ACK_ENABLE */ + uint32_t ReadBurstSize; /**< Количество байт в пакете. Определяется как 2^{ReadBurstSize}. @warning Количество байт в пакете должно быть кратно ReadSize. */ + HAL_DMA_ChannelRequestTypeDef ReadRequest; /**< Выбор периферийной линии источника при ReadMode = DMA_CHANNEL_MODE_PERIPHERY. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelRequestTypeDef. */ + + HAL_DMA_ChannelModeTypeDef WriteMode; /**< Режим адресации назначения. Данный параметр может иметь значение #DMA_CHANNEL_MODE_PERIPHERY или #DMA_CHANNEL_MODE_MEMORY. */ + HAL_DMA_ChannelIncTypeDef WriteInc; /**< Наличие инкремента адреса назначения. Данный параметр может иметь значение #DMA_CHANNEL_INC_DISABLE или #DMA_CHANNEL_INC_ENABLE. */ + HAL_DMA_ChannelSizeTypeDef WriteSize; /**< Разрядность адреса назначения. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelSizeTypeDef. @warning Разрядность должна быть кратна количеству байт пересылки (LEN + 1). */ + HAL_DMA_ChannelACKTypeDef WriteAck; /**< Разрешение работы логики с откликом для адресата назначения. Данный параметр может иметь значение #DMA_CHANNEL_ACK_DISABLE или #DMA_CHANNEL_ACK_ENABLE */ + uint32_t WriteBurstSize; /**< Количество байт в пакете. Определяется как 2^{WriteBurstSize}. @warning Количество байт в пакете должно быть кратно WriteSize. */ + HAL_DMA_ChannelRequestTypeDef WriteRequest; /**< Выбор периферийной линии назначения при ReadMode = DMA_CHANNEL_MODE_PERIPHERY. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelRequestTypeDef. */ + +} DMA_ChannelInitHandleTypeDef; + +/** + * @brief Структура для инициализации DMA. + */ +typedef struct __DMA_InitTypeDef +{ + DMA_CONFIG_TypeDef *Instance; /**< Базовый адрес регистров DMA. Этот параметр может иметь значение #DMA_CONFIG. */ + HAL_DMA_CurrentValueTypeDef CurrentValue; /**< Разрешить или запретить читать текущий статус канала. При значении #DMA_CURRENT_VALUE_ENABLE регистры CHx_DST, CHx_SRC, CHx_LEN возвращают текущие значения, а в CHx_CFG при считывании меняются битовые поля. При значении #DMA_CURRENT_VALUE_DISABLE регистры возвращают значения при настройке. */ +} DMA_InitTypeDef; + +/** + * @brief Структура для инициализации канала DMA. + */ +typedef struct __DMA_ChannelHandleTypeDef +{ + DMA_InitTypeDef *dma; /**< Указатель на структуру для инициализации DMA. */ + DMA_ChannelInitHandleTypeDef ChannelInit; /**< Настройки канала DMA. */ +} DMA_ChannelHandleTypeDef; + + +void HAL_DMA_MspInit(DMA_InitTypeDef* hdma); +void HAL_DMA_SetChannel(DMA_ChannelHandleTypeDef *hdma_channel, HAL_DMA_ChannelIndexTypeDef ChannelIndex); +void HAL_DMA_ClearLocalIrq(DMA_InitTypeDef *hdma); +void HAL_DMA_ClearGlobalIrq(DMA_InitTypeDef *hdma); +void HAL_DMA_ClearErrorIrq(DMA_InitTypeDef *hdma); +void HAL_DMA_ClearIrq(DMA_InitTypeDef *hdma); +void HAL_DMA_SetCurrentValue(DMA_InitTypeDef *hdma, HAL_DMA_CurrentValueTypeDef CurrentValue); +int HAL_DMA_GetChannelCurrentValue(DMA_InitTypeDef *hdma); +void HAL_DMA_GlobalIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission); +void HAL_DMA_ErrorIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission); +void HAL_DMA_LocalIRQEnable(DMA_ChannelHandleTypeDef* hdma_channel, HAL_DMA_IRQTypeDef Permission); +HAL_StatusTypeDef HAL_DMA_Init(DMA_InitTypeDef *hdma); +HAL_StatusTypeDef HAL_DMA_Wait(DMA_ChannelHandleTypeDef* hdma_channel, uint32_t Timeout); +int HAL_DMA_GetChannelReadyStatus(DMA_ChannelHandleTypeDef* hdma_channel); +int HAL_DMA_GetChannelIrq(DMA_ChannelHandleTypeDef* hdma_channel); +int HAL_DMA_GetBusError(DMA_ChannelHandleTypeDef* hdma_channel); +void HAL_DMA_ChannelDisable(DMA_ChannelHandleTypeDef *hdma_channel); +void HAL_DMA_ChannelEnable(DMA_ChannelHandleTypeDef *hdma_channel); +void HAL_DMA_Start(DMA_ChannelHandleTypeDef *hdma_channel, void* Source, void* Destination, uint32_t Len); + + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_eeprom.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_eeprom.h new file mode 100644 index 0000000..86f8836 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_eeprom.h @@ -0,0 +1,118 @@ +#ifndef MIK32_HAL_EEPROM_H_INCLUDED +#define MIK32_HAL_EEPROM_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_def.h" +#include +#include +#include + +#ifndef HAL_EEPROM_TIMEOUT +#define HAL_EEPROM_TIMEOUT 10000 +#endif + +typedef enum +{ + HAL_EEPROM_OP_READ = 0b00, + HAL_EEPROM_OP_CLEAR = 0b01, + HAL_EEPROM_OP_PROGRAM = 0b10, +} HAL_EEPROM_OperationTypeDef; + +typedef enum +{ + HAL_EEPROM_WRITE_SINGLE = 0b00, + HAL_EEPROM_WRITE_EVEN = 0b01, + HAL_EEPROM_WRITE_ODD = 0b10, + HAL_EEPROM_WRITE_ALL = 0b11, +} HAL_EEPROM_WriteBehaviourTypeDef; + +typedef enum +{ + HAL_EEPROM_MODE_TWO_STAGE = 0b00, + HAL_EEPROM_MODE_THREE_STAGE = 0b01, +} HAL_EEPROM_ModeTypeDef; + +typedef enum +{ + HAL_EEPROM_ECC_ENABLE = 0b00, + HAL_EEPROM_ECC_DISABLE = 0b01, +} HAL_EEPROM_ErrorCorrectionTypeDef; + +typedef enum +{ + HAL_EEPROM_SERR_DISABLE = 0b00, + HAL_EEPROM_SERR_ENABLE = 0b01, +} HAL_EEPROM_EnableInterruptTypeDef; + +typedef struct +{ + uint8_t N_LD; + uint8_t N_R_1; + uint8_t N_R_2; + uint32_t N_EP_1; + uint16_t N_EP_2; +} HAL_EEPROM_TimingsTypeDef; + +typedef struct +{ + EEPROM_REGS_TypeDef *Instance; + HAL_EEPROM_TimingsTypeDef Timings; + HAL_EEPROM_ModeTypeDef Mode; + HAL_EEPROM_ErrorCorrectionTypeDef ErrorCorrection; + HAL_EEPROM_EnableInterruptTypeDef EnableInterrupt; +} HAL_EEPROM_HandleTypeDef; + +static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_EEPROM_WaitBusy(HAL_EEPROM_HandleTypeDef *eeprom, uint32_t timeout) +{ + while (timeout) + { + timeout--; + if (!(eeprom->Instance->EESTA & EEPROM_EESTA_BSY_M)) + { + return HAL_OK; + } + } + + return HAL_TIMEOUT; +} + +#define HAL_EEPROM_INTERRUPT_GET(eeprom) ((*eeprom).Instance->EESTA & EEPROM_EESTA_SERR_M) +#define HAL_EEPROM_INTERRUPT_FLAG_CLEAR(eeprom) (*eeprom).Instance->EESTA &= ~EEPROM_EESTA_SERR_M; + +HAL_StatusTypeDef HAL_EEPROM_Init(HAL_EEPROM_HandleTypeDef *eeprom); + +HAL_StatusTypeDef HAL_EEPROM_Erase( + HAL_EEPROM_HandleTypeDef *eeprom, + uint16_t address, + uint8_t erasedWordsCount, + HAL_EEPROM_WriteBehaviourTypeDef erasedPages, + uint32_t timeout); + +HAL_StatusTypeDef HAL_EEPROM_Write( + HAL_EEPROM_HandleTypeDef *eeprom, + uint16_t address, + uint32_t *data, + uint8_t length, + HAL_EEPROM_WriteBehaviourTypeDef writedPages, + uint32_t timeout); + +HAL_StatusTypeDef HAL_EEPROM_Read(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint32_t *data, uint8_t length, uint32_t timeout); + +void HAL_EEPROM_SetMode(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ModeTypeDef mode); + +void HAL_EEPROM_SetErrorCorrection(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ErrorCorrectionTypeDef errorCorrection); + +void HAL_EEPROM_SetInterrupt(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_EnableInterruptTypeDef enableInterrupt); + +void HAL_EEPROM_CalculateTimings(HAL_EEPROM_HandleTypeDef *eeprom, int32_t frequency); + +HAL_StatusTypeDef HAL_EEPROM_GetECC(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint8_t *buf_value_ecc, uint32_t timeout); + +#ifdef __cplusplus +} +#endif + +#endif // MIK32_HAL_EEPROM_H_INCLUDED \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h new file mode 100644 index 0000000..b3a6776 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h @@ -0,0 +1,391 @@ +#ifndef MIK32_HAL_GPIO_NEW +#define MIK32_HAL_GPIO_NEW + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_def.h" +#include "pad_config.h" +#include "gpio.h" +#include "gpio_irq.h" +#include "mcu32_memory_map.h" +#include "mik32_hal_pcc.h" + +#define GPIO_MODE_BIT_LEVEL_S 0 /**< Позиция бита для режима LEVEL_SET (тип прерывания по уровню низкий/высокий или по событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */ +#define GPIO_MODE_BIT_EDGE_S 1 /**< Позиция бита для режима EDGE (тип прерывания уровень или событие) в перечислении @ref HAL_GPIO_InterruptMode. */ +#define GPIO_MODE_BIT_ANYEDGE_S 2 /**< Позиция бита для режима ANYEDGE (режим прерывания по любому событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */ +#define GPIO_MODE_BIT_LEVEL_M (1 << GPIO_MODE_BIT_LEVEL_S) /**< Маска для режима LEVEL_SET (тип прерывания по уровню низкий/высокий или по событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */ +#define GPIO_MODE_BIT_EDGE_M (1 << GPIO_MODE_BIT_EDGE_S) /**< Маска для режима EDGE (тип прерывания уровень или событие) в перечислении @ref HAL_GPIO_InterruptMode. */ +#define GPIO_MODE_BIT_ANYEDGE_M (1 << GPIO_MODE_BIT_ANYEDGE_S) /**< Маска для режима ANYEDGE (режим прерывания по любому событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */ +#define GPIO_IRQ_LINE_S 4 /**< Позиция номера канала в перечислении @ref HAL_GPIO_Line @ref и @ref HAL_GPIO_Line_Config. */ + +#define __LOW GPIO_PIN_LOW /**< Псевдоним @ref GPIO_PIN_LOW. Низкий выходной уровень GPIO. */ +#define __HIGH GPIO_PIN_HIGH /**< Псевдоним @ref GPIO_PIN_HIGH. Высокий выходной уровень GPIO. */ +#define __INPUT HAL_GPIO_MODE_GPIO_INPUT /**< Псевдоним @ref HAL_GPIO_MODE_GPIO_INPUT. Режим вывода - GPIO. Вход. */ +#define __OUTPUT HAL_GPIO_MODE_GPIO_OUTPUT /**< Псевдоним @ref HAL_GPIO_MODE_GPIO_OUTPUT. Режим вывода - GPIO. Выход. */ +#define __PULL_NONE HAL_GPIO_PULL_NONE /**< Псевдоним @ref HAL_GPIO_PULL_NONE. Подтяжка не подключаются. */ +#define __PULL_UP HAL_GPIO_PULL_UP /**< Псевдоним @ref HAL_GPIO_PULL_UP. Подтяжка к питанию. */ +#define __PULL_DOWN HAL_GPIO_PULL_DOWN /**< Псевдоним @ref HAL_GPIO_PULL_DOWN. Подтяжка к земле. */ +#define __DS_2MA HAL_GPIO_DS_2MA /**< Псевдоним @ref HAL_GPIO_DS_2MA. Режим драйвера 2мА. */ +#define __DS_4MA HAL_GPIO_DS_4MA /**< Псевдоним @ref HAL_GPIO_DS_4MA. Режим драйвера 4мА. */ +#define __DS_8MA HAL_GPIO_DS_8MA /**< Псевдоним @ref HAL_GPIO_DS_8MA. Режим драйвера 8мА. */ + +/** + * @brief Маска выводов. + */ +typedef enum __HAL_PinsTypeDef +{ + GPIO_PIN_0 = (1 << 0), /**< Выбран пин 0. */ + GPIO_PIN_1 = (1 << 1), /**< Выбран пин 1. */ + GPIO_PIN_2 = (1 << 2), /**< Выбран пин 2. */ + GPIO_PIN_3 = (1 << 3), /**< Выбран пин 3. */ + GPIO_PIN_4 = (1 << 4), /**< Выбран пин 4. */ + GPIO_PIN_5 = (1 << 5), /**< Выбран пин 5. */ + GPIO_PIN_6 = (1 << 6), /**< Выбран пин 6. */ + GPIO_PIN_7 = (1 << 7), /**< Выбран пин 7. */ + GPIO_PIN_8 = (1 << 8), /**< Выбран пин 8. */ + GPIO_PIN_9 = (1 << 9), /**< Выбран пин 9. */ + GPIO_PIN_10 = (1 << 10), /**< Выбран пин 10. */ + GPIO_PIN_11 = (1 << 11), /**< Выбран пин 11. */ + GPIO_PIN_12 = (1 << 12), /**< Выбран пин 12. */ + GPIO_PIN_13 = (1 << 13), /**< Выбран пин 13. */ + GPIO_PIN_14 = (1 << 14), /**< Выбран пин 14. */ + GPIO_PIN_15 = (1 << 15), /**< Выбран пин 15. */ + GPIO_PIN_ALL = 0xFFFF /**< Выбраны все пины порта. */ + +} HAL_PinsTypeDef; + +/** + * @brief Перечисление состояний выходного уровня GPIO. + */ +typedef enum __GPIO_PinState +{ + GPIO_PIN_LOW = 0, /**< Низкий выходной уровень GPIO. */ + GPIO_PIN_HIGH = 1 /**< Высокий выходной уровень GPIO.*/ +} GPIO_PinState; + +/** + * @brief Перечисление режимов вывода. + */ +typedef enum __HAL_GPIO_ModeTypeDef +{ +#ifdef MIK32V0 + HAL_GPIO_MODE_GPIO_INPUT = 0b101, /**< Режим вывода - GPIO. Вход. */ + HAL_GPIO_MODE_GPIO_OUTPUT = 0b001, /**< Режим вывода - GPIO. Выход. */ + HAL_GPIO_MODE_SERIAL = 0b00, /**< Режим вывода - последовательный интерфейс. */ +#else // MIK32V2 + HAL_GPIO_MODE_GPIO_INPUT = 0b100, /**< Режим вывода - GPIO. Вход. */ + HAL_GPIO_MODE_GPIO_OUTPUT = 0b000, /**< Режим вывода - GPIO. Выход. */ + HAL_GPIO_MODE_SERIAL = 0b01, /**< Режим вывода - последовательный интерфейс. */ +#endif // MIK32V0 + + HAL_GPIO_MODE_TIMER_SERIAL = 0b10, /**< Режим вывода - последовательный интерфейс или таймер. */ + HAL_GPIO_MODE_ANALOG = 0b11 /**< Аналоговый сигнал. */ +} HAL_GPIO_ModeTypeDef; + +/** + * @brief Перечисление режимов подтяжки. + */ +typedef enum __HAL_GPIO_PullTypeDef +{ + HAL_GPIO_PULL_NONE = 0b00, /**< Подтяжка не подключаются. */ + HAL_GPIO_PULL_UP = 0b01, /**< Подтяжка к питанию. */ + HAL_GPIO_PULL_DOWN = 0b10 /**< Подтяжка к земле. */ +} HAL_GPIO_PullTypeDef; + +/** + * @brief Перечисление режимов нагрузочной способности. + */ +typedef enum __HAL_GPIO_DSTypeDef +{ + HAL_GPIO_DS_2MA = 0b00, /**< Режим драйвера 2мА. */ + HAL_GPIO_DS_4MA = 0b01, /**< Режим драйвера 4мА. */ + HAL_GPIO_DS_8MA = 0b10 /**< Режим драйвера 8мА. */ +} HAL_GPIO_DSTypeDef; + +/** + * @brief Настройки для конфигурации выводов. + */ +typedef struct __GPIO_InitTypeDef +{ + /** + * @brief Маска выводов, к которым применяется инициализация.. + * + * Этот параметр является маской из значений @ref HAL_PinsTypeDef. + */ + HAL_PinsTypeDef Pin; + + /** + * @brief Режим выводов или направление GPIO. + * + * Этот параметр должен быть одним из значений: + * - @ref HAL_GPIO_MODE_GPIO_INPUT - режим вывода - GPIO. Вход + * - @ref HAL_GPIO_MODE_GPIO_OUTPUT - режим вывода - GPIO. Выход + * - @ref HAL_GPIO_MODE_SERIAL - режим вывода - последовательный интерфейс + * - @ref HAL_GPIO_MODE_TIMER_SERIAL - режим вывода - последовательный интерфейс или таймер + * - @ref HAL_GPIO_MODE_ANALOG - режим вывода аналоговый сигнал + */ + + /** + * @brief Режим выводов или направление GPIO. + * + * Этот параметр должен быть одним из значений: + * - @ref HAL_GPIO_MODE_GPIO_INPUT - режим вывода GPIO. Направление вывода как вход; + * - @ref HAL_GPIO_MODE_GPIO_OUTPUT - режим вывода GPIO. Направление вывода как выход; + * - @ref HAL_GPIO_MODE_SERIAL - режим вывода последовательный интерфейс; + * - @ref HAL_GPIO_MODE_TIMER_SERIAL - режим вывода последовательный интерфейс или таймер; + * - @ref HAL_GPIO_MODE_ANALOG - режим вывода аналоговый сигнал. + */ + HAL_GPIO_ModeTypeDef Mode; + + /** + * @brief Режим подтяжки. + * + * Этот параметр должен быть одним из значений: + * - @ref HAL_GPIO_PULL_NONE подтяжка не подключаются + * - @ref HAL_GPIO_PULL_UP подтяжка к питанию + * - @ref HAL_GPIO_PULL_DOWN подтяжка к земле + */ + HAL_GPIO_PullTypeDef Pull; + + /** + * @brief Нагрузочная способность выводов. + * + * Этот параметр должен быть одним из значений: + * - @ref HAL_GPIO_DS_2MA режим драйвера 2мА + * - @ref HAL_GPIO_DS_4MA режим драйвера 4мА + * - @ref HAL_GPIO_DS_8MA режим драйвера 8мА + */ + HAL_GPIO_DSTypeDef DS; +} GPIO_InitTypeDef; + +/** + * @brief Перечисление масок для линий внешних прерываний. + */ +typedef enum __HAL_GPIO_Line +{ + GPIO_LINE_0 = 0 << GPIO_IRQ_LINE_S, /**< Линия прерываний 0.*/ + GPIO_LINE_1 = 1 << GPIO_IRQ_LINE_S, /**< Линия прерываний 1.*/ + GPIO_LINE_2 = 2 << GPIO_IRQ_LINE_S, /**< Линия прерываний 2.*/ + GPIO_LINE_3 = 3 << GPIO_IRQ_LINE_S, /**< Линия прерываний 3.*/ + GPIO_LINE_4 = 4 << GPIO_IRQ_LINE_S, /**< Линия прерываний 4.*/ + GPIO_LINE_5 = 5 << GPIO_IRQ_LINE_S, /**< Линия прерываний 5.*/ + GPIO_LINE_6 = 6 << GPIO_IRQ_LINE_S, /**< Линия прерываний 6.*/ + GPIO_LINE_7 = 7 << GPIO_IRQ_LINE_S, /**< Линия прерываний 7.*/ +} HAL_GPIO_Line; + +/** + * @brief Конфигурация линии прерывания. + * + * @note значение представляется в виде 0b0LLLMMMM, где L - биты номера линии, M - биты выбранного входа мультиплексора линии. + */ +typedef enum __HAL_GPIO_Line_Config +{ + GPIO_MUX_LINE_0_PORT0_0 = 0 | GPIO_LINE_0, /**< PORT0_0 как вход для линии прерывания 0. */ + GPIO_MUX_LINE_0_PORT0_8 = 1 | GPIO_LINE_0, /**< PORT0_8 как вход для линии прерывания 0. */ + GPIO_MUX_LINE_0_PORT1_0 = 2 | GPIO_LINE_0, /**< PORT1_0 как вход для линии прерывания 0. */ + GPIO_MUX_LINE_0_PORT1_8 = 3 | GPIO_LINE_0, /**< PORT1_8 как вход для линии прерывания 0. */ + GPIO_MUX_LINE_0_PORT2_0 = 4 | GPIO_LINE_0, /**< PORT2_0 как вход для линии прерывания 0. */ + GPIO_MUX_LINE_0_PORT0_4 = 5 | GPIO_LINE_0, /**< PORT0_4 как вход для линии прерывания 0. */ + GPIO_MUX_LINE_0_PORT0_12 = 6 | GPIO_LINE_0, /**< PORT0_12 как вход для линии прерывания 0. */ + GPIO_MUX_LINE_0_PORT1_4 = 7 | GPIO_LINE_0, /**< PORT1_4 как вход для линии прерывания 0. */ + GPIO_MUX_LINE_0_PORT1_12 = 8 | GPIO_LINE_0, /**< PORT1_12 как вход для линии прерывания 0. */ + GPIO_MUX_LINE_0_PORT2_4 = 9 | GPIO_LINE_0, /**< PORT2_4 как вход для линии прерывания 0. */ + + GPIO_MUX_PORT0_0_LINE_0 = 0 | GPIO_LINE_0, /**< PORT0_0 как вход для линии прерывания 0. */ + GPIO_MUX_PORT0_8_LINE_0 = 1 | GPIO_LINE_0, /**< PORT0_8 как вход для линии прерывания 0. */ + GPIO_MUX_PORT1_0_LINE_0 = 2 | GPIO_LINE_0, /**< PORT1_0 как вход для линии прерывания 0. */ + GPIO_MUX_PORT1_8_LINE_0 = 3 | GPIO_LINE_0, /**< PORT1_8 как вход для линии прерывания 0. */ + GPIO_MUX_PORT2_0_LINE_0 = 4 | GPIO_LINE_0, /**< PORT2_0 как вход для линии прерывания 0. */ + GPIO_MUX_PORT0_4_LINE_0 = 5 | GPIO_LINE_0, /**< PORT0_4 как вход для линии прерывания 0. */ + GPIO_MUX_PORT0_12_LINE_0 = 6 | GPIO_LINE_0, /**< PORT0_12 как вход для линии прерывания 0. */ + GPIO_MUX_PORT1_4_LINE_0 = 7 | GPIO_LINE_0, /**< PORT1_4 как вход для линии прерывания 0. */ + GPIO_MUX_PORT1_12_LINE_0 = 8 | GPIO_LINE_0, /**< PORT1_12 как вход для линии прерывания 0. */ + GPIO_MUX_PORT2_4_LINE_0 = 9 | GPIO_LINE_0, /**< PORT2_4 как вход для линии прерывания 0. */ + + GPIO_MUX_LINE_1_PORT0_1 = 0 | GPIO_LINE_1, /**< PORT0_1 как вход для линии прерывания 1. */ + GPIO_MUX_LINE_1_PORT0_9 = 1 | GPIO_LINE_1, /**< PORT0_9 как вход для линии прерывания 1. */ + GPIO_MUX_LINE_1_PORT1_1 = 2 | GPIO_LINE_1, /**< PORT1_1 как вход для линии прерывания 1. */ + GPIO_MUX_LINE_1_PORT1_9 = 3 | GPIO_LINE_1, /**< PORT1_9 как вход для линии прерывания 1. */ + GPIO_MUX_LINE_1_PORT2_1 = 4 | GPIO_LINE_1, /**< PORT2_1 как вход для линии прерывания 1. */ + GPIO_MUX_LINE_1_PORT0_5 = 5 | GPIO_LINE_1, /**< PORT0_5 как вход для линии прерывания 1. */ + GPIO_MUX_LINE_1_PORT0_13 = 6 | GPIO_LINE_1, /**< PORT0_13 как вход для линии прерывания 1. */ + GPIO_MUX_LINE_1_PORT1_5 = 7 | GPIO_LINE_1, /**< PORT1_5 как вход для линии прерывания 1. */ + GPIO_MUX_LINE_1_PORT1_13 = 8 | GPIO_LINE_1, /**< PORT1_13 как вход для линии прерывания 1. */ + GPIO_MUX_LINE_1_PORT2_5 = 9 | GPIO_LINE_1, /**< PORT2_5 как вход для линии прерывания 1. */ + + GPIO_MUX_PORT0_1_LINE_1 = 0 | GPIO_LINE_1, /**< PORT0_1 как вход для линии прерывания 1. */ + GPIO_MUX_PORT0_9_LINE_1 = 1 | GPIO_LINE_1, /**< PORT0_9 как вход для линии прерывания 1. */ + GPIO_MUX_PORT1_1_LINE_1 = 2 | GPIO_LINE_1, /**< PORT1_1 как вход для линии прерывания 1. */ + GPIO_MUX_PORT1_9_LINE_1 = 3 | GPIO_LINE_1, /**< PORT1_9 как вход для линии прерывания 1. */ + GPIO_MUX_PORT2_1_LINE_1 = 4 | GPIO_LINE_1, /**< PORT2_1 как вход для линии прерывания 1. */ + GPIO_MUX_PORT0_5_LINE_1 = 5 | GPIO_LINE_1, /**< PORT0_5 как вход для линии прерывания 1. */ + GPIO_MUX_PORT0_13_LINE_1 = 6 | GPIO_LINE_1, /**< PORT0_13 как вход для линии прерывания 1. */ + GPIO_MUX_PORT1_5_LINE_1 = 7 | GPIO_LINE_1, /**< PORT1_5 как вход для линии прерывания 1. */ + GPIO_MUX_PORT1_13_LINE_1 = 8 | GPIO_LINE_1, /**< PORT1_13 как вход для линии прерывания 1. */ + GPIO_MUX_PORT2_5_LINE_1 = 9 | GPIO_LINE_1, /**< PORT2_5 как вход для линии прерывания 1. */ + + GPIO_MUX_LINE_2_PORT0_2 = 0 | GPIO_LINE_2, /**< PORT0_2 как вход для линии прерывания 2. */ + GPIO_MUX_LINE_2_PORT0_10 = 1 | GPIO_LINE_2, /**< PORT0_10 как вход для линии прерывания 2. */ + GPIO_MUX_LINE_2_PORT1_2 = 2 | GPIO_LINE_2, /**< PORT1_2 как вход для линии прерывания 2. */ + GPIO_MUX_LINE_2_PORT1_10 = 3 | GPIO_LINE_2, /**< PORT1_10 как вход для линии прерывания 2. */ + GPIO_MUX_LINE_2_PORT2_2 = 4 | GPIO_LINE_2, /**< PORT2_2 как вход для линии прерывания 2. */ + GPIO_MUX_LINE_2_PORT0_6 = 5 | GPIO_LINE_2, /**< PORT0_6 как вход для линии прерывания 2. */ + GPIO_MUX_LINE_2_PORT0_14 = 6 | GPIO_LINE_2, /**< PORT0_14 как вход для линии прерывания 2. */ + GPIO_MUX_LINE_2_PORT1_6 = 7 | GPIO_LINE_2, /**< PORT1_6 как вход для линии прерывания 2. */ + GPIO_MUX_LINE_2_PORT1_14 = 8 | GPIO_LINE_2, /**< PORT1_14 как вход для линии прерывания 2. */ + GPIO_MUX_LINE_2_PORT2_6 = 9 | GPIO_LINE_2, /**< PORT2_6 как вход для линии прерывания 2. */ + + GPIO_MUX_PORT0_2_LINE_2 = 0 | GPIO_LINE_2, /**< PORT0_2 как вход для линии прерывания 2. */ + GPIO_MUX_PORT0_10_LINE_2 = 1 | GPIO_LINE_2, /**< PORT0_10 как вход для линии прерывания 2. */ + GPIO_MUX_PORT1_2_LINE_2 = 2 | GPIO_LINE_2, /**< PORT1_2 как вход для линии прерывания 2. */ + GPIO_MUX_PORT1_10_LINE_2 = 3 | GPIO_LINE_2, /**< PORT1_10 как вход для линии прерывания 2. */ + GPIO_MUX_PORT2_2_LINE_2 = 4 | GPIO_LINE_2, /**< PORT2_2 как вход для линии прерывания 2. */ + GPIO_MUX_PORT0_6_LINE_2 = 5 | GPIO_LINE_2, /**< PORT0_6 как вход для линии прерывания 2. */ + GPIO_MUX_PORT0_14_LINE_2 = 6 | GPIO_LINE_2, /**< PORT0_14 как вход для линии прерывания 2. */ + GPIO_MUX_PORT1_6_LINE_2 = 7 | GPIO_LINE_2, /**< PORT1_6 как вход для линии прерывания 2. */ + GPIO_MUX_PORT1_14_LINE_2 = 8 | GPIO_LINE_2, /**< PORT1_14 как вход для линии прерывания 2. */ + GPIO_MUX_PORT2_6_LINE_2 = 9 | GPIO_LINE_2, /**< PORT2_6 как вход для линии прерывания 2. */ + + GPIO_MUX_LINE_3_PORT0_3 = 0 | GPIO_LINE_3, /**< PORT0_3 как вход для линии прерывания 3. */ + GPIO_MUX_LINE_3_PORT0_11 = 1 | GPIO_LINE_3, /**< PORT0_11 как вход для линии прерывания 3. */ + GPIO_MUX_LINE_3_PORT1_3 = 2 | GPIO_LINE_3, /**< PORT1_3 как вход для линии прерывания 3. */ + GPIO_MUX_LINE_3_PORT1_11 = 3 | GPIO_LINE_3, /**< PORT1_11 как вход для линии прерывания 3. */ + GPIO_MUX_LINE_3_PORT2_3 = 4 | GPIO_LINE_3, /**< PORT2_3 как вход для линии прерывания 3. */ + GPIO_MUX_LINE_3_PORT0_7 = 5 | GPIO_LINE_3, /**< PORT0_7 как вход для линии прерывания 3. */ + GPIO_MUX_LINE_3_PORT0_15 = 6 | GPIO_LINE_3, /**< PORT0_15 как вход для линии прерывания 3. */ + GPIO_MUX_LINE_3_PORT1_7 = 7 | GPIO_LINE_3, /**< PORT1_7 как вход для линии прерывания 3. */ + GPIO_MUX_LINE_3_PORT1_15 = 8 | GPIO_LINE_3, /**< PORT1_15 как вход для линии прерывания 3. */ + GPIO_MUX_LINE_3_PORT2_7 = 9 | GPIO_LINE_3, /**< PORT2_7 как вход для линии прерывания 3. */ + + GPIO_MUX_PORT0_3_LINE_3 = 0 | GPIO_LINE_3, /**< PORT0_3 как вход для линии прерывания 3. */ + GPIO_MUX_PORT0_11_LINE_3 = 1 | GPIO_LINE_3, /**< PORT0_11 как вход для линии прерывания 3. */ + GPIO_MUX_PORT1_3_LINE_3 = 2 | GPIO_LINE_3, /**< PORT1_3 как вход для линии прерывания 3. */ + GPIO_MUX_PORT1_11_LINE_3 = 3 | GPIO_LINE_3, /**< PORT1_11 как вход для линии прерывания 3. */ + GPIO_MUX_PORT2_3_LINE_3 = 4 | GPIO_LINE_3, /**< PORT2_3 как вход для линии прерывания 3. */ + GPIO_MUX_PORT0_7_LINE_3 = 5 | GPIO_LINE_3, /**< PORT0_7 как вход для линии прерывания 3. */ + GPIO_MUX_PORT0_15_LINE_3 = 6 | GPIO_LINE_3, /**< PORT0_15 как вход для линии прерывания 3. */ + GPIO_MUX_PORT1_7_LINE_3 = 7 | GPIO_LINE_3, /**< PORT1_7 как вход для линии прерывания 3. */ + GPIO_MUX_PORT1_15_LINE_3 = 8 | GPIO_LINE_3, /**< PORT1_15 как вход для линии прерывания 3. */ + GPIO_MUX_PORT2_7_LINE_3 = 9 | GPIO_LINE_3, /**< PORT2_7 как вход для линии прерывания 3. */ + + GPIO_MUX_LINE_4_PORT0_4 = 0 | GPIO_LINE_4, /**< PORT0_4 как вход для линии прерывания 4. */ + GPIO_MUX_LINE_4_PORT0_12 = 1 | GPIO_LINE_4, /**< PORT0_12 как вход для линии прерывания 4. */ + GPIO_MUX_LINE_4_PORT1_4 = 2 | GPIO_LINE_4, /**< PORT1_4 как вход для линии прерывания 4. */ + GPIO_MUX_LINE_4_PORT1_12 = 3 | GPIO_LINE_4, /**< PORT1_12 как вход для линии прерывания 4. */ + GPIO_MUX_LINE_4_PORT2_4 = 4 | GPIO_LINE_4, /**< PORT2_4 как вход для линии прерывания 4. */ + GPIO_MUX_LINE_4_PORT0_0 = 5 | GPIO_LINE_4, /**< PORT0_0 как вход для линии прерывания 4. */ + GPIO_MUX_LINE_4_PORT0_8 = 6 | GPIO_LINE_4, /**< PORT0_8 как вход для линии прерывания 4. */ + GPIO_MUX_LINE_4_PORT1_0 = 7 | GPIO_LINE_4, /**< PORT1_0 как вход для линии прерывания 4. */ + GPIO_MUX_LINE_4_PORT1_8 = 8 | GPIO_LINE_4, /**< PORT1_8 как вход для линии прерывания 4. */ + GPIO_MUX_LINE_4_PORT2_0 = 9 | GPIO_LINE_4, /**< PORT2_0 как вход для линии прерывания 4. */ + + GPIO_MUX_PORT0_4_LINE_4 = 0 | GPIO_LINE_4, /**< PORT0_4 как вход для линии прерывания 4. */ + GPIO_MUX_PORT0_12_LINE_4 = 1 | GPIO_LINE_4, /**< PORT0_12 как вход для линии прерывания 4. */ + GPIO_MUX_PORT1_4_LINE_4 = 2 | GPIO_LINE_4, /**< PORT1_4 как вход для линии прерывания 4. */ + GPIO_MUX_PORT1_12_LINE_4 = 3 | GPIO_LINE_4, /**< PORT1_12 как вход для линии прерывания 4. */ + GPIO_MUX_PORT2_4_LINE_4 = 4 | GPIO_LINE_4, /**< PORT2_4 как вход для линии прерывания 4. */ + GPIO_MUX_PORT0_0_LINE_4 = 5 | GPIO_LINE_4, /**< PORT0_0 как вход для линии прерывания 4. */ + GPIO_MUX_PORT0_8_LINE_4 = 6 | GPIO_LINE_4, /**< PORT0_8 как вход для линии прерывания 4. */ + GPIO_MUX_PORT1_0_LINE_4 = 7 | GPIO_LINE_4, /**< PORT1_0 как вход для линии прерывания 4. */ + GPIO_MUX_PORT1_8_LINE_4 = 8 | GPIO_LINE_4, /**< PORT1_8 как вход для линии прерывания 4. */ + GPIO_MUX_PORT2_0_LINE_4 = 9 | GPIO_LINE_4, /**< PORT2_0 как вход для линии прерывания 4. */ + + GPIO_MUX_LINE_5_PORT0_5 = 0 | GPIO_LINE_5, /**< PORT0_5 как вход для линии прерывания 5. */ + GPIO_MUX_LINE_5_PORT0_13 = 1 | GPIO_LINE_5, /**< PORT0_13 как вход для линии прерывания 5. */ + GPIO_MUX_LINE_5_PORT1_5 = 2 | GPIO_LINE_5, /**< PORT1_5 как вход для линии прерывания 5. */ + GPIO_MUX_LINE_5_PORT1_13 = 3 | GPIO_LINE_5, /**< PORT1_13 как вход для линии прерывания 5. */ + GPIO_MUX_LINE_5_PORT2_5 = 4 | GPIO_LINE_5, /**< PORT2_5 как вход для линии прерывания 5. */ + GPIO_MUX_LINE_5_PORT0_1 = 5 | GPIO_LINE_5, /**< PORT0_1 как вход для линии прерывания 5. */ + GPIO_MUX_LINE_5_PORT0_9 = 6 | GPIO_LINE_5, /**< PORT0_9 как вход для линии прерывания 5. */ + GPIO_MUX_LINE_5_PORT1_1 = 7 | GPIO_LINE_5, /**< PORT1_1 как вход для линии прерывания 5. */ + GPIO_MUX_LINE_5_PORT1_9 = 8 | GPIO_LINE_5, /**< PORT1_9 как вход для линии прерывания 5. */ + GPIO_MUX_LINE_5_PORT2_1 = 9 | GPIO_LINE_5, /**< PORT2_1 как вход для линии прерывания 5. */ + + GPIO_MUX_PORT0_5_LINE_5 = 0 | GPIO_LINE_5, /**< PORT0_5 как вход для линии прерывания 5. */ + GPIO_MUX_PORT0_13_LINE_5 = 1 | GPIO_LINE_5, /**< PORT0_13 как вход для линии прерывания 5. */ + GPIO_MUX_PORT1_5_LINE_5 = 2 | GPIO_LINE_5, /**< PORT1_5 как вход для линии прерывания 5. */ + GPIO_MUX_PORT1_13_LINE_5 = 3 | GPIO_LINE_5, /**< PORT1_13 как вход для линии прерывания 5. */ + GPIO_MUX_PORT2_5_LINE_5 = 4 | GPIO_LINE_5, /**< PORT2_5 как вход для линии прерывания 5. */ + GPIO_MUX_PORT0_1_LINE_5 = 5 | GPIO_LINE_5, /**< PORT0_1 как вход для линии прерывания 5. */ + GPIO_MUX_PORT0_9_LINE_5 = 6 | GPIO_LINE_5, /**< PORT0_9 как вход для линии прерывания 5. */ + GPIO_MUX_PORT1_1_LINE_5 = 7 | GPIO_LINE_5, /**< PORT1_1 как вход для линии прерывания 5. */ + GPIO_MUX_PORT1_9_LINE_5 = 8 | GPIO_LINE_5, /**< PORT1_9 как вход для линии прерывания 5. */ + GPIO_MUX_PORT2_1_LINE_5 = 9 | GPIO_LINE_5, /**< PORT2_1 как вход для линии прерывания 5. */ + + GPIO_MUX_LINE_6_PORT0_6 = 0 | GPIO_LINE_6, /**< PORT0_6 как вход для линии прерывания 6. */ + GPIO_MUX_LINE_6_PORT0_14 = 1 | GPIO_LINE_6, /**< PORT0_14 как вход для линии прерывания 6. */ + GPIO_MUX_LINE_6_PORT1_6 = 2 | GPIO_LINE_6, /**< PORT1_6 как вход для линии прерывания 6. */ + GPIO_MUX_LINE_6_PORT1_14 = 3 | GPIO_LINE_6, /**< PORT1_14 как вход для линии прерывания 6. */ + GPIO_MUX_LINE_6_PORT2_6 = 4 | GPIO_LINE_6, /**< PORT2_6 как вход для линии прерывания 6. */ + GPIO_MUX_LINE_6_PORT0_2 = 5 | GPIO_LINE_6, /**< PORT0_2 как вход для линии прерывания 6. */ + GPIO_MUX_LINE_6_PORT0_10 = 6 | GPIO_LINE_6, /**< PORT0_10 как вход для линии прерывания 6. */ + GPIO_MUX_LINE_6_PORT1_2 = 7 | GPIO_LINE_6, /**< PORT1_2 как вход для линии прерывания 6. */ + GPIO_MUX_LINE_6_PORT1_10 = 8 | GPIO_LINE_6, /**< PORT1_10 как вход для линии прерывания 6. */ + GPIO_MUX_LINE_6_PORT2_2 = 9 | GPIO_LINE_6, /**< PORT2_2 как вход для линии прерывания 6. */ + + GPIO_MUX_PORT0_6_LINE_6 = 0 | GPIO_LINE_6, /**< PORT0_6 как вход для линии прерывания 6. */ + GPIO_MUX_PORT0_14_LINE_6 = 1 | GPIO_LINE_6, /**< PORT0_14 как вход для линии прерывания 6. */ + GPIO_MUX_PORT1_6_LINE_6 = 2 | GPIO_LINE_6, /**< PORT1_6 как вход для линии прерывания 6. */ + GPIO_MUX_PORT1_14_LINE_6 = 3 | GPIO_LINE_6, /**< PORT1_14 как вход для линии прерывания 6. */ + GPIO_MUX_PORT2_6_LINE_6 = 4 | GPIO_LINE_6, /**< PORT2_6 как вход для линии прерывания 6. */ + GPIO_MUX_PORT0_2_LINE_6 = 5 | GPIO_LINE_6, /**< PORT0_2 как вход для линии прерывания 6. */ + GPIO_MUX_PORT0_10_LINE_6 = 6 | GPIO_LINE_6, /**< PORT0_10 как вход для линии прерывания 6. */ + GPIO_MUX_PORT1_2_LINE_6 = 7 | GPIO_LINE_6, /**< PORT1_2 как вход для линии прерывания 6. */ + GPIO_MUX_PORT1_10_LINE_6 = 8 | GPIO_LINE_6, /**< PORT1_10 как вход для линии прерывания 6. */ + GPIO_MUX_PORT2_2_LINE_6 = 9 | GPIO_LINE_6, /**< PORT2_2 как вход для линии прерывания 6. */ + + GPIO_MUX_LINE_7_PORT0_7 = 0 | GPIO_LINE_7, /**< PORT0_7 как вход для линии прерывания 7. */ + GPIO_MUX_LINE_7_PORT0_15 = 1 | GPIO_LINE_7, /**< PORT0_15 как вход для линии прерывания 7. */ + GPIO_MUX_LINE_7_PORT1_7 = 2 | GPIO_LINE_7, /**< PORT1_7 как вход для линии прерывания 7. */ + GPIO_MUX_LINE_7_PORT1_15 = 3 | GPIO_LINE_7, /**< PORT1_15 как вход для линии прерывания 7. */ + GPIO_MUX_LINE_7_PORT2_7 = 4 | GPIO_LINE_7, /**< PORT2_7 как вход для линии прерывания 7. */ + GPIO_MUX_LINE_7_PORT0_3 = 5 | GPIO_LINE_7, /**< PORT0_3 как вход для линии прерывания 7. */ + GPIO_MUX_LINE_7_PORT0_11 = 6 | GPIO_LINE_7, /**< PORT0_11 как вход для линии прерывания 7. */ + GPIO_MUX_LINE_7_PORT1_3 = 7 | GPIO_LINE_7, /**< PORT1_3 как вход для линии прерывания 7. */ + GPIO_MUX_LINE_7_PORT1_11 = 8 | GPIO_LINE_7, /**< PORT1_11 как вход для линии прерывания 7. */ + GPIO_MUX_LINE_7_PORT2_3 = 9 | GPIO_LINE_7, /**< PORT2_3 как вход для линии прерывания 7. */ + + GPIO_MUX_PORT0_7_LINE_7 = 0 | GPIO_LINE_7, /**< PORT0_7 как вход для линии прерывания 7. */ + GPIO_MUX_PORT0_15_LINE_7 = 1 | GPIO_LINE_7, /**< PORT0_15 как вход для линии прерывания 7. */ + GPIO_MUX_PORT1_7_LINE_7 = 2 | GPIO_LINE_7, /**< PORT1_7 как вход для линии прерывания 7. */ + GPIO_MUX_PORT1_15_LINE_7 = 3 | GPIO_LINE_7, /**< PORT1_15 как вход для линии прерывания 7. */ + GPIO_MUX_PORT2_7_LINE_7 = 4 | GPIO_LINE_7, /**< PORT2_7 как вход для линии прерывания 7. */ + GPIO_MUX_PORT0_3_LINE_7 = 5 | GPIO_LINE_7, /**< PORT0_3 как вход для линии прерывания 7. */ + GPIO_MUX_PORT0_11_LINE_7 = 6 | GPIO_LINE_7, /**< PORT0_11 как вход для линии прерывания 7. */ + GPIO_MUX_PORT1_3_LINE_7 = 7 | GPIO_LINE_7, /**< PORT1_3 как вход для линии прерывания 7. */ + GPIO_MUX_PORT1_11_LINE_7 = 8 | GPIO_LINE_7, /**< PORT1_11 как вход для линии прерывания 7. */ + GPIO_MUX_PORT2_3_LINE_7 = 9 | GPIO_LINE_7, /**< PORT2_3 как вход для линии прерывания 7. */ + +} HAL_GPIO_Line_Config; + +/** + * @brief Режим прерывания линии GPIO. + * \note Функция инициализации @ref HAL_GPIO_InitInterruptLine не включает прерывания GPIO в EPIC. + */ +typedef enum __HAL_GPIO_InterruptMode +{ + GPIO_INT_MODE_LOW = 0, /**< Режим прерывания по низкому уровню на выводе. */ + GPIO_INT_MODE_HIGH = GPIO_MODE_BIT_LEVEL_M, /**< Режим прерывания по высокому уровню на выводе. */ + GPIO_INT_MODE_FALLING = GPIO_MODE_BIT_EDGE_M, /**< Режим прерывания по смене уровня на выводе с высокого на низкий. */ + GPIO_INT_MODE_RISING = GPIO_MODE_BIT_LEVEL_M | GPIO_MODE_BIT_EDGE_M, /**< Режим прерывания по смене уровня на выводе с низкого на высокий. */ + GPIO_INT_MODE_CHANGE = GPIO_MODE_BIT_EDGE_M | GPIO_MODE_BIT_ANYEDGE_M, /**< Режим прерывания по изменению уровня на выводе. */ +} HAL_GPIO_InterruptMode; + +HAL_StatusTypeDef HAL_GPIO_Init(GPIO_TypeDef *GPIO_x, GPIO_InitTypeDef *GPIO_Init); +HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, HAL_GPIO_ModeTypeDef mode, HAL_GPIO_PullTypeDef pull, HAL_GPIO_DSTypeDef driveStrength); +GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin); +void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState); +void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin); +HAL_StatusTypeDef HAL_GPIO_InitInterruptLine(HAL_GPIO_Line_Config mux, HAL_GPIO_InterruptMode mode); +HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine); +uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine); +GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine); +void HAL_GPIO_ClearInterrupts(); + +#ifdef __cplusplus +} +#endif + +#endif // MIK32_HAL_GPIO \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_i2c.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_i2c.h new file mode 100644 index 0000000..68a5a6c --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_i2c.h @@ -0,0 +1,615 @@ +#ifndef MIK32_HAL_I2C +#define MIK32_HAL_I2C + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_pcc.h" +#include "mik32_hal_gpio.h" +#include "mik32_hal_def.h" +#include "i2c.h" +#include "mcu32_memory_map.h" +#include "mik32_hal_dma.h" + + +/* + * Define: I2C_TIMEOUT + * Количество циклов ожидания установки флага TXIS или RXNE + * + */ +#define I2C_TIMEOUT_DEFAULT 1000000 /* Количество циклов ожидания установки флага TXIS или RXNE */ +/* + * Define: I2C_NBYTE_MAX + * Максимальлное количество байт в посылке (NBYTES) + * + */ +#define I2C_NBYTE_MAX 255 /* Максимальное количество байт в посылке (NBYTES) */ + +#define I2C_ADDRESS_7BIT_MAX 0x7F /* Максимальный 7 битный адрес */ +#define I2C_ADDRESS_10BIT_MAX 0x3FF /* Максимальный 10 битный адрес */ + +#define I2C_INTMASK 0b11111110 /* Маска для разрешенных прерываний */ + +/* I2C_error - номера ошибок I2C*/ +/* Номер канала */ +typedef enum +{ + I2C_ERROR_NONE = 0, /* Ошибок нет */ + I2C_ERROR_TIMEOUT = 1, /* Превышено ожидание установки флага TXIS или RXNE */ + I2C_ERROR_NACK = 2, /* Во время передачи не получено подтверждение данных (NACK) */ + I2C_ERROR_BERR = 3, /* Ошибка шины */ + I2C_ERROR_ARLO = 4, /* Проигрыш арбитража */ + I2C_ERROR_OVR = 5, /* Переполнение или недозагрузка */ + I2C_ERROR_STOP = 6, /* Обнаружение STOP на линии */ +} HAL_I2C_ErrorTypeDef; + +/* I2C_addressing_mode - Режим адреса */ +typedef enum +{ + I2C_ADDRESSINGMODE_7BIT = 0, /* 7 битный адрес */ + I2C_ADDRESSINGMODE_10BIT = 1 /* 10 битный адрес */ +} HAL_I2C_AddressingModeTypeDef; + +/* I2C_dual_addressing_mode - Режим дополнительного адреса 7 бит */ +typedef enum +{ + I2C_DUALADDRESS_DISABLE = 0, /* Выключить дополнительный адрес */ + I2C_DUALADDRESS_ENABLE = 1 /* Включить дополнительный адрес */ +} HAL_I2C_DualAddressTypeDef; + +/* I2C_general_call_mode - Адрес общего вызова */ +typedef enum +{ + I2C_GENERALCALL_DISABLE = 0, /* Выключить адрес общего вызова */ + I2C_GENERALCALL_ENABLE = 1 /* Включить адрес общего вызова */ +} HAL_I2C_GeneralCallTypeDef; + +/* I2C_nostretch_mode - Режим удержания SCL ведомым */ +typedef enum +{ + I2C_NOSTRETCH_DISABLE = 0, /* Растягивание активно */ + I2C_NOSTRETCH_ENABLE = 1 /* растягивание выключено */ +} HAL_I2C_NoStretchModeTypeDef; + +/* I2C_sbc_mode - Режим аппаратного контроля байта ведомым */ +typedef enum +{ + I2C_SBC_DISABLE = 0, /* Аппаратный контроль выключен */ + I2C_SBC_ENABLE = 1 /* Аппаратный контроль включен */ +} HAL_I2C_SBCModeTypeDef; + +/* I2C_reload_mode - Режим перезаписи NBYTES: */ +typedef enum +{ + I2C_RELOAD_DISABLE = 0, /* Транзакция завершена после пересылки NBYTES байт данных (на шине ожидаются STOP или RESTART) */ + I2C_RELOAD_ENABLE = 1 /* Транзакция не завершена после пересылки NBYTES байт данных (значение NBYTES будет перезаписано) */ +} HAL_I2C_ReloadModeTypeDef; + +/* I2C_autoend_mode - Режим автоматического окончания */ +typedef enum +{ + I2C_AUTOEND_DISABLE = 0, /* Режим автоматического окончания отключен */ + I2C_AUTOEND_ENABLE = 1 /* Режим автоматического окончания включен */ +} HAL_I2C_AutoEndModeTypeDef; + +/* I2C_transfer_direction - Направление передачи */ +typedef enum +{ + I2C_TRANSFER_WRITE = 0, /* Ведущий запрашивает транзакцию записи */ + I2C_TRANSFER_READ = 1 /* Ведущий запрашивает транзакцию чтения */ +} HAL_I2C_TransferDirectionTypeDef; + +/* I2C_OwnAddress2_mask - Маска второго собственного адреса */ +typedef enum +{ + I2C_OWNADDRESS2_MASK_DISABLE = 0, /* Нет маски */ + I2C_OWNADDRESS2_MASK_111111x = 1, /* Сравниваются только OA2[7:2] */ + I2C_OWNADDRESS2_MASK_11111xx = 2, /* Сравниваются только OA2[7:3]; */ + I2C_OWNADDRESS2_MASK_1111xxx = 3, /* Сравниваются только OA2[7:4]; */ + I2C_OWNADDRESS2_MASK_111xxxx = 4, /* Сравниваются только OA2[7:5]; */ + I2C_OWNADDRESS2_MASK_11xxxxx = 5, /* Сравниваются только OA2[7:6]; */ + I2C_OWNADDRESS2_MASK_1xxxxxx = 6, /* Сравниваются только OA2[7]; */ + I2C_OWNADDRESS2_MASK_1111111 = 7 /* OA2[7:1] маскируются, подтверждаются (ACK) все 7-битные адреса (кроме зарезервированных) */ +} HAL_I2C_OwnAddress2MaskTypeDef; + +/* I2C_digital_filter - Цифровой фильтр */ +typedef enum +{ + I2C_DIGITALFILTER_OFF = 0, + I2C_DIGITALFILTER_1CLOCKCYCLES = 1, + I2C_DIGITALFILTER_2CLOCKCYCLES = 2, + I2C_DIGITALFILTER_15CLOCKCYCLES = 15 +} HAL_I2C_DigitalFilterTypeDef; + +/* I2C_analog_filter - Цифровой фильтр */ +typedef enum +{ + I2C_ANALOGFILTER_ENABLE = 0, + I2C_ANALOGFILTER_DISABLE = 1 +} HAL_I2C_AnalogFilterTypeDef; + +typedef enum +{ + HAL_I2C_MODE_MASTER = 0, /* Режим ведущего */ + HAL_I2C_MODE_SLAVE = 1, /* Режим ведомого */ + +} HAL_I2C_ModeTypeDef; + + +typedef struct +{ + + HAL_I2C_ModeTypeDef Mode; /* Режим ведомый или ведущий */ + + /* + * Variable: OwnAddress1 + * Основной собственный адрес. + * + * Когда включен дополнительный адрес, длинна основного адреса должна быть 7 бит. + * + * Этот параметр должен быть 7-битным или 10-битным числом + * + */ + uint32_t OwnAddress1; + + /* + * Variable: DualAddressMode + * Активация дополнительного 7 битного адреса + * + * Можно использовать, если длина основного адреса 7 бит + * + * Этот параметр должен быть одним из значений: + * + * - ; + * - . + * + * + */ + HAL_I2C_DualAddressTypeDef DualAddressMode; + + /* + * Variable: OwnAddress2 + * Дополнительный 7 битный адрес + * + * Можно использовать, если длина основного адреса 7 бит + * + * Этот параметр должен быть 7 битным числом. + * + */ + uint32_t OwnAddress2; + + HAL_I2C_GeneralCallTypeDef GeneralCall; + + /* + * Variable: OwnAddress2Mask + * Маска сравнения дополнительного 7 битного адреса + * + * Этот параметр должен быть одним из значений: + * + * - + * - + * - + * - + * - + * - + * - + * - + * + */ + HAL_I2C_OwnAddress2MaskTypeDef OwnAddress2Mask; + + /* + * Variable: NoStretchMode + * Растягивания тактового сигнала в режиме "ведомый". + * + * Не совместим с режимом SBC + * + * В режиме ведущий значение всегда I2C_NOSTRETCH_DISABLE + * + * Этот параметр должен быть одним из значений: + * + * - + * - + * + */ + HAL_I2C_NoStretchModeTypeDef NoStretchMode; + + /* + * Variable: SBCMode + * Режим аппаратного контроля передачи данных в режиме "ведомый" + * + * Не совместим с режимом NOSTRETCH + * + * Этот параметр должен быть одним из значений: + * + * - + * - + * + */ + HAL_I2C_SBCModeTypeDef SBCMode; + + /* + * Variable: AutoEnd + * Управление режимом автоматического окончания в режиме "ведущий" + * + * Этот параметр должен быть одним из значений: + * + * - + * - + * + */ + HAL_I2C_AutoEndModeTypeDef AutoEnd; + + /* + * Variable: Filter + * Цифровой фильтр + * + * Этот параметр должен быть одним из значений: + * + * - + * - + * - + * - + * + */ + HAL_I2C_DigitalFilterTypeDef DigitalFilter; + + HAL_I2C_AnalogFilterTypeDef AnalogFilter; + +} I2C_InitTypeDef; + +/* + * Struct: I2C_ClockTypeDef + * + * Настройки временных ограничений + * + */ +typedef struct +{ +/* + * Variable: PRESC + * Предварительный делитель частоты I2CCLK. + * + * Используется для вычисления значения t_PRESC используемого счетчиками предустановки, удержания, низкого и высокого уровней. + * + * Этот параметр может быть числом в пределах от 0 до 15 + * + */ + uint32_t PRESC; + +/* + * Variable: SCLDEL + * Длительность предустановки данных. + * + * Задержка между изменением SDA и фронтом SCL. + * + * Этот параметр может быть числом в пределах от 0 до 15. + * + */ + uint32_t SCLDEL; + +/* + * Variable: SDADEL + * Длительность предустановки данных. + * + * Задержка между спадом SCL и изменением SDA в режиме ведущего и ведомого при NOSTRETCH = 0. + * + * Этот параметр может быть числом в пределах от 0 до 15. + * + */ + uint32_t SDADEL; + +/* + * Variable: SCLH + * Длительность удержания SCL в состоянии логической "1" в режиме "ведущий". + * + * Этот параметр может быть от 0 до 255. + * + */ + uint32_t SCLH; + +/* + * Variable: SCLL + * Длительность удержания SCL в состоянии логического "0" в режиме "ведущий". + * + * Этот параметр может быть от 0 до 255. + * + */ + uint32_t SCLL; + +} I2C_ClockTypeDef; + +typedef enum +{ + HAL_I2C_STATE_READY, /* Готов к передаче */ + HAL_I2C_STATE_BUSY, /* Идет передача */ + HAL_I2C_STATE_END, /* Передача завершена */ + HAL_I2C_STATE_ERROR /* Ошибка при передаче */ +} HAL_I2C_StateTypeDef; + +typedef struct +{ + /* + * Variable: Instance + * Базовый адрес регистров I2C + * + */ + I2C_TypeDef *Instance; + + /* + * Variable: Init + * Параметры инициализации I2C + * + */ + I2C_InitTypeDef Init; + + /* + * Variable: Clock + * Параметры частоты I2C + * + */ + I2C_ClockTypeDef Clock; + + /* + * Variable: ErrorCode + * Код ошибки I2C + * + */ + HAL_I2C_ErrorTypeDef ErrorCode; + + /* + * Variable: hdmatx + * Канала DMA для отправки данных + */ + DMA_ChannelHandleTypeDef *hdmatx; + + /* + * Variable: hdmarx + * Канала DMA для приема данных + */ + DMA_ChannelHandleTypeDef *hdmarx; + + volatile HAL_I2C_StateTypeDef State; + + uint8_t *pBuffPtr; + uint32_t TransferSize; + uint32_t TransferCount; + +} I2C_HandleTypeDef; + + +void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c); +void HAL_I2C_Disable(I2C_HandleTypeDef *hi2c); +void HAL_I2C_Reset(I2C_HandleTypeDef *hi2c); +void HAL_I2C_Enable(I2C_HandleTypeDef *hi2c); +void HAL_I2C_AnalogFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_AnalogFilterTypeDef AnalogFilter); +void HAL_I2C_DigitalFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_DigitalFilterTypeDef DigitalFilter); +void HAL_I2C_SetClockSpeed(I2C_HandleTypeDef *hi2c); +void HAL_I2C_NoStretchMode(I2C_HandleTypeDef *hi2c, HAL_I2C_NoStretchModeTypeDef NoStretchMode); +void HAL_I2C_OwnAddress1(I2C_HandleTypeDef *hi2c); +void HAL_I2C_OwnAddress2(I2C_HandleTypeDef *hi2c); +void HAL_I2C_GeneralCall(I2C_HandleTypeDef *hi2c, HAL_I2C_GeneralCallTypeDef GeneralCall); +void HAL_I2C_SBCMode(I2C_HandleTypeDef *hi2c, HAL_I2C_SBCModeTypeDef SBCMode); +void HAL_I2C_SlaveInit(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MasterInit(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); +void HAL_I2C_AutoEnd(I2C_HandleTypeDef *hi2c, HAL_I2C_AutoEndModeTypeDef AutoEnd); +HAL_StatusTypeDef HAL_I2C_Master_WaitTXIS(I2C_HandleTypeDef *hi2c, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Master_WaitRXNE(I2C_HandleTypeDef *hi2c, uint32_t Timeout); +void HAL_I2C_Master_SlaveAddress(I2C_HandleTypeDef *hi2h, uint16_t SlaveAddress); +HAL_StatusTypeDef HAL_I2C_WaitBusy(I2C_HandleTypeDef *hi2c, uint32_t Timeout); +void HAL_I2C_Master_NBYTES(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_WaitADDR(I2C_HandleTypeDef *hi2c, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_WaitTXIS(I2C_HandleTypeDef *hi2c, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_WaitRXNE(I2C_HandleTypeDef *hi2c, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_WaitTCR(I2C_HandleTypeDef *hi2c, uint32_t Timeout); +void HAL_I2C_Slave_ACK(I2C_HandleTypeDef *hi2c); +void HAL_I2C_Slave_NACK(I2C_HandleTypeDef *hi2c); +extern HAL_StatusTypeDef HAL_I2C_Slave_SBC(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t ByteCount); +HAL_StatusTypeDef HAL_I2C_Slave_ReceiveSBC(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize); +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout); + +void HAL_I2C_InterruptDisable(I2C_HandleTypeDef *hi2c, uint32_t IntDisMask); +void HAL_I2C_InterruptEnable(I2C_HandleTypeDef *hi2c, uint32_t IntEnMask); +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize); +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_NOSTRETCH_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_NOSTRETCH_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize); +HAL_StatusTypeDef HAL_I2C_Slave_ReceiveSBC_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize); + +static inline __attribute__((always_inline)) void HAL_I2C_ADDR_IRQ(I2C_HandleTypeDef *hi2c) +{ + if (hi2c->Instance->CR1 & I2C_CR1_SBC_M) + { + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(0x1); + } + + /* Сброс флага ADDR */ + hi2c->Instance->ICR |= I2C_ICR_ADDRCF_M; +} + +static inline __attribute__((always_inline)) void HAL_I2C_ERR_IRQ(I2C_HandleTypeDef *hi2c) +{ + hi2c->State = HAL_I2C_STATE_ERROR; + /* Выключить все прерывания I2C */ + hi2c->Instance->CR1 &= ~I2C_INTMASK; + /* Сброс I2C */ + hi2c->ErrorCode = I2C_ERROR_NONE; + hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; + hi2c->Instance->CR1 |= I2C_CR1_PE_M; +} + +static inline __attribute__((always_inline)) void HAL_I2C_NACK_IRQ(I2C_HandleTypeDef *hi2c) +{ + hi2c->State = HAL_I2C_STATE_ERROR; + /* Выключить все прерывания I2C */ + hi2c->Instance->CR1 &= ~I2C_INTMASK; + /* Сброс I2C */ + hi2c->ErrorCode = I2C_ERROR_NONE; + hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; + hi2c->Instance->CR1 |= I2C_CR1_PE_M; +} + +static inline __attribute__((always_inline)) void HAL_I2C_STOP_IRQ(I2C_HandleTypeDef *hi2c) +{ + hi2c->State = HAL_I2C_STATE_END; + /* Сброс содержимого TXDR */ + hi2c->Instance->ISR |= I2C_ISR_TXE_M; + /* Сброс флага детектирования STOP на шине */ + hi2c->Instance->ICR |= I2C_ICR_STOPCF_M; +} + +static inline __attribute__((always_inline)) void HAL_I2C_TXIS_IRQ(I2C_HandleTypeDef *hi2c) +{ + hi2c->Instance->TXDR = *((uint8_t *)hi2c->pBuffPtr); + hi2c->pBuffPtr++; + hi2c->TransferCount++; + if (hi2c->TransferCount == hi2c->TransferSize) + { + hi2c->State = HAL_I2C_STATE_END; + } + + +} + +static inline __attribute__((always_inline)) void HAL_I2C_RXNE_IRQ(I2C_HandleTypeDef *hi2c) +{ + *((uint8_t *)hi2c->pBuffPtr) = (uint8_t)hi2c->Instance->RXDR; + + if (hi2c->Instance->CR1 & I2C_CR1_SBC_M) + { + if (HAL_I2C_Slave_SBC(hi2c, hi2c->pBuffPtr - hi2c->TransferCount, hi2c->TransferSize, hi2c->TransferCount) != HAL_OK) + { + hi2c->State = HAL_I2C_STATE_END; + /* Выключить все прерывания I2C */ + hi2c->Instance->CR1 &= ~I2C_INTMASK; + /* Сброс I2C */ + hi2c->ErrorCode = I2C_ERROR_NONE; + hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; + hi2c->Instance->CR1 |= I2C_CR1_PE_M; + + } + } + + + hi2c->pBuffPtr++; + hi2c->TransferCount++; + if (hi2c->TransferCount == hi2c->TransferSize) + { + hi2c->State = HAL_I2C_STATE_END; + } +} + +static inline __attribute__((always_inline)) void HAL_I2C_TCR_IRQ(I2C_HandleTypeDef *hi2c) +{ + if (hi2c->Instance->CR1 & I2C_CR1_SBC_M) + { + if (hi2c->TransferCount < hi2c->TransferSize) + { + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(0x1); + } + else + { + hi2c->State = HAL_I2C_STATE_END; + } + } + else + { + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + /* Подготовка перед отправкой */ + + if ((hi2c->TransferSize - hi2c->TransferCount) <= I2C_NBYTE_MAX) + { + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(hi2c->TransferSize - hi2c->TransferCount); + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + hi2c->Instance->CR2 &= ~I2C_CR2_AUTOEND_M; + hi2c->Instance->CR2 |= hi2c->Init.AutoEnd << I2C_CR2_AUTOEND_S; + } + else /* DataSize > 255 */ + { + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(I2C_NBYTE_MAX); + /* При RELOAD = 1 AUTOEND игнорируется */ + hi2c->Instance->CR2 |= I2C_CR2_RELOAD_M; + } + } +} + +static inline __attribute__((always_inline)) void HAL_I2C_TC_IRQ(I2C_HandleTypeDef *hi2c) +{ + hi2c->State = HAL_I2C_STATE_END; +} + +static inline __attribute__((always_inline)) void HAL_I2C_IRQHandler(I2C_HandleTypeDef *hi2c) +{ + uint32_t int_mask = hi2c->Instance->CR1 & I2C_INTMASK; /* разрешенные прерывания */ + uint32_t interrupt_status = hi2c->Instance->ISR; /* Флаги */ + + if ((interrupt_status & I2C_ISR_ADDR_M) && (int_mask & I2C_CR1_ADDRIE_M)) + { + // xprintf("ADDR\n"); + HAL_I2C_ADDR_IRQ(hi2c); + } + + if ((interrupt_status & (I2C_ISR_BERR_M | I2C_ISR_ARLO_M | I2C_ISR_OVR_M)) && (int_mask & I2C_CR1_ERRIE_M)) + { + // xprintf("Err, count %d, ISR %d\n", hi2c->TransferCount, hi2c->Instance->ISR); + HAL_I2C_ERR_IRQ(hi2c); + } + + if ((interrupt_status & I2C_ISR_NACKF_M) && (int_mask & I2C_CR1_NACKIE_M)) + { + // xprintf("NACK\n"); + HAL_I2C_NACK_IRQ(hi2c); + } + + if ((interrupt_status & I2C_ISR_STOPF_M) && (int_mask & I2C_CR1_STOPIE_M)) + { + // xprintf("Stop\n"); + HAL_I2C_STOP_IRQ(hi2c); + } + + if ((interrupt_status & I2C_ISR_TXIS_M) && (int_mask & I2C_CR1_TXIE_M)) + { + // xprintf("TXIS %d (%d)\n", hi2c->TransferCount, *((uint8_t *)hi2c->pBuffPtr)); + HAL_I2C_TXIS_IRQ(hi2c); + } + + if ((interrupt_status & I2C_ISR_RXNE_M) && (int_mask & I2C_CR1_RXIE_M)) + { + // xprintf("RXNE %d\n", hi2c->TransferCount); + HAL_I2C_RXNE_IRQ(hi2c); + } + + if ((interrupt_status & I2C_ISR_TCR_M) && (int_mask & I2C_CR1_TCIE_M)) + { + // xprintf("TCR\n"); + HAL_I2C_TCR_IRQ(hi2c); + } + + if ((interrupt_status & I2C_ISR_TC_M) && (int_mask & I2C_CR1_TCIE_M)) + { + // xprintf("TC\n"); + HAL_I2C_TC_IRQ(hi2c); + } + +} + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_irq.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_irq.h new file mode 100644 index 0000000..0b8ad2c --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_irq.h @@ -0,0 +1,333 @@ +#ifndef MIK32_HAL_IRQ +#define MIK32_HAL_IRQ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "epic.h" +#include "csr.h" +#include "scr1_csr_encoding.h" +#include "mcu32_memory_map.h" + + +/* Title: Макросы */ +#ifdef MIK32V0 + /* + * Defines: Маска линии прерывания + * + * + * HAL_EPIC_TIMER32_0_MASK - Маска для линии прерывания Timer32_0 + * HAL_EPIC_UART_0_MASK - Маска для линии прерывания USART_0 + * HAL_EPIC_UART_1_MASK - Маска для линии прерывания USART_1 + * HAL_EPIC_SPI_0_MASK - Маска для линии прерывания SPI_0 + * HAL_EPIC_SPI_1_MASK - Маска для линии прерывания SPI_1 + * HAL_EPIC_GPIO_IRQ_MASK - Маска для линии прерывания GPIO + * HAL_EPIC_I2C_0_MASK - Маска для линии прерывания I2C_0 + * HAL_EPIC_I2C_1_MASK - Маска для линии прерывания I2C_1 + * HAL_EPIC_WDT_MASK - Маска для линии прерывания Сторожевой таймер + * HAL_EPIC_TIMER16_0_MASK - Маска для линии прерывания Timer16_0 + * HAL_EPIC_TIMER16_1_MASK - Маска для линии прерывания Timer16_1 + * HAL_EPIC_TIMER16_2_MASK - Маска для линии прерывания Timer16_2 + * HAL_EPIC_TIMER32_1_MASK - Маска для линии прерывания Timer32_1 + * HAL_EPIC_TIMER32_2_MASK - Маска для линии прерывания Timer32_2 + * HAL_EPIC_SPIFI_MASK - Маска для линии прерывания SPIFI + * HAL_EPIC_RTC_MASK - Маска для линии прерывания RTC + * HAL_EPIC_EEPROM_MASK - Маска для линии прерывания EEPROM + * HAL_EPIC_WDT_DOM3_MASK - Маска для линии прерывания Сторожевой таймер шины (периферийные устройства) + * HAL_EPIC_WDT_SPIFI_MASK - Маска для линии прерывания Сторожевой таймер шины (SPIFI) + * HAL_EPIC_WDT_EEPROM_MASK - Маска для линии прерывания Сторожевой таймер шины (EEPROM) + * HAL_EPIC_DMA_GLB_ERR_MASK - Маска для линии прерывания ПДП глобальное прерывание + * HAL_EPIC_DMA_CHANNELS_MASK - Маска для линии прерывания ПДП локальное прерывание + * HAL_EPIC_FREQ_MON_MASK - Маска для линии прерывания Монитор частоты + * HAL_EPIC_PVD_AVCC_UNDER - Маска для линии прерывания Монитор напряжения AVCC (ниже порога) + * HAL_EPIC_PVD_AVCC_OVER - Маска для линии прерывания Монитор напряжения AVCC (выше порога) + * HAL_EPIC_PVD_VCC_UNDER - Маска для линии прерывания Монитор напряжения VCC (ниже порога) + * HAL_EPIC_PVD_VCC_OVER - Маска для линии прерывания Монитор напряжения VCC (выше порога) + * HAL_EPIC_BATTERY_NON_GOOD - Маска для линии прерывания Недостаточное напряжение батареи + * HAL_EPIC_BOR_MASK - Маска для линии прерывания BrouwnOut детектор + * HAL_EPIC_TSENS_MASK - Маска для линии прерывания Монитор температуры + * HAL_EPIC_ADC_MASK - Маска для линии прерывания АЦП + * + */ + #define HAL_EPIC_TIMER32_0_MASK ( 1 << EPIC_TIMER32_0_INDEX ) + #define HAL_EPIC_UART_0_MASK ( 1 << EPIC_UART_0_INDEX ) + #define HAL_EPIC_UART_1_MASK ( 1 << EPIC_UART_1_INDEX ) + #define HAL_EPIC_SPI_0_MASK ( 1 << EPIC_SPI_0_INDEX ) + #define HAL_EPIC_SPI_1_MASK ( 1 << EPIC_SPI_1_INDEX ) + #define HAL_EPIC_GPIO_IRQ_MASK ( 1 << EPIC_GPIO_IRQ_INDEX ) + #define HAL_EPIC_I2C_0_MASK ( 1 << EPIC_I2C_0_INDEX ) + #define HAL_EPIC_I2C_1_MASK ( 1 << EPIC_I2C_1_INDEX ) + #define HAL_EPIC_WDT_MASK ( 1 << EPIC_WDT_INDEX ) + #define HAL_EPIC_TIMER16_0_MASK ( 1 << EPIC_TIMER16_0_INDEX ) + #define HAL_EPIC_TIMER16_1_MASK ( 1 << EPIC_TIMER16_1_INDEX ) + #define HAL_EPIC_TIMER16_2_MASK ( 1 << EPIC_TIMER16_2_INDEX ) + #define HAL_EPIC_TIMER32_1_MASK ( 1 << EPIC_TIMER32_1_INDEX ) + #define HAL_EPIC_TIMER32_2_MASK ( 1 << EPIC_TIMER32_2_INDEX ) + #define HAL_EPIC_SPIFI_MASK ( 1 << EPIC_SPIFI_INDEX ) + #define HAL_EPIC_RTC_MASK ( 1 << EPIC_RTC_INDEX ) + #define HAL_EPIC_EEPROM_MASK ( 1 << EPIC_EEPROM_INDEX ) + #define HAL_EPIC_WDT_DOM3_MASK ( 1 << EPIC_WDT_DOM3_INDEX ) + #define HAL_EPIC_WDT_SPIFI_MASK ( 1 << EPIC_WDT_SPIFI_INDEX ) + #define HAL_EPIC_WDT_EEPROM_MASK ( 1 << EPIC_WDT_EEPROM_INDEX ) + #define HAL_EPIC_DMA_GLB_ERR_MASK ( 1 << EPIC_DMA_GLB_ERR_INDEX ) + #define HAL_EPIC_DMA_CHANNELS_MASK ( 1 << EPIC_DMA_CHANNELS_INDEX ) + #define HAL_EPIC_FREQ_MON_MASK ( 1 << EPIC_FREQ_MON_INDEX ) + #define HAL_EPIC_PVD_AVCC_UNDER ( 1 << EPIC_PVD_AVCC_UNDER ) + #define HAL_EPIC_PVD_AVCC_OVER ( 1 << EPIC_PVD_AVCC_OVER ) + #define HAL_EPIC_PVD_VCC_UNDER ( 1 << EPIC_PVD_VCC_UNDER ) + #define HAL_EPIC_PVD_VCC_OVER ( 1 << EPIC_PVD_VCC_OVER ) + #define HAL_EPIC_BATTERY_NON_GOOD ( 1 << EPIC_BATTERY_NON_GOOD ) + #define HAL_EPIC_BOR_MASK ( 1 << EPIC_BOR_INDEX ) + #define HAL_EPIC_TSENS_MASK ( 1 << EPIC_TSENS_INDEX ) + #define HAL_EPIC_ADC_MASK ( 1 << EPIC_ADC_INDEX ) + + /* + * macros: Проверка флагов линий прерываний в EPIC + * + * + * EPIC_CHECK_Timer32_0 - Проверка флага Timer32_0 + * EPIC_CHECK_UART_0 - Проверка флага USART_0 + * EPIC_CHECK_UART_1 - Проверка флага USART_1 + * EPIC_CHECK_SPI_0 - Проверка флага SPI_0 + * EPIC_CHECK_SPI_1 - Проверка флага SPI_1 + * EPIC_CHECK_GPIO - Проверка флага GPIO + * EPIC_CHECK_I2C_0 - Проверка флага I2C_0 + * EPIC_CHECK_I2C_1 - Проверка флага I2C_1 + * EPIC_CHECK_WDT - Проверка флага Сторожевой таймер + * EPIC_CHECK_TIMER16_0 - Проверка флага Timer16_0 + * EPIC_CHECK_TIMER16_1 - Проверка флага Timer16_1 + * EPIC_CHECK_TIMER16_2 - Проверка флага Timer16_2 + * EPIC_CHECK_TIMER32_1 - Проверка флага Timer32_1 + * EPIC_CHECK_TIMER32_2 - Проверка флага Timer32_2 + * EPIC_CHECK_SPIFI - Проверка флага SPIFI + * EPIC_CHECK_RTC - Проверка флага RTC + * EPIC_CHECK_EEPROM - Проверка флага EEPROM + * EPIC_CHECK_WDT_DOM3 - Проверка флага Сторожевой таймер шины (периферийные устройства) + * EPIC_CHECK_WDT_SPIFI - Проверка флага Сторожевой таймер шины (SPIFI) + * EPIC_CHECK_WDT_EEPROM - Проверка флага Сторожевой таймер шины (EEPROM) + * EPIC_CHECK_DMA_GLB_ERR - Проверка флага ПДП глобальное прерывание + * EPIC_CHECK_DMA_CHANNELS - Проверка флага ПДП локальное прерывание + * EPIC_CHECK_FREQ_MON - Проверка флага Монитор частоты + * EPIC_CHECK_PVD_AVCC_UNDER - Проверка флага Монитор напряжения AVCC (ниже порога) + * EPIC_CHECK_PVD_AVCC_OVER - Проверка флага Монитор напряжения AVCC (выше порога) + * EPIC_CHECK_PVD_VCC_UNDER - Проверка флага Монитор напряжения VCC (ниже порога) + * EPIC_CHECK_PVD_VCC_OVER - Проверка флага Монитор напряжения VCC (выше порога) + * EPIC_CHECK_BATTERY_NON_GOOD - Проверка флага Недостаточное напряжение батареи + * EPIC_CHECK_BOR - Проверка флага BrouwnOut детектор + * EPIC_CHECK_TSENS - Проверка флага Монитор температуры + * EPIC_CHECK_ADC - Проверка флага АЦП + * + */ + #define EPIC_CHECK_TIMER32_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_0_INDEX)) + #define EPIC_CHECK_UART_0() (EPIC->RAW_STATUS & (1 << EPIC_UART_0_INDEX)) + #define EPIC_CHECK_UART_1() (EPIC->RAW_STATUS & (1 << EPIC_UART_1_INDEX)) + #define EPIC_CHECK_SPI_0() (EPIC->RAW_STATUS & (1 << EPIC_SPI_0_INDEX)) + #define EPIC_CHECK_SPI_1() (EPIC->RAW_STATUS & (1 << EPIC_SPI_1_INDEX)) + #define EPIC_CHECK_GPIO_IRQ() (EPIC->RAW_STATUS & (1 << EPIC_GPIO_IRQ_INDEX)) + #define EPIC_CHECK_I2C_0() (EPIC->RAW_STATUS & (1 << EPIC_I2C_0_INDEX)) + #define EPIC_CHECK_I2C_1() (EPIC->RAW_STATUS & (1 << EPIC_I2C_1_INDEX)) + #define EPIC_CHECK_WDT() (EPIC->STATUS & (1 << EPIC_WDT_INDEX)) + #define EPIC_CHECK_TIMER16_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_0_INDEX)) + #define EPIC_CHECK_TIMER16_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_1_INDEX)) + #define EPIC_CHECK_TIMER16_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_2_INDEX)) + #define EPIC_CHECK_TIMER32_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_1_INDEX)) + #define EPIC_CHECK_TIMER32_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_2_INDEX)) + #define EPIC_CHECK_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_SPIFI_INDEX)) + #define EPIC_CHECK_RTC() (EPIC->RAW_STATUS & (1 << EPIC_RTC_INDEX)) + #define EPIC_CHECK_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_EEPROM_INDEX)) + #define EPIC_CHECK_WDT_DOM3() (EPIC->RAW_STATUS & (1 << EPIC_WDT_DOM3_INDEX)) + #define EPIC_CHECK_WDT_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_WDT_SPIFI_INDEX)) + #define EPIC_CHECK_WDT_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_WDT_EEPROM_INDEX)) + #define EPIC_CHECK_DMA_GLB_ERR() (EPIC->RAW_STATUS & (1 << EPIC_DMA_GLB_ERR_INDEX)) + #define EPIC_CHECK_DMA_CHANNELS() (EPIC->RAW_STATUS & (1 << EPIC_DMA_CHANNELS_INDEX)) + #define EPIC_CHECK_FREQ_MON() (EPIC->STATUS & (1 << EPIC_FREQ_MON_INDEX)) + #define EPIC_CHECK_PVD_AVCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_UNDER)) + #define EPIC_CHECK_PVD_AVCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_OVER)) + #define EPIC_CHECK_PVD_VCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_UNDER)) + #define EPIC_CHECK_PVD_VCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_OVER)) + #define EPIC_CHECK_BATTERY_NON_GOOD() (EPIC->STATUS & (1 << EPIC_BATTERY_NON_GOOD)) + #define EPIC_CHECK_BOR() (EPIC->STATUS & (1 << EPIC_BOR_INDEX)) + #define EPIC_CHECK_TSENS() (EPIC->RAW_STATUS & (1 << EPIC_TSENS_INDEX)) + #define EPIC_CHECK_ADC() (EPIC->STATUS & (1 << EPIC_ADC_INDEX)) +#else // MIK32V2 + #define HAL_EPIC_TIMER32_0_MASK (1 << EPIC_TIMER32_0_INDEX) + #define HAL_EPIC_UART_0_MASK (1 << EPIC_UART_0_INDEX) + #define HAL_EPIC_UART_1_MASK (1 << EPIC_UART_1_INDEX) + #define HAL_EPIC_SPI_0_MASK (1 << EPIC_SPI_0_INDEX) + #define HAL_EPIC_SPI_1_MASK (1 << EPIC_SPI_1_INDEX) + #define HAL_EPIC_GPIO_IRQ_MASK (1 << EPIC_GPIO_IRQ_INDEX) + #define HAL_EPIC_I2C_0_MASK (1 << EPIC_I2C_0_INDEX) + #define HAL_EPIC_I2C_1_MASK (1 << EPIC_I2C_1_INDEX) + #define HAL_EPIC_WDT_MASK (1 << EPIC_WDT_INDEX) + #define HAL_EPIC_TIMER16_0_MASK (1 << EPIC_TIMER16_0_INDEX) + #define HAL_EPIC_TIMER16_1_MASK (1 << EPIC_TIMER16_1_INDEX) + #define HAL_EPIC_TIMER16_2_MASK (1 << EPIC_TIMER16_2_INDEX) + #define HAL_EPIC_TIMER32_1_MASK (1 << EPIC_TIMER32_1_INDEX) + #define HAL_EPIC_TIMER32_2_MASK (1 << EPIC_TIMER32_2_INDEX) + #define HAL_EPIC_SPIFI_MASK (1 << EPIC_SPIFI_INDEX) + #define HAL_EPIC_RTC_MASK (1 << EPIC_RTC_INDEX) + #define HAL_EPIC_EEPROM_MASK (1 << EPIC_EEPROM_INDEX) + #define HAL_EPIC_WDT_DOM3_MASK (1 << EPIC_WDT_DOM3_INDEX) + #define HAL_EPIC_WDT_SPIFI_MASK (1 << EPIC_WDT_SPIFI_INDEX) + #define HAL_EPIC_WDT_EEPROM_MASK (1 << EPIC_WDT_EEPROM_INDEX) + #define HAL_EPIC_DMA_MASK (1 << EPIC_DMA_INDEX) + #define HAL_EPIC_FREQ_MON_MASK (1 << EPIC_FREQ_MON_INDEX) + #define HAL_EPIC_PVD_AVCC_MASK (1 << EPIC_PVD_AVCC_UNDER) + #define HAL_EPIC_PVD_AVCCMASK (1 << EPIC_PVD_AVCC_OVER) + #define HAL_EPIC_PVD_VCC_MASK (1 << EPIC_PVD_VCC_UNDER) + #define HAL_EPIC_PVD_VCCMASK (1 << EPIC_PVD_VCC_OVER) + #define HAL_EPIC_BATTERY_NONMASK (1 << EPIC_BATTERY_NON_GOOD) + #define HAL_EPIC_BOR_MASK (1 << EPIC_BOR_INDEX) + #define HAL_EPIC_TSENS_MASK (1 << EPIC_TSENS_INDEX) + #define HAL_EPIC_ADC_MASK (1 << EPIC_ADC_INDEX) + #define HAL_EPIC_DAC0_MASK (1 << EPIC_DAC0_INDEX) + #define HAL_EPIC_DAC1_MASK (1 << EPIC_DAC1_INDEX) + + #define EPIC_CHECK_TIMER32_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_0_INDEX)) + #define EPIC_CHECK_UART_0() (EPIC->RAW_STATUS & (1 << EPIC_UART_0_INDEX)) + #define EPIC_CHECK_UART_1() (EPIC->RAW_STATUS & (1 << EPIC_UART_1_INDEX)) + #define EPIC_CHECK_SPI_0() (EPIC->RAW_STATUS & (1 << EPIC_SPI_0_INDEX)) + #define EPIC_CHECK_SPI_1() (EPIC->RAW_STATUS & (1 << EPIC_SPI_1_INDEX)) + #define EPIC_CHECK_GPIO_IRQ() (EPIC->RAW_STATUS & (1 << EPIC_GPIO_IRQ_INDEX)) + #define EPIC_CHECK_I2C_0() (EPIC->RAW_STATUS & (1 << EPIC_I2C_0_INDEX)) + #define EPIC_CHECK_I2C_1() (EPIC->RAW_STATUS & (1 << EPIC_I2C_1_INDEX)) + #define EPIC_CHECK_WDT() (EPIC->STATUS & (1 << EPIC_WDT_INDEX)) + #define EPIC_CHECK_TIMER16_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_0_INDEX)) + #define EPIC_CHECK_TIMER16_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_1_INDEX)) + #define EPIC_CHECK_TIMER16_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_2_INDEX)) + #define EPIC_CHECK_TIMER32_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_1_INDEX)) + #define EPIC_CHECK_TIMER32_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_2_INDEX)) + #define EPIC_CHECK_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_SPIFI_INDEX)) + #define EPIC_CHECK_RTC() (EPIC->RAW_STATUS & (1 << EPIC_RTC_INDEX)) + #define EPIC_CHECK_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_EEPROM_INDEX)) + #define EPIC_CHECK_WDT_DOM3() (EPIC->RAW_STATUS & (1 << EPIC_WDT_DOM3_INDEX)) + #define EPIC_CHECK_WDT_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_WDT_SPIFI_INDEX)) + #define EPIC_CHECK_WDT_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_WDT_EEPROM_INDEX)) + #define EPIC_CHECK_DMA() (EPIC->RAW_STATUS & (1 << EPIC_DMA_INDEX)) + #define EPIC_CHECK_FREQ_MON() (EPIC->STATUS & (1 << EPIC_FREQ_MON_INDEX)) + #define EPIC_CHECK_PVD_AVCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_UNDER)) + #define EPIC_CHECK_PVD_AVCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_OVER)) + #define EPIC_CHECK_PVD_VCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_UNDER)) + #define EPIC_CHECK_PVD_VCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_OVER)) + #define EPIC_CHECK_BATTERY_NON_GOOD() (EPIC->STATUS & (1 << EPIC_BATTERY_NON_GOOD)) + #define EPIC_CHECK_BOR() (EPIC->STATUS & (1 << EPIC_BOR_INDEX)) + #define EPIC_CHECK_TSENS() (EPIC->RAW_STATUS & (1 << EPIC_TSENS_INDEX)) + #define EPIC_CHECK_ADC() (EPIC->STATUS & (1 << EPIC_ADC_INDEX)) + #define EPIC_CHECK_DAC0() (EPIC->STATUS & (1 << EPIC_DAC0_INDEX)) + #define EPIC_CHECK_DAC1() (EPIC->STATUS & (1 << EPIC_DAC1_INDEX)) +#endif // MIK32V0 + + + +/* + * Function: HAL_IRQ_EnableInterrupts + * Разрешить глобальные прерывания. + * + * Разрешается машинное программное прерывание. + * + * Returns: + * void. + */ +void HAL_IRQ_EnableInterrupts(); + +/* + * Function: HAL_IRQ_DisableInterrupts + * Запретить машинное программное прерывание. + * + * Глобальные прерывания не запрещаются. + * + * Returns: + * void. + */ +void HAL_IRQ_DisableInterrupts(); +/* Прерывание по фронту */ + +/* + * Function: HAL_EPIC_MaskSet + * Задать маску разрешенных линий прерываний по фронту + * + * Parameters: + * InterruptMask - Маска разрешенных линий прерываний + * + * Returns: + * void. + */ +void HAL_EPIC_MaskEdgeSet(uint32_t InterruptMask); + +/* + * Function: HAL_EPIC_MaskClear + * Сбросить маску разрешенный линий прерываний по фронту + * + * Parameters: + * InterruptMask - Маска сбрасываемых линий прерываний + * + * Returns: + * void. + */ +void HAL_EPIC_MaskEdgeClear(uint32_t InterruptMask); + +/* + * Function: HAL_EPIC_MaskSet + * Задать маску разрешенных линий прерываний по уровню + * + * Parameters: + * InterruptMask - Маска разрешенных линий прерываний + * + * Returns: + * void. + */ +void HAL_EPIC_MaskLevelSet(uint32_t InterruptMask); + +/* + * Function: HAL_EPIC_MaskClear + * Сбросить маску разрешенный линий прерываний по уровню + * + * Parameters: + * InterruptMask - Маска сбрасываемых линий прерываний + * + * Returns: + * void. + */ +void HAL_EPIC_MaskLevelClear(uint32_t InterruptMask); + +/* + * Function: HAL_EPIC_Clear + * Сбросить прерывания + * + * Parameters: + * InterruptMask - Маска сбрасываемых линий прерываний + * + * Returns: + * void. + */ +static inline __attribute__((always_inline)) void HAL_EPIC_Clear(uint32_t InterruptMask) +{ + EPIC->CLEAR = InterruptMask; +} + +/* + * Function: HAL_EPIC_GetStatus + * Получить текущий статус прерываний в соответствии с маской разрешенных прерываний + * + * Returns: + * (uint32_t ) - Текущий статус прерываний в соответствии с маской разрешенных прерываний + */ +uint32_t HAL_EPIC_GetStatus(); + +/* + * Function: HAL_EPIC_GetRawStatus + * Получить текущий статус прерываний + * + * В данном статусе маска разрешенных прерываний не учитывается + * + * Returns: + * (uint32_t ) - текущий статус прерываний + */ +uint32_t HAL_EPIC_GetRawStatus(); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_otp.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_otp.h new file mode 100644 index 0000000..dc753f2 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_otp.h @@ -0,0 +1,71 @@ +#ifndef MIK32_HAL_OTP +#define MIK32_HAL_OTP + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_pcc.h" +#include "mik32_hal_gpio.h" +#include "power_manager.h" +#include "otp.h" +#include "pad_config.h" +#include "stdbool.h" +#include "mcu32_memory_map.h" + + +/* Выбор напряжения на UPP матрицы. */ +#define OTP_UPP_READ_2V 0b000 /**< 2 В. */ +#define OTP_UPP_READ_2_5V 0b001 /**< 2,5 В. */ +#define OTP_UPP_READ_3V 0b011 /**< 3 В. */ +#define OTP_UPP_READ_VDD18 0b010 /**< VDD18. */ +#define OTP_UPP_READ_VDD5 0b110 /**< VDD5. */ + +/* Выбор тока считывания. */ +#define OTP_READ_CUR_2 0 /**< 2 мкА. */ +#define OTP_READ_CUR_0_2 1 /**< 0,2 мкА. */ + +#define OTP_POWER_OFF 1 /**< Hard IP введен в режим пониженного энергопотребления, операции записи и чтения запрещены. */ +#define OTP_POWER_ON 0 /**< Hard IP выведен из режима пониженного энергопотребления и может выполнять операции чтения и записи. */ + + +/* Режим чтения. */ +#define OPT_READ_2STAGES 0 /**< Чтение в 2 этапа. Вводятся такты ожидания APB. */ +#define OPT_READ_3STAGES 1 /**< Чтение в 3 этапа. Опрос флага BSY. Нет тактов ожидания APB. */ + + +/** + * @brief Настройки OTP. + * + */ +typedef struct __OTP_HandleTypeDef +{ + OTP_TypeDef *Instance; /**< Базовый адрес регистров OTP. */ + + uint8_t ReadMode; /**< Режим чтения. */ + +} OTP_HandleTypeDef; + + +void HAL_OTP_MspInit(OTP_HandleTypeDef* hotp); +void HAL_OTP_PowerOff(OTP_HandleTypeDef *hotp, uint8_t PowerOff); +void HAL_OTP_SetUppRead(OTP_HandleTypeDef *hotp, uint8_t UppReadVoltage); +void HAL_OTP_SetReadCur(OTP_HandleTypeDef *hotp, uint8_t ReadCur); +void HAL_OPT_TimeInit(OTP_HandleTypeDef *hotp); +void HAL_OTP_Init(OTP_HandleTypeDef *hotp); +void HAL_OTP_WaitBSY(OTP_HandleTypeDef *hotp); +void HAL_OTP_WriteTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength); +void HAL_OTP_WriteTestRow(OTP_HandleTypeDef *hotp, uint32_t Data); +void HAL_OTP_WriteTestBit(OTP_HandleTypeDef *hotp, uint32_t Data); +void HAL_OTP_Write(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength); +void HAL_OTP_ReadTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength); +uint32_t HAL_OTP_ReadTestRow(OTP_HandleTypeDef *hotp); +uint32_t HAL_OTP_ReadTestBit(OTP_HandleTypeDef *hotp); +void HAL_OTP_Read(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength); + + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_pcc.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_pcc.h new file mode 100644 index 0000000..ace7a7d --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_pcc.h @@ -0,0 +1,280 @@ +#ifndef MIK32_HAL_PCC +#define MIK32_HAL_PCC + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wakeup.h" +#include "power_manager.h" +#include "mik32_hal_def.h" +#include "mcu32_memory_map.h" +#include "mik32_hal.h" + +#define CLOCKSWITCH_TIMEOUT_VALUE 500000 /**< Стандартная задержка для ожидания детектирования источника тактирования, на который происходит переключение */ + +/** + * @brief Источники тактирования. + * + * Используется как маска для включения источников частоты и + * для назначения приоритетного источника тактирования системы в мониторе частоты. + */ +typedef enum __HAL_PCC_OscillatorTypeTypeDef +{ + PCC_OSCILLATORTYPE_NONE = 0b0000, /**< Автоматический выбор источника тактирования RTC */ + PCC_OSCILLATORTYPE_HSI32M = 0b0001, /**< Внутренний источник тактирования 32МГц */ + PCC_OSCILLATORTYPE_OSC32M = 0b0010, /**< Внешний источник тактирования 32МГц */ + PCC_OSCILLATORTYPE_LSI32K = 0b0100, /**< Внутренний источник тактирования 32КГц */ + PCC_OSCILLATORTYPE_OSC32K = 0b1000, /**< Внешний источник тактирования 32КГц */ + PCC_OSCILLATORTYPE_ALL = 0b1111 /**< Все источники */ +} HAL_PCC_OscillatorTypeTypeDef; + +/** + * @brief Принудительный выбор источника тактирования системы. + * + * Используется для включения или отключения автоматического переключения источника тактирования системы. + */ +typedef enum __HAL_PCC_ForceOscSysTypeDef +{ + PCC_FORCE_OSC_SYS_UNFIXED = 0, /**< Источник тактирования системы не выбирается принудительно */ + PCC_FORCE_OSC_SYS_FIXED = 1 /**< Источник тактирования системы выбирается принудительно */ +} HAL_PCC_ForceOscSysTypeDef; + +/** + * @brief Опорный источник тактирования монитора частоты. + * + * Используется для назначения приоритетного опорного источника тактирования монитора частоты. + */ +typedef enum __HAL_PCC_FreqMonitorSourceTypeDef +{ + PCC_FREQ_MONITOR_SOURCE_AUTO = 0b00, /**< Опорный источник частоты монитора частоты выбирается автоматически */ + PCC_FREQ_MONITOR_SOURCE_LSI32K = 0b01, /**< Опорный источник частоты монитора частоты принудительно выбран как LSI32K */ + PCC_FREQ_MONITOR_SOURCE_OSC32K = 0b10 /**< Опорный источник частоты монитора частоты принудительно выбран как OSC32K */ +} HAL_PCC_FreqMonitorSourceTypeDef; + +/** + * @brief Источники тактирования RTC. + * + * Используются для назначения приоритетного источника тактирования модуля RTC. + */ +typedef enum __HAL_PCC_RTCClockSourceTypeDef +{ + PCC_RTC_CLOCK_SOURCE_AUTO = 0b00, /**< Источник тактирования RTC выбирается автоматически. Если присутствуют оба тактовых сигнала 32K, то выбирается LSI32K */ + PCC_RTC_CLOCK_SOURCE_LSI32K = 0b01, /**< Приоритетный источник тактирования RTC - LSI32K */ + PCC_RTC_CLOCK_SOURCE_OSC32K = 0b10 /**< Приоритетный источник тактирования RTC - OSC32K */ +} HAL_PCC_RTCClockSourceTypeDef; + +/** + * @brief Источники тактирования RTC в составе ядра. + * + * Используются для назначения приоритетного источника тактирования RTC в составе ядра. + */ +typedef enum __HAL_PCC_CPURTCClockSourceTypeDef +{ + PCC_CPU_RTC_CLOCK_SOURCE_OSC32K = 0, /**< Источник тактирования RTC в составе ядра - OSC32K */ + PCC_CPU_RTC_CLOCK_SOURCE_LSI32K = 1 /**< Источник тактирования RTC в составе ядра - LSI32K */ +} HAL_PCC_CPURTCClockSourceTypeDef; + + +/** + * @name Шина AHB + * @brief Макросы для включения и отключения тактирования периферии на шине AHB + @{ +*/ + +#define __HAL_PCC_CPU_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CPU_M) /**< Включить тактирование CPU */ +#define __HAL_PCC_CPU_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CPU_M) /**< Выключить тактирование CPU */ + +#define __HAL_PCC_EEPROM_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_EEPROM_M) /**< Включить тактирование EEPROM */ +#define __HAL_PCC_EEPROM_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_EEPROM_M) /**< Выключить тактирование EEPROM */ + +#define __HAL_PCC_RAM_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_RAM_M) /**< Включить тактирование RAM */ +#define __HAL_PCC_RAM_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_RAM_M) /**< Выключить тактирование SPIFI */ + +#define __HAL_PCC_SPIFI_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_SPIFI_M) /**< Включить тактирование SPIFI */ +#define __HAL_PCC_SPIFI_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_SPIFI_M) /**< Выключить тактирование SPIFI */ + +#define __HAL_PCC_TCB_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_TCB_M) /**< Включить тактирование блока TCB */ +#define __HAL_PCC_TCB_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_TCB_M) /**< Выключить тактирование блока TCB */ + +#define __HAL_PCC_DMA_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_DMA_M) /**< Включить тактирование DMA */ +#define __HAL_PCC_DMA_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_DMA_M) /**< Выключить тактирование DMA */ + +#define __HAL_PCC_CRYPTO_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRYPTO_M) /**< Включить тактирование крипто-блока */ +#define __HAL_PCC_CRYPTO_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRYPTO_M) /**< Выключить тактирование крипто-блока */ + +#define __HAL_PCC_CRC32_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRC32_M) /**< Включить тактирование CRC */ +#define __HAL_PCC_CRC32_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRC32_M) /**< Выключить тактирование CRC */ + +/** @} */ + +/** + * @name Шина APB_M + * @brief Макросы для включения и отключения тактирования периферии на шине APB_M + @{ +*/ + +#define __HAL_PCC_PM_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_PM_M) /**< Включить тактирование Power manager */ +#define __HAL_PCC_PM_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_PM_M) /**< Выключить тактирование Power manager */ + +#define __HAL_PCC_EPIC_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_EPIC_M) /**< Включить тактирование контроллера прерываний */ +#define __HAL_PCC_EPIC_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_EPIC_M) /**< Выключить тактирование контроллера прерываний */ + +#define __HAL_PCC_TIMER32_0_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_TIMER32_0_M) /**< Включить тактирование TIMER32_0 */ +#define __HAL_PCC_TIMER32_0_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_TIMER32_0_M) /**< Выключить тактирование TIMER32_0 */ + +#define __HAL_PCC_PAD_CONFIG_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_PAD_CONFIG_M) /**< Включить тактирование контроллера выводов */ +#define __HAL_PCC_PAD_CONFIG_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_PAD_CONFIG_M) /**< Выключить тактирование контроллера выводов */ + +#define __HAL_PCC_WDT_BUS_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_WDT_BUS_M) /**< Включить тактирование сторожевого таймера шины */ +#define __HAL_PCC_WDT_BUS_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_WDT_BUS_M) /**< Выключить тактирование сторожевого таймера шины */ + +#define __HAL_PCC_OTP_CONTROLLER_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_OTP_CONTROLLER_M) /**< Включить тактирование OTP */ +#define __HAL_PCC_OTP_CONTROLLER_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_OTP_CONTROLLER_M) /**< Выключить тактирование OTP */ + +#define __HAL_PCC_PVD_CONTROL_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_PVD_CONTROL_M) /**< Включить тактирование Монитора напряжения */ +#define __HAL_PCC_PVD_CONTROL_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_PVD_CONTROL_M) /**< Выключить тактирование Монитора напряжения */ + +#define __HAL_PCC_WU_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_WU_M) /**< Включить тактирование Wake up */ +#define __HAL_PCC_WU_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_WU_M) /**< Выключить тактирование Wake up */ + +#define __HAL_PCC_RTC_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_RTC_M) /**< Включить тактирование RTC */ +#define __HAL_PCC_RTC_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_RTC_M) /**< Выключить тактирование RTC */ + +/** @} */ + + +/** + * @name Шина APB_P + * @brief Макросы для включения и отключения тактирования периферии на шине APB_P + @{ +*/ + +#define __HAL_PCC_WDT_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_WDT_M) /**< Включить тактирование сторожевого таймера */ +#define __HAL_PCC_WDT_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_WDT_M) /**< Выключить тактирование сторожевого таймера */ + +#define __HAL_PCC_UART_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_UART_0_M) /**< Включить тактирование UART_0 */ +#define __HAL_PCC_UART_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_UART_0_M) /**< Выключить тактирование UART_0 */ + +#define __HAL_PCC_UART_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_UART_1_M) /**< Включить тактирование UART_1 */ +#define __HAL_PCC_UART_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_UART_1_M) /**< Выключить тактирование UART_1 */ + +#define __HAL_PCC_TIMER16_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER16_0_M) /**< Включить тактирование Timer16_0 */ +#define __HAL_PCC_TIMER16_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER16_0_M) /**< Выключить тактирование Timer16_0 */ + +#define __HAL_PCC_TIMER16_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER16_1_M) /**< Включить тактирование Timer16_1 */ +#define __HAL_PCC_TIMER16_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER16_1_M) /**< Выключить тактирование Timer16_1 */ + +#define __HAL_PCC_TIMER16_2_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER16_2_M) /**< Включить тактирование Timer16_2 */ +#define __HAL_PCC_TIMER16_2_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER16_2_M) /**< Выключить тактирование Timer16_2 */ + +#define __HAL_PCC_TIMER32_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER32_1_M) /**< Включить тактирование Timer32_1 */ +#define __HAL_PCC_TIMER32_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER32_1_M) /**< Выключить тактирование Timer32_1 */ + +#define __HAL_PCC_TIMER32_2_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER32_2_M) /**< Включить тактирование Timer32_2 */ +#define __HAL_PCC_TIMER32_2_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER32_2_M) /**< Выключить тактирование Timer32_2 */ + +#define __HAL_PCC_SPI_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_SPI_0_M) /**< Включить тактирование SPI_0 */ +#define __HAL_PCC_SPI_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_SPI_0_M) /**< Выключить тактирование SPI_0 */ + +#define __HAL_PCC_SPI_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_SPI_1_M) /**< Включить тактирование SPI_1 */ +#define __HAL_PCC_SPI_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_SPI_1_M) /**< Выключить тактирование SPI_1 */ + +#define __HAL_PCC_I2C_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_I2C_0_M) /**< Включить тактирование I2C_0 */ +#define __HAL_PCC_I2C_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_I2C_0_M) /**< Выключить тактирование I2C_0 */ + +#define __HAL_PCC_I2C_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_I2C_1_M) /**< Включить тактирование I2C_1 */ +#define __HAL_PCC_I2C_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_I2C_1_M) /**< Выключить тактирование I2C_1 */ + +#define __HAL_PCC_GPIO_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_0_M) /**< Включить тактирование GPIO_0 */ +#define __HAL_PCC_GPIO_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_0_M) /**< Выключить тактирование GPIO_0 */ + +#define __HAL_PCC_GPIO_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_1_M) /**< Включить тактирование GPIO_1 */ +#define __HAL_PCC_GPIO_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_1_M) /**< Выключить тактирование GPIO_1 */ + +#define __HAL_PCC_GPIO_2_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_2_M) /**< Включить тактирование GPIO_2 */ +#define __HAL_PCC_GPIO_2_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_2_M) /**< Выключить тактирование GPIO_2 */ + +#define __HAL_PCC_ANALOG_REGS_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_ANALOG_REGS_M) /**< Включить тактирование аналоговых блоков */ +#define __HAL_PCC_ANALOG_REGS_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_ANALOG_REGS_M) /**< Выключить тактирование аналоговых блоков */ + +#define __HAL_PCC_GPIO_IRQ_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_IRQ_M) /**< Включить тактирование схемы формирования прерываний GPIO */ +#define __HAL_PCC_GPIO_IRQ_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_IRQ_M) /**< Выключить тактирование схемы формирования прерываний GPIO */ + +/** @} */ + +/** + * @brief Структура с состояниями ошибок. + * + * Используется только как возвращаемое значение функции HAL_PCC_Config(PCC_InitTypeDef *PCC_Init). + */ +typedef struct __PCC_ConfigErrorsTypeDef +{ + HAL_StatusTypeDef FreqMonRef; /**< Ошибка, возвращаемая функцией HAL_PCC_FreqMonRefSet(HAL_PCC_FreqMonitorSourceTypeDef Force32KClk) */ + + HAL_StatusTypeDef SetOscSystem; /**< Ошибка, возвращаемая функцией HAL_PCC_SetOscSystem(uint32_t OscillatorSystem, HAL_PCC_ForceOscSysTypeDef ForceOscSys) */ + + HAL_StatusTypeDef RTCClock; /**< Ошибка, возвращаемая функцией HAL_PCC_RTCClock(HAL_PCC_RTCClockSourceTypeDef Oscillator) */ + + HAL_StatusTypeDef CPURTCClock; /**< Ошибка, возвращаемая функцией HAL_PCC_CPURTCClock(HAL_PCC_CPURTCClockSourceTypeDef Oscillator) */ + +} PCC_ConfigErrorsTypeDef; + + +/** + * @brief Настройки монитора частоты + */ +typedef struct __PCC_FreqMonTypeDef +{ + uint8_t OscillatorSystem; /**< Источник тактирования системы. Может принимать одно из значений HAL_PCC_OscillatorTypeTypeDef. */ + + HAL_PCC_ForceOscSysTypeDef ForceOscSys; /**< Разрешение принудительного выбора источника тактирования системы. Может принимать одно из значений HAL_PCC_ForceOscSysTypeDef. */ + + HAL_PCC_FreqMonitorSourceTypeDef Force32KClk; /**< Опорный источник монитора частоты. Может принимать одно из значений HAL_PCC_FreqMonitorSourceTypeDef. */ + +} PCC_FreqMonTypeDef; + +/** + * @brief Настройки тактирования и монитора частоты + */ +typedef struct __PCC_InitTypeDef +{ + uint8_t OscillatorEnable; /**< Осциллятор, который должен быть включен. Этот параметр может быть маской из значений HAL_PCC_OscillatorTypeTypeDef. */ + + PCC_FreqMonTypeDef FreqMon; /**< Настройки монитора частоты. */ + + uint32_t AHBDivider; /**< Делитель частоты AHB. Этот параметр должен быть числом между Min = 0 и Max = 255 */ + + uint32_t APBMDivider; /**< Делитель частоты APB_M. Этот параметр должен быть числом между Min = 0 и Max = 255 */ + + uint32_t APBPDivider; /**< Делитель частоты APB_P. Этот параметр должен быть числом между Min = 0 и Max = 255 */ + + uint8_t HSI32MCalibrationValue; /**< Поправочный коэффициент HSI32M. Этот параметр должен быть числом между Min = 0 и Max = 255 */ + + uint8_t LSI32KCalibrationValue; /**< Поправочный коэффициент LSI32K. Этот параметр должен быть числом между Min = 0 и Max = 255 */ + + HAL_PCC_RTCClockSourceTypeDef RTCClockSelection; /**< Источник тактирования RTC. Может принимать одно из значений HAL_PCC_RTCClockSourceTypeDef. */ + + HAL_PCC_CPURTCClockSourceTypeDef RTCClockCPUSelection; /**< Источник тактирования RTC в составе ядра. Может принимать одно из значений HAL_PCC_CPURTCClockSourceTypeDef. */ + +} PCC_InitTypeDef; + + + +void HAL_PCC_OscEnable(HAL_PCC_OscillatorTypeTypeDef Oscillator); +void HAL_PCC_OscDisable(uint32_t Oscillator); +HAL_StatusTypeDef HAL_PCC_FreqMonRefSet(HAL_PCC_FreqMonitorSourceTypeDef Force32KClk); +HAL_StatusTypeDef HAL_PCC_SetOscSystem(uint32_t OscillatorSystem, HAL_PCC_ForceOscSysTypeDef ForceOscSys); +HAL_StatusTypeDef HAL_PCC_RTCClock(HAL_PCC_RTCClockSourceTypeDef Oscillator); +HAL_StatusTypeDef HAL_PCC_CPURTCClock(HAL_PCC_CPURTCClockSourceTypeDef Oscillator); +void HAL_PCC_DividerAHB(uint32_t DividerAHB); +void HAL_PCC_DividerAPB_M(uint32_t DividerAPB_M); +void HAL_PCC_DividerAPB_P(uint32_t DividerAPB_P); +PCC_ConfigErrorsTypeDef HAL_PCC_Config(PCC_InitTypeDef *PCC_Init); +uint32_t HAL_PCC_GetSysClockFreq(); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_rtc.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_rtc.h new file mode 100644 index 0000000..0d0122c --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_rtc.h @@ -0,0 +1,485 @@ +#ifndef MIK32_HAL_RTC +#define MIK32_HAL_RTC + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_pcc.h" +#include "mik32_hal_gpio.h" +#include "rtc.h" +#include "mcu32_memory_map.h" + +/* Title: Макросы */ + +/* + * Defines: Месяц + * + * + * RTC_MONTH_JANUARY - Январь + * RTC_MONTH_FEBRUARY - Февраль + * RTC_MONTH_MARCH - Март + * RTC_MONTH_APRIL - Апрель + * RTC_MONTH_MAY - Май + * RTC_MONTH_JUNE - Июнь + * RTC_MONTH_JULY - Июль + * RTC_MONTH_AUGUST - Август + * RTC_MONTH_SEPTEMBER - Сентябрь + * RTC_MONTH_OCTOBER - Октябрь + * RTC_MONTH_NOVEMBER - Ноябрь + * RTC_MONTH_DECEMBER - Декабрь + * + */ +/* Месяц */ +#define RTC_MONTH_JANUARY 1 +#define RTC_MONTH_FEBRUARY 2 +#define RTC_MONTH_MARCH 3 +#define RTC_MONTH_APRIL 4 +#define RTC_MONTH_MAY 5 +#define RTC_MONTH_JUNE 6 +#define RTC_MONTH_JULY 7 +#define RTC_MONTH_AUGUST 8 +#define RTC_MONTH_SEPTEMBER 9 +#define RTC_MONTH_OCTOBER 10 +#define RTC_MONTH_NOVEMBER 11 +#define RTC_MONTH_DECEMBER 12 + +/* Title: Макросы */ + +/* + * Defines: День недели + * + * + * RTC_WEEKDAY_MONDAY - Понедельник + * RTC_WEEKDAY_TUESDAY - Вторник + * RTC_WEEKDAY_WEDNESDAY - Среда + * RTC_WEEKDAY_THURSDAY - Четверг + * RTC_WEEKDAY_FRIDAY - Пятница + * RTC_WEEKDAY_SATURDAY - Суббота + * RTC_WEEKDAY_SUNDAY - Воскресенье + * + */ +/* День недели */ +#define RTC_WEEKDAY_MONDAY 1 +#define RTC_WEEKDAY_TUESDAY 2 +#define RTC_WEEKDAY_WEDNESDAY 3 +#define RTC_WEEKDAY_THURSDAY 4 +#define RTC_WEEKDAY_FRIDAY 5 +#define RTC_WEEKDAY_SATURDAY 6 +#define RTC_WEEKDAY_SUNDAY 7 + +/* + * Defines: Прерывание будильника Alarm + * + * + * RTC_ALARM_IRQ_DISABLE - Запретить прерывание Alarm + * RTC_ALARM_IRQ_ENABLE - Разрешить прерывание Alarm + * + */ +#define RTC_ALARM_IRQ_DISABLE 0 /* Запретить прерывание Alarm */ +#define RTC_ALARM_IRQ_ENABLE 1 /* Разрешить прерывание Alarm */ + +/* Title: Структуры */ + +typedef struct +{ + uint8_t Alarm; /* Разрешение прерывания при наличии установленного бита ALRM */ + +} RTC_IRQnTypeDef; + +/* + * Struct: RTC_HandleTypeDef + * Настройки инициализации RTC + * + */ +typedef struct +{ + /* + * Variable: Instance + * Базовый адрес регистров RTC + * + */ + RTC_TypeDef *Instance; + + RTC_IRQnTypeDef Interrupts; /* Прерывания RTC */ + +} RTC_HandleTypeDef; + +/* + * Struct: RTC_HandleTypeDef + * Время и день недели + * + */ +typedef struct +{ +/* + * Variable: Dow + * День недели + * + * Этот параметр должен быть одним из значений: + * + * - + * - + * - + * - + * - + * - + * - + * + */ + uint8_t Dow; /* Параметр RTC. День недели. + Этот параметр должен быть числом между Min = 1 и Max = 7 */ + +/* + * Variable: Hours + * Часы + * + * Этот параметр должен быть числом в диапазоне от 0 до 23. + * + */ + uint8_t Hours; + + /* + * Variable: Minutes + * Минуты + * + * Этот параметр должен быть числом в диапазоне от 0 до 59. + * + */ + uint8_t Minutes; + + /* + * Variable: Seconds + * Секунды + * + * Этот параметр должен быть числом в диапазоне от 0 до 59. + * + */ + uint8_t Seconds; + +} RTC_TimeTypeDef; + +/* + * Struct: RTC_DateTypeDef + * Дата + * + */ +typedef struct +{ + /* + * Variable: Century + * Секунды + * + * Этот параметр должен быть числом в диапазоне от 0 до 99. + * + */ + uint8_t Century; + + /* + * Variable: Day + * Число + * + * Этот параметр должен быть числом в диапазоне от 1 до 31. + * + */ + uint8_t Day; + + /* + * Variable: Day + * Месяц + * + * Этот параметр должен быть числом в диапазоне от 1 до 12. + * + */ + uint8_t Month; + + /* + * Variable: Day + * Год + * + * Этот параметр должен быть числом в диапазоне от 0 до 99. + * + */ + uint8_t Year; + +} RTC_DateTypeDef; + +/* + * Struct: RTC_DateTypeDef + * Дата и время будильника + * + */ +typedef struct +{ + /* + * Variable: AlarmTime + * Время и день недели будильника + * + */ + RTC_TimeTypeDef AlarmTime; + + /* + * Variable: AlarmDate + * Дата будильника + * + */ + RTC_DateTypeDef AlarmDate; + + /* + * Variable: MaskAlarmTime + * Маска сравнений будильника по времени + * + */ + uint32_t MaskAlarmTime; + + /* + * Variable: MaskAlarmDate + * Маска сравнений будильника по дате + * + */ + uint32_t MaskAlarmDate; + +} RTC_AlarmTypeDef; + +/* Title: Функции */ +void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc); + +/* + * Function: HAL_RTC_WaitFlag + * + * Ожидать после записи в регистр RTC установку Flag в 0 + * + * Сигнал проведения синхронизации между тактовыми доменами. После записи в любой регистр и пока данный флаг + * читается равным 1, запрещено выполнять любую новую запись. + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * + * Returns: + * void. + * + */ +void HAL_RTC_WaitFlag(RTC_HandleTypeDef *hrtc); + +/* + * Function: HAL_RTC_Disable + * + * Выключить модуль RTC + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * + * Returns: + * void. + */ +void HAL_RTC_Disable(RTC_HandleTypeDef *hrtc); + +/* + * Function: HAL_RTC_Disable + * + * Включить модуль RTC + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * + * Returns: + * void. + */ +void HAL_RTC_Enable(RTC_HandleTypeDef *hrtc); + +/* + * Function: HAL_RTC_SetTime + * + * Установить временя и день недели RTC в соответствии с параметрами sTime + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * sTime - Указатель на структуру с настройками времени и дня недели. + * + * Returns: + * void. + */ +void HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime); + +/* + * Function: HAL_RTC_SetDate + * + * Установить дату в соответствии с параметрами sDate + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * sDate - Указатель на структуру с настройками даты. + * + * Returns: + * void. + */ +void HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate); + +/* + * Function: HAL_RTC_Alarm_SetTime + * + * Установить время будильника в соответствии с параметрами sAlarm + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * sAlarm - Указатель на структуру с настройками времени и дня недели будильника. + * + * Returns: + * void. + */ +void HAL_RTC_Alarm_SetTime(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm); + +/* + * Function: HAL_RTC_Alarm_SetDate + * + * Установить время будильника в соответствии с параметрами sAlarm + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * sAlarm - Указатель на структуру с настройками даты будильника. + * + * Returns: + * void. + */ +void HAL_RTC_Alarm_SetDate(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm); + +/* + * Function: HAL_RTC_SetAlarm + * + * Установить дату и время будильника в соответствии с параметрами sAlarm + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * sAlarm - Указатель на структуру с настройками даты и времени будильника. + * + * Returns: + * void. + */ +void HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm); + +/* + * Function: HAL_RTC_AlarmDisable + * + * Запретить все сравнения будильника + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * + * Returns: + * void. + */ +void HAL_RTC_AlarmDisable(RTC_HandleTypeDef *hrtc); + +/* + * Function: HAL_RTC_AlarmDisable + * + * Очистить флаг будильника Alrm + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * + * Returns: + * void. + */ +void HAL_RTC_ClearAlrmFlag(RTC_HandleTypeDef *hrtc); + +/* + * Function: HAL_RTC_GetAlrmFlag + * + * Получить значение флага будильника Alrm + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * + * Returns: + * void. + */ +int HAL_RTC_GetAlrmFlag(RTC_HandleTypeDef *hrtc); + +/* + * Function: HAL_RTC_GetDate + * + * Получить текущую дату RTC + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * + * Returns: + * (RTC_DateTypeDef ) - Структура с текущей датой RTC + */ +RTC_DateTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc); + +/* + * Function: HAL_RTC_GetTime + * + * Получить текущее время RTC + * + * Parameters: + * + * hrtc - Указатель на структуру с настройками RTC. + * + * Returns: + * (RTC_DateTypeDef ) - Структура с текущей датой RTC + */ +RTC_TimeTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc); + +/* + * Function: HAL_RTC_SetInterruptAlarm + * Задать разрешение на включение прерывания Alarm в соответствии с InterruptEnable + * + * Parameters: + * hrtc - Указатель на структуру с настройками RTC. + * InterruptEnable - Разрешение прерывания Alarm. + * + * Этот параметр должен быть одним из значений: + * + * - + * - + * + * Returns: + * void. + */ +void HAL_RTC_SetInterruptAlarm(RTC_HandleTypeDef *hrtc, uint32_t InterruptEnable); + +/* + * Function: HAL_RTC_InterruptInit + * Инициализировать прерывания RTC в соответствии с настройками hrtc + * + * Parameters: + * hrtc - Указатель на структуру с настройками RTC. + * + * Returns: + * void. + */ +void HAL_RTC_InterruptInit(RTC_HandleTypeDef *hrtc); + +/* + * Function: HAL_RTC_GetINTE + * Получить текущее значение бита разрешения прерывания Alarm - INTE + * + * Parameters: + * hrtc - Указатель на структуру с настройками RTC. + * + * Returns: + * (int ) - Текущее значение бита разрешения прерывания Alarm - INTE + * + */ +int HAL_RTC_GetINTE(RTC_HandleTypeDef *hrtc); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spi.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spi.h new file mode 100644 index 0000000..f95a8ec --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spi.h @@ -0,0 +1,484 @@ +#ifndef MIK32_HAL_SPI +#define MIK32_HAL_SPI + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stddef.h" +#include "mik32_hal_pcc.h" +#include "mik32_hal_gpio.h" +#include "power_manager.h" +#include "spi_.h" +#include "mik32_hal_def.h" +#include "mcu32_memory_map.h" + + +/** Значение timeout по умолчанию. */ +#define SPI_TIMEOUT_DEFAULT 1000000 + +/* Ошибки SPI */ +#define HAL_SPI_ERROR_NONE 0b00000000 /**< Значение при отсутствии ошибок. */ +#define HAL_SPI_ERROR_MODF 0b00000001 /**< Маска для ошибки MODE_FAIL - напряжение на выводе n_ss_in не соответствую режиму работы SPI. */ +#define HAL_SPI_ERROR_OVR 0b00000010 /**< Маска для ошибки RX_OVERFLOW - прерывание при переполнении RX_FIFO. */ + +/* Выбор ведомых устройств. */ +#define SPI_CS_NONE 0b1111 /**< Ведомое устройство не выбрано. */ +#define SPI_CS_0 0b1110 /**< Ведомое устройство 1. */ +#define SPI_CS_1 0b1101 /**< Ведомое устройство 2. */ +#define SPI_CS_2 0b1011 /**< Ведомое устройство 3. */ +#define SPI_CS_3 0b0111 /**< Ведомое устройство 4. */ + +/* Коэффициент деления частоты spi_ref_clk. */ +#define SPI_BAUDRATE_DIV4 0b001 /**< Коэффициент деления частоты spi_ref_clk - 4. */ +#define SPI_BAUDRATE_DIV8 0b010 /**< Коэффициент деления частоты spi_ref_clk - 8. */ +#define SPI_BAUDRATE_DIV16 0b011 /**< Коэффициент деления частоты spi_ref_clk - 16. */ +#define SPI_BAUDRATE_DIV32 0b100 /**< Коэффициент деления частоты spi_ref_clk - 32. */ +#define SPI_BAUDRATE_DIV64 0b101 /**< Коэффициент деления частоты spi_ref_clk - 64. */ +#define SPI_BAUDRATE_DIV128 0b110 /**< Коэффициент деления частоты spi_ref_clk - 128. */ +#define SPI_BAUDRATE_DIV256 0b111 /**< Коэффициент деления частоты spi_ref_clk - 256. */ + +/* Режим управления сигналом выбора ведомого CS. */ +#define SPI_MANUALCS_OFF 0 /**< Автоматический режим. */ +#define SPI_MANUALCS_ON 1 /**< Ручной режим. */ + +/* Настройки фазы тактового сигнала. */ +#define SPI_PHASE_OFF 0 /**< Тактовая частота SPI активна вне слова */ +#define SPI_PHASE_ON 1 /**< Тактовая частота SPI неактивна вне слова */ + +/* Настройки полярности тактового сигнала вне слова. */ +#define SPI_POLARITY_LOW 0 /**< Тактовый сигнал вне слова удерживается на низком уровне. */ +#define SPI_POLARITY_HIGH 1 /**< Тактовый сигнал вне слова удерживается на высоком уровне. */ + +/* Использование внешнего декодера. */ +#define SPI_DECODER_NONE 0 /**< Внешний декодер не используется. Выбор только 1 из 4 ведомых устройств. */ +#define SPI_DECODER_USE 1 /**< Используется внешний декодер. */ + +/* Длина передаваемой посылки. */ +#define SPI_DATASIZE_8BITS 0 /**< Длина передаваемой посылки - 8 бит. */ +#define SPI_DATASIZE_16BITS 1 /**< Длина передаваемой посылки - 16 бит. */ +#define SPI_DATASIZE_24BITS 2 /**< Длина передаваемой посылки - 24 бит. */ +#define SPI_DATASIZE_32BITS 3 /**< Длина передаваемой посылки - 32 бит. */ + +/* Значения по умолчанию порогового значения TX_FIFO. */ +#define SPI_THRESHOLD_DEFAULT 4 /* Значение Threshold_of_TX_FIFO по умолчанию*/ + +/* Прерывания. */ +#define TX_FIFO_UNDERFLOW 6 /**< Регистр TX FIFO опустошен. */ +#define RX_FIFO_FULL 5 /**< Регистр RX_FIFO заполнен. */ +#define RX_FIFO_NOT_EMPTY 4 /**< Регистр RX_FIFO не пустой. */ +#define TX_FIFO_FULL 3 /**< Регистр TX_FIFO заполнен. */ +#define TX_FIFO_NOT_FULL 2 /**< Регистр TX_FIFO не заполнен. */ +#define MODE_FAIL 1 /**< Напряжение на выводе n_ss_in не соответствую режиму работы SPI. */ +#define RX_OVERFLOW 0 /**< Прерывание при переполнении RX_FIFO, значение сбрасывается при чтении. */ + +#define SPI_BUFFER_SIZE 8 /**< Размер буферов RX и TX. */ + +/** @brief Включить модуль SPI. + * @param __HANDLE__ Указатель SPI Handle. + */ +#define __HAL_SPI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->ENABLE = SPI_ENABLE_M) + +/** @brief Выключить модуль SPI. + * @param __HANDLE__ Указатель SPI Handle. + */ +#define __HAL_SPI_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->ENABLE &= ~SPI_ENABLE_M) + +/** @brief Проверить установлен ли указанный флаг SPI или нет. + * @param __HANDLE__ Указатель SPI Handle. + * @param __FLAG__ Флаг для проверки. + * Этот параметр должен быть одним из следующих значений: + * - @ref SPI_INT_STATUS_SPI_ACTIVE_M: Флаг статуса сеанса передачи + * - @ref SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M: Флаг опустошения буфера TX_FIFO в режиме ведомого перед началом обмена + * - @ref SPI_INT_STATUS_RX_FIFO_FULL_M: Флаг заполнения буфера RX_FIFO + * - @ref SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M: Флаг наличия данных в буфере RX_FIFO + * - @ref SPI_INT_STATUS_TX_FIFO_FULL_M: Флаг заполнения буфера TX_FIFO + * - @ref SPI_INT_STATUS_TX_FIFO_NOT_FULL_M: Флаг заполнения буфера TX_FIFO ниже порогового значения + * - @ref SPI_INT_STATUS_MODE_FAIL_M: Флаг детектирования напряжение на выводе n_ss_in не соответствую режиму работы SPI + * - @ref SPI_INT_STATUS_RX_OVERFLOW_M: Флаг переполнения буфера RX_FIFO + * + * @return Состояние флага @p __FLAG__ (TRUE или FALSE). + */ +#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->ENABLE) & (__FLAG__)) == (__FLAG__)) + +/** + * @brief Выбор режима ведущий/ведомый. + */ +typedef enum __HAL_SPI_ModeTypeDef +{ + HAL_SPI_MODE_SLAVE = 0, /**< Режим ведомого. */ + HAL_SPI_MODE_MASTER = 1, /**< Режим ведущего. */ + +} HAL_SPI_ModeTypeDef; + +/** + * @brief Состояние модуля SPI. + */ +typedef enum __HAL_SPI_StateTypeDef +{ + HAL_SPI_STATE_READY, /**< Готов к передаче. */ + HAL_SPI_STATE_BUSY, /**< Идет передача. */ + HAL_SPI_STATE_END, /**< Передача завершена. */ + HAL_SPI_STATE_ERROR /**< Ошибка при передаче. */ +} HAL_SPI_StateTypeDef; + +/** + * @brief Определение структуры конфигурации SPI + */ +typedef struct __SPI_InitTypeDef +{ + + /** + * @brief Выбор режима ведущий/ведомый. + * + * Этот параметр должен быть одним из значений: + * - @ref HAL_SPI_MODE_SLAVE - режим ведомого + * - @ref HAL_SPI_MODE_MASTER - режим ведущего + */ + HAL_SPI_ModeTypeDef SPI_Mode; + + /** + * @brief Коэффициент деления частоты. + * + * Этот параметр должен быть одним из значений: + * - @ref SPI_BAUDRATE_DIV4; + * - @ref SPI_BAUDRATE_DIV8; + * - @ref SPI_BAUDRATE_DIV16; + * - @ref SPI_BAUDRATE_DIV32; + * - @ref SPI_BAUDRATE_DIV64; + * - @ref SPI_BAUDRATE_DIV128; + * - @ref SPI_BAUDRATE_DIV256. + */ + uint8_t BaudRateDiv; + + /** + * @brief Режим управления сигналом выбора ведомого CS. + * + * Этот параметр должен быть одним из значений: + * - @ref SPI_MANUALCS_OFF - сигнал выбора ведомого CS управляется автоматически + * - @ref SPI_MANUALCS_ON - сигнал выбора ведомого CS управляется вручную + */ + uint8_t ManualCS; + + /** + * @brief Настройка фазы тактового сигнала. + * + * Этот параметр должен быть одним из значений: + * - @ref SPI_PHASE_OFF - тактовая частота SPI активна вне слова. Сигналы SS переводятся в неактивное состояние между словами. + * Длительность импульса всегда 1 период тактового сигнала шины APB_P + * - @ref SPI_PHASE_ON - тактовая частота SPI неактивна вне слова. Сигналы SS не переводятся в неактивное состояние между словами + */ + uint8_t CLKPhase; + + /** + * @brief Настройка полярности тактового сигнала вне слова. + * + * Этот параметр должен быть одним из значений: + * - @ref SPI_POLARITY_LOW - тактовый сигнал вне слова удерживается на низком уровне + * - @ref SPI_POLARITY_HIGH - тактовый сигнал вне слова удерживается на высоком уровне + */ + uint8_t CLKPolarity; + + /** + * @brief Использование внешнего декодера. + * + * Этот параметр должен быть одним из значений: + * - @ref SPI_DECODER_NONE - внешний декодер не используется. Выбирается один ведомый из четырех, подключенный к одному из выводов CS0 - CS3 + * - @ref SPI_DECODER_USE - используется внешний декодер. Значение @ref SPI_InitTypeDef::ChipSelect "SPI_HandleTypeDef.Init.ChipSelect" + * отображается на выводах CS0 - CS3 + * + */ + uint8_t Decoder; + + /** + * @brief Пороговое значение TX_FIFO. + * + * Уровень, при котором TX_FIFO считается незаполненным и формируется прерывание TX_FIFO_NOT_full (IXR_TXOW). + */ + uint8_t ThresholdTX; + + /** + * @brief Выбранное ведомое устройство. + * + * Этот параметр должен быть одним из значений: + * - @ref SPI_CS_NONE - ведомое устройство не выбрано + * - @ref SPI_CS_0 - ведомое устройство 1 + * - @ref SPI_CS_1 - ведомое устройство 2 + * - @ref SPI_CS_2 - ведомое устройство 3 + * - @ref SPI_CS_3 - ведомое устройство 4 + */ + uint8_t ChipSelect; + +} SPI_InitTypeDef; + +/** + * @brief Определение структуры SPI Handle. + */ +typedef struct __SPI_HandleTypeDef +{ + + SPI_TypeDef *Instance; /**< Адрес регистров SPI. */ + + SPI_InitTypeDef Init; /**< Параметры SPI. */ + + uint8_t ErrorCode; /**< Код ошибки при работе SPI. */ + + HAL_SPI_StateTypeDef State; /**< Состояние модуля SPI. */ + + uint8_t *pTxBuffPtr; /**< Указатель на буфер для передачи данных по SPI. */ + + uint32_t TxCount; /**< Счетчик байт при передачи данных по SPI. */ + + uint8_t *pRxBuffPtr; /**< Указатель на буфер для считывания данных по SPI. */ + + uint32_t RxCount; /**< Счетчик байт при считывания данных по SPI. */ + +} SPI_HandleTypeDef; + +void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi); +void HAL_SPI_Enable(SPI_HandleTypeDef *hspi); +void HAL_SPI_Disable(SPI_HandleTypeDef *hspi); +void HAL_SPI_SetDelayBTWN(SPI_HandleTypeDef *hspi, uint8_t btwn); +void HAL_SPI_SetDelayAFTER(SPI_HandleTypeDef *hspi, uint8_t after); +void HAL_SPI_SetDelayINIT(SPI_HandleTypeDef *hspi, uint8_t init); +void HAL_SPI_SetSlaveIdleCounter(SPI_HandleTypeDef *hspi, uint8_t slave_idle_counter); +void HAL_SPI_SetThresholdTX(SPI_HandleTypeDef *hspi, uint32_t threshold); +uint32_t HAL_SPI_ReadModuleID(SPI_HandleTypeDef *hspi); +HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi); +void HAL_SPI_ClearTXFIFO(SPI_HandleTypeDef *hspi); +void HAL_SPI_ClearRXFIFO(SPI_HandleTypeDef *hspi); +void HAL_SPI_ClearError(SPI_HandleTypeDef *hspi); +void HAL_SPI_CS_Enable(SPI_HandleTypeDef *hspi, uint32_t CS_M); +void HAL_SPI_CS_Disable(SPI_HandleTypeDef *hspi); +HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout); +HAL_StatusTypeDef HAL_SPI_Exchange_IT(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size); + + +/** + * @brief Разрешить прерывания в соответствии с маской. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param IntEnMask маска разрешенных прерываний. + */ +static inline __attribute__((always_inline)) void HAL_SPI_InterruptEnable(SPI_HandleTypeDef *hspi, uint32_t IntEnMask) +{ + hspi->Instance->INT_ENABLE |= IntEnMask; +} + +/** + * @brief Запретить прерывания в соответствии с маской. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param IntDisMask маска запрещенных прерываний. + */ +static inline __attribute__((always_inline)) void HAL_SPI_InterruptDisable(SPI_HandleTypeDef *hspi, uint32_t IntDisMask) +{ + hspi->Instance->INT_DISABLE |= IntDisMask; +} + +/** + * @brief Получить состояние флага прерывания с учетом маски разрешенных прерываний. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param Interrupt Флаг прерывания. + * Этот параметр должен быть одним из следующих значений: + * - @ref TX_FIFO_UNDERFLOW - регистр TX FIFO опустошен + * - @ref RX_FIFO_FULL - регистр RX_FIFO заполнен + * - @ref RX_FIFO_NOT_EMPTY - регистр RX_FIFO не пустой + * - @ref TX_FIFO_FULL - регистр TX_FIFO заполнен + * - @ref TX_FIFO_NOT_FULL - регистр TX_FIFO не заполнен + * - @ref MODE_FAIL - напряжение на выводе n_ss_in не соответствую режиму работы SPI + * - @ref RX_OVERFLOW - прерывание при переполнении RX_FIFO, значение сбрасывается при чтении + * @return Состояние флага. + */ +static inline __attribute__((always_inline)) uint8_t HAL_SPI_GetInterruptStatus(SPI_HandleTypeDef *hspi, uint32_t Interrupt) +{ + uint32_t interrupt_status = hspi->Instance->INT_STATUS & hspi->Instance->INT_MASK; + + switch (Interrupt) + { + case TX_FIFO_UNDERFLOW: + interrupt_status = (interrupt_status & SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M) >> SPI_INT_STATUS_TX_FIFO_UNDERFLOW_S; + break; + case RX_FIFO_FULL: + interrupt_status = (interrupt_status & SPI_INT_STATUS_RX_FIFO_FULL_M) >> SPI_INT_STATUS_RX_FIFO_FULL_S; + break; + + case RX_FIFO_NOT_EMPTY: + interrupt_status = (interrupt_status & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M) >> SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_S; + break; + + case TX_FIFO_FULL: + interrupt_status = (interrupt_status & SPI_INT_STATUS_TX_FIFO_FULL_M) >> SPI_INT_STATUS_TX_FIFO_FULL_S; + break; + + case TX_FIFO_NOT_FULL: + interrupt_status = (interrupt_status & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M) >> SPI_INT_STATUS_TX_FIFO_NOT_FULL_S; + break; + + case MODE_FAIL: + interrupt_status = (interrupt_status & SPI_INT_STATUS_MODE_FAIL_M) >> SPI_INT_STATUS_MODE_FAIL_S; + break; + + case RX_OVERFLOW: + interrupt_status = (interrupt_status & SPI_INT_STATUS_RX_OVERFLOW_M) >> SPI_INT_STATUS_RX_OVERFLOW_S; + break; + + default: + break; + } + + return interrupt_status; +} + +/** + * @brief Обработчик прерывания RX_OVERFLOW (IXR_RXOVR) - переполнение буфера RX. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + */ +static inline __attribute__((always_inline)) void HAL_SPI_RXOverflow_IRQ(SPI_HandleTypeDef *hspi) +{ + hspi->State = HAL_SPI_STATE_ERROR; + hspi->ErrorCode |= HAL_SPI_ERROR_OVR; + HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M | + SPI_INT_STATUS_MODE_FAIL_M | + SPI_INT_STATUS_TX_FIFO_NOT_FULL_M | + SPI_INT_STATUS_TX_FIFO_FULL_M | + SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M | + SPI_INT_STATUS_RX_FIFO_FULL_M | + SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M); +} + +/** + * @brief Обработчик прерывания MODE_FAIL (IXR_MODF) - напряжение на выводе n_ss_in не соответствую режиму работы SPI. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + */ +static inline __attribute__((always_inline)) void HAL_SPI_ModeFail_IRQ(SPI_HandleTypeDef *hspi) +{ + hspi->State = HAL_SPI_STATE_ERROR; + hspi->ErrorCode |= HAL_SPI_ERROR_MODF; + HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M | + SPI_INT_STATUS_MODE_FAIL_M | + SPI_INT_STATUS_TX_FIFO_NOT_FULL_M | + SPI_INT_STATUS_TX_FIFO_FULL_M | + SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M | + SPI_INT_STATUS_RX_FIFO_FULL_M | + SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M); +} + +/** + * @brief Обработчик прерывания TX_FIFO_NOT_full (IXR_TXOW) - регистр TX_FIFO не заполнен (меньше значения ThresholdTX). + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + */ +static inline __attribute__((always_inline)) void HAL_SPI_TXFifoNotFull_IRQ(SPI_HandleTypeDef *hspi) +{ + uint32_t write_read_bytes = SPI_BUFFER_SIZE - hspi->Init.ThresholdTX + 1; /* Число байт для записи и чтения в итерации */ + + for (volatile uint32_t i = 0; (i < write_read_bytes) && hspi->TxCount; i++) + { + hspi->Instance->TXDATA = *(hspi->pTxBuffPtr); + hspi->pTxBuffPtr++; + hspi->TxCount--; + } + + if (hspi->TxCount == 0) + { + + HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_TX_FIFO_NOT_FULL_M); + + if (hspi->RxCount == 0) + { + hspi->State = HAL_SPI_STATE_END; + __HAL_SPI_DISABLE(hspi); + hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */ + volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */ + (void)unused; + HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M | + SPI_INT_STATUS_MODE_FAIL_M | + SPI_INT_STATUS_TX_FIFO_NOT_FULL_M | + SPI_INT_STATUS_TX_FIFO_FULL_M | + SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M | + SPI_INT_STATUS_RX_FIFO_FULL_M | + SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M); + } + } +} + +/** + * @brief Обработчик прерывания RX_FIFO_NOT_EMPTY (IXR_RXNEMPTY) - Регистр RX_FIFO не пустой. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + */ +static inline __attribute__((always_inline)) void HAL_SPI_RXFifoNotEmpty_IRQ(SPI_HandleTypeDef *hspi) +{ + /* Чтение одного байта */ + *(hspi->pRxBuffPtr) = hspi->Instance->RXDATA; + hspi->pRxBuffPtr++; + hspi->RxCount--; + + if (hspi->RxCount == 0) + { + HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M | SPI_INT_STATUS_RX_OVERFLOW_M); + + if (hspi->TxCount == 0) + { + hspi->State = HAL_SPI_STATE_END; + __HAL_SPI_DISABLE(hspi); + hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */ + volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */ + (void)unused; + HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M | + SPI_INT_STATUS_MODE_FAIL_M | + SPI_INT_STATUS_TX_FIFO_NOT_FULL_M | + SPI_INT_STATUS_TX_FIFO_FULL_M | + SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M | + SPI_INT_STATUS_RX_FIFO_FULL_M | + SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M); + } + } +} + +/** + * @brief Обработчик запроса прерывания SPI. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + */ +static inline __attribute__((always_inline)) void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi) +{ + uint32_t interrupt_status = hspi->Instance->INT_STATUS & hspi->Instance->INT_MASK; + + if (!(interrupt_status & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M | SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M))) + { + if (interrupt_status & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M) + { + HAL_SPI_RXFifoNotEmpty_IRQ(hspi); + } + + if (interrupt_status & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M) + { + HAL_SPI_TXFifoNotFull_IRQ(hspi); + } + return; + } + + if (interrupt_status & SPI_INT_STATUS_RX_OVERFLOW_M) + { + HAL_SPI_RXOverflow_IRQ(hspi); + return; + } + + if (interrupt_status & SPI_INT_STATUS_MODE_FAIL_M) + { + HAL_SPI_ModeFail_IRQ(hspi); + return; + } +} + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spifi.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spifi.h new file mode 100644 index 0000000..f3b5aef --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spifi.h @@ -0,0 +1,234 @@ +#ifndef MIK32_HAL_SPIFI +#define MIK32_HAL_SPIFI + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mik32_hal_def.h" +#include "mik32_hal_pcc.h" +#include "mik32_hal_gpio.h" +#include +#include + +#define HAL_SPIFI_TIMEOUT 100000 + +typedef enum __HAL_SPIFI_CacheEnableTypeDef +{ + SPIFI_CACHE_DISABLE = 0, + SPIFI_CACHE_ENABLE = 1, +} HAL_SPIFI_CacheEnableTypeDef; + +typedef enum __HAL_SPIFI_DataCacheEnableTypeDef +{ + SPIFI_DATA_CACHE_ENABLE = 0, + SPIFI_DATA_CACHE_DISABLE = 1, +} HAL_SPIFI_DataCacheEnableTypeDef; + +typedef enum __HAL_SPIFI_InterruptEnableTypeDef +{ + SPIFI_INTERRUPT_DISABLE = 0, + SPIFI_INTERRUPT_ENABLE = 1, +} HAL_SPIFI_InterruptEnableTypeDef; + +typedef enum __HAL_SPIFI_Mode3EnableTypeDef +{ + SPIFI_MODE3_DISABLE = 0, + SPIFI_MODE3_ENABLE = 1, +} HAL_SPIFI_Mode3EnableTypeDef; + +typedef enum __HAL_SPIFI_PrefetchEnableTypeDef +{ + SPIFI_PREFETCH_ENABLE = 0, + SPIFI_PREFETCH_DISABLE = 1, +} HAL_SPIFI_PrefetchEnableTypeDef; + +typedef enum __HAL_SPIFI_DualModeEnableTypeDef +{ + SPIFI_DUAL_MODE_ENABLE = 0, + SPIFI_DUAL_MODE_DISABLE = 1, +} HAL_SPIFI_DualModeEnableTypeDef; + +typedef enum __HAL_SPIFI_DMAEnableTypeDef +{ + SPIFI_DMA_ENABLE = 0, + SPIFI_DMA_DISABLE = 1, +} HAL_SPIFI_DMAEnableTypeDef; + +typedef enum __HAL_SPIFI_FieldFormTypeDef +{ + SPIFI_FIELDFORM_ALL_SERIAL = SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL, + SPIFI_FIELDFORM_DATA_PARALLEL = SPIFI_CONFIG_CMD_FIELDFORM_DATA_PARALLEL, + SPIFI_FIELDFORM_OPCODE_SERIAL = SPIFI_CONFIG_CMD_FIELDFORM_OPCODE_SERIAL, + SPIFI_FIELDFORM_ALL_PARALLEL = SPIFI_CONFIG_CMD_FIELDFORM_ALL_PARALLEL, +} HAL_SPIFI_FieldFormTypeDef; + +typedef enum __HAL_SPIFI_FrameFormTypeDef +{ + SPIFI_FRAMEFORM_OPCODE = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_NOADDR, + SPIFI_FRAMEFORM_OPCODE_1ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_1ADDR, + SPIFI_FRAMEFORM_OPCODE_2ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_2ADDR, + SPIFI_FRAMEFORM_OPCODE_3ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_3ADDR, + SPIFI_FRAMEFORM_OPCODE_4ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_4ADDR, + SPIFI_FRAMEFORM_3ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_NOOPCODE_3ADDR, + SPIFI_FRAMEFORM_4ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_NOOPCODE_4ADDR, +} HAL_SPIFI_FrameFormTypeDef; + +typedef enum __HAL_SPIFI_DirectionTypeDef +{ + SPIFI_DIRECTION_INPUT = SPIFI_CONFIG_CMD_DOUT_M ^ (1 << SPIFI_CONFIG_CMD_DOUT_S), + SPIFI_DIRECTION_OUTPUT = SPIFI_CONFIG_CMD_DOUT_M +} HAL_SPIFI_DirectionTypeDef; + +typedef struct __SPIFI_MemoryCommandTypeDef +{ + uint32_t InterimData; + + uint8_t InterimLength; + + HAL_SPIFI_FieldFormTypeDef FieldForm; + + HAL_SPIFI_FrameFormTypeDef FrameForm; + + uint8_t OpCode; + +} SPIFI_MemoryCommandTypeDef; + +typedef struct __SPIFI_MemoryModeConfig_HandleTypeDef +{ + + SPIFI_CONFIG_TypeDef *Instance; + + HAL_SPIFI_CacheEnableTypeDef CacheEnable; + + uint32_t CacheLimit; + + SPIFI_MemoryCommandTypeDef Command; + +} SPIFI_MemoryModeConfig_HandleTypeDef; + +typedef struct __SPIFI_HandleTypeDef +{ + + SPIFI_CONFIG_TypeDef *Instance; + + uint16_t timeout; + + uint8_t CS_High; + + HAL_SPIFI_CacheEnableTypeDef cacheEnabled; + + HAL_SPIFI_DataCacheEnableTypeDef dataCacheEnabled; + + HAL_SPIFI_InterruptEnableTypeDef interruptEnabled; + + HAL_SPIFI_Mode3EnableTypeDef mode3Enabled; + + uint8_t divider; + + HAL_SPIFI_PrefetchEnableTypeDef prefetchEnabled; + + HAL_SPIFI_DualModeEnableTypeDef dualModeEnabled; + + bool DMAEnabled; + +} SPIFI_HandleTypeDef; + +typedef struct __SPIFI_CommandTypeDef +{ + HAL_SPIFI_DirectionTypeDef Direction; + + uint32_t InterimData; + + uint8_t InterimLength; + + HAL_SPIFI_FieldFormTypeDef FieldForm; + + HAL_SPIFI_FrameFormTypeDef FrameForm; + + uint8_t OpCode; + +} SPIFI_CommandTypeDef; + +__attribute__((weak)) void HAL_SPIFI_MspInit(); + +void HAL_SPIFI_MemoryMode_Init(SPIFI_MemoryModeConfig_HandleTypeDef *spifi); + +HAL_StatusTypeDef HAL_SPIFI_SendCommand( + SPIFI_HandleTypeDef *spifi, + SPIFI_CommandTypeDef *cmd, + uint32_t address, + uint16_t bufferSize, + uint8_t *readBuffer, + uint8_t *writeBuffer, + uint32_t timeout); + +HAL_StatusTypeDef HAL_SPIFI_SendCommand_LL( + SPIFI_HandleTypeDef *spifi, + uint32_t cmdRegCfg, + uint32_t address, + uint16_t bufferSize, + uint8_t *readBuffer, + uint8_t *writeBuffer, + uint32_t interimData, + uint32_t timeout); + +bool HAL_SPIFI_IsMemoryModeEnabled(SPIFI_HandleTypeDef *spifi); + +static inline __attribute__((always_inline)) bool HAL_SPIFI_IsCommandCompleted(SPIFI_HandleTypeDef *spifi) +{ + return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) != 0; +} + +static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_WaitCommandProcessing(SPIFI_HandleTypeDef *spifi, uint32_t timeout) +{ + while (timeout-- > 0) + { + if (HAL_SPIFI_IsCommandCompleted(spifi)) + { + return HAL_OK; + } + } + + return HAL_TIMEOUT; +} + +void HAL_SPIFI_Reset(SPIFI_HandleTypeDef *spifi); + +bool HAL_SPIFI_IsReady(SPIFI_HandleTypeDef *spifi); + +static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_WaitInterruptRequest(SPIFI_HandleTypeDef *spifi, uint32_t timeout) +{ + while (timeout-- != 0) + { + if ((spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) != 0) + { + return HAL_OK; + } + } + return HAL_TIMEOUT; +} + +static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_WaitInterruptClear(SPIFI_HandleTypeDef *spifi, uint32_t timeout) +{ + while (timeout-- != 0) + { + if ((spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) == 0) + { + return HAL_OK; + } + } + return HAL_TIMEOUT; +} + +static inline __attribute__((always_inline)) bool HAL_SPIFI_IsInterruptRequest(SPIFI_HandleTypeDef *spifi, uint32_t timeout) +{ + return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) != 0; +} + +#ifdef __cplusplus +} +#endif + +#endif // MIK32_HAL_SPIFI diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h new file mode 100644 index 0000000..873a26f --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h @@ -0,0 +1,318 @@ +#ifndef MIK32_HAL_TIMER16 +#define MIK32_HAL_TIMER16 + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_pcc.h" +#include "mik32_hal_gpio.h" +#include "power_manager.h" +#include "timer16.h" +#include "pad_config.h" +#include "stdbool.h" +#include "mcu32_memory_map.h" + + +/** + * @brief Источник тактирования. + */ +typedef enum __HAL_Timer16_SourceTypeDef +{ + TIMER16_SOURCE_INTERNAL_SYSTEM = 0x0, /**< Тактирование от системной частоты (sys_clk). */ + TIMER16_SOURCE_INTERNAL_AHB = 0x1, /**< Тактирование от частоты шины AHB. */ + TIMER16_SOURCE_INTERNAL_OSC32M = 0x2, /**< Тактирование от частоты внешнего осциллятора OSC32М. */ + TIMER16_SOURCE_INTERNAL_HSI32M = 0x3, /**< Тактирование от частоты встроенного осциллятора HSI32M. */ + TIMER16_SOURCE_INTERNAL_OSC32K = 0x4, /**< Тактирование от частоты внешнего осциллятора OSC32К. */ + TIMER16_SOURCE_INTERNAL_LSI32K = 0x5, /**< Тактирование от частоты встроенного осциллятора LSI32K. */ + TIMER16_SOURCE_EXTERNAL_INPUT1 = 0x6 /**< Тактирование от внешнего вывода Input1. */ +} HAL_Timer16_SourceTypeDef; + +/** + * @brief Делитель частоты. + */ +typedef enum __HAL_Timer16_PrescalerTypeDef +{ + TIMER16_PRESCALER_1 = 0b000, /**< Делитель частоты 1. */ + TIMER16_PRESCALER_2 = 0b001, /**< Делитель частоты 2. */ + TIMER16_PRESCALER_4 = 0b010, /**< Делитель частоты 4. */ + TIMER16_PRESCALER_8 = 0b011, /**< Делитель частоты 8. */ + TIMER16_PRESCALER_16 = 0b100, /**< Делитель частоты 16. */ + TIMER16_PRESCALER_32 = 0b101, /**< Делитель частоты 32. */ + TIMER16_PRESCALER_64 = 0b110, /**< Делитель частоты 64. */ + TIMER16_PRESCALER_128 = 0b111 /**< Делитель частоты 128. */ +} HAL_Timer16_PrescalerTypeDef; + +/** + * @brief Источник тактового сигнала таймера для синхронизации счетчика. + */ +typedef enum __HAL_Timer16_CountModeTypeDef +{ + TIMER16_COUNTMODE_INTERNAL = 0, /**< Счетчик увеличивается после каждого внутреннего тактового импульса. */ + TIMER16_COUNTMODE_EXTERNAL = 1 /**< Счетчик увеличивается после каждого действительного тактового импульса на внешнем выводе input1. */ +} HAL_Timer16_CountModeTypeDef; + +/** + * @brief Полярность синхронизации. + * Выбор активного фронта при тактировании от внешнего источника. + * + */ +typedef enum __HAL_Timer16_ActiveEdgeTypeDef +{ + TIMER16_ACTIVEEDGE_RISING = 0b00, /**< Нарастающий фронт является активным фронтом, используемым для подсчета. */ + TIMER16_ACTIVEEDGE_FOLLING = 0b01, /**< Спадающий фронт является активным фронтом, используемым для подсчета. */ + TIMER16_ACTIVEEDGE_BOTH = 0b10 /**< Оба фронта являются активными фронтами. */ +} HAL_Timer16_ActiveEdgeTypeDef; + +/* Title: Источник триггера */ + +typedef enum __HAL_Timer16_TriggerTypeDef +{ + TIMER16_TRIGGER_TIM0_GPIO0_7 = 0b000, /**< GPIO0_7 источник триггера для Timer16_0. */ + TIMER16_TRIGGER_TIM0_GPIO0_4 = 0b001, /**< GPIO0_4 источник триггера для Timer16_0. */ + TIMER16_TRIGGER_TIM0_GPIO0_15 = 0b010, /**< GPIO0_15 источник триггера для Timer16_0. */ + TIMER16_TRIGGER_TIM0_GPIO0_14 = 0b011, /**< GPIO0_14 источник триггера для Timer16_0. */ + + TIMER16_TRIGGER_TIM1_GPIO1_9 = 0b000, /**< GPIO1_9 источник триггера для Timer16_1. */ + TIMER16_TRIGGER_TIM1_GPIO1_8 = 0b001, /**< GPIO1_8 источник триггера для Timer16_1. */ + TIMER16_TRIGGER_TIM1_GPIO1_7 = 0b010, /**< GPIO1_7 источник триггера для Timer16_1. */ + TIMER16_TRIGGER_TIM1_GPIO1_6 = 0b011, /**< GPIO1_6 источник триггера для Timer16_1. */ + + TIMER16_TRIGGER_TIM2_GPIO2_3 = 0b000, /**< GPIO2_3 источник триггера для Timer16_2. */ + TIMER16_TRIGGER_TIM2_GPIO2_2 = 0b001, /**< GPIO2_2 источник триггера для Timer16_2. */ + TIMER16_TRIGGER_TIM2_GPIO2_1 = 0b010, /**< GPIO2_1 источник триггера для Timer16_2. */ + TIMER16_TRIGGER_TIM2_GPIO2_0 = 0b011, /**< GPIO2_0 источник триггера для Timer16_2. */ + + TIMER16_TRIGGER_TEMPERATURE = 0b100, /**< Источник триггера - термосенсор. */ + TIMER16_TRIGGER_ADC = 0b101, /**< Источник триггера - окончание преобразования АЦП. */ + TIMER16_TRIGGER_RTC = 0b110, /**< Источник триггера - прерывание RTC. */ + TIMER16_TRIGGER_AlARM = 0b111 /**< Источник триггера - Будильник. */ +} HAL_Timer16_TriggerTypeDef; + +/** + * @brief Полярность синхронизации. + * Выбор активного фронта при тактировании от внешнего источника. + */ +typedef enum __HAL_Timer16_Trigger_ActiveEdgeTypeDef +{ + TIMER16_TRIGGER_ACTIVEEDGE_SOFTWARE = 0b00, /**< Программный триггер. Запускается при установленном CNTSTRT или SNGSTRT. */ + TIMER16_TRIGGER_ACTIVEEDGE_RISING = 0b01, /**< Нарастающий фронт является активным фронтом. */ + TIMER16_TRIGGER_ACTIVEEDGE_FOLLING = 0b10, /**< Спадающий фронт является активным фронтом. */ + TIMER16_TRIGGER_ACTIVEEDGE_BOTH = 0b11 /**< Оба фронта являются активными фронтами. */ +} HAL_Timer16_Trigger_ActiveEdgeTypeDef; + +/** + * @brief Функция тайм-аут. + */ +typedef enum __HAL_Timer16_TimeoutTypeDef +{ + TIMER16_TIMEOUT_DISABLE = 0, /**< Триггерное событие, поступающее, когда таймер уже запущен, будет проигнорировано. */ + TIMER16_TIMEOUT_ENABLE = 1 /**< Триггерное событие, поступающее, когда таймер уже запущен, сбросит и перезапустит счетчик. */ +} HAL_Timer16_TimeoutTypeDef; + +/** + * @brief Режим обновления регистров ARR и CMP. + */ +typedef enum __HAL_Timer16_PreloadTypeDef +{ + TIMER16_PRELOAD_AFTERWRITE = 0, /**< Регистры обновляются после каждого доступа к записи на шине APB. */ + TIMER16_PRELOAD_ENDPERIOD = 1 /**< Регистры обновляются в конце текущего периода Timer16. */ +} HAL_Timer16_PreloadTypeDef; + +/** + * @brief Фильтр для внешнего тактового генератора/триггера. + */ +typedef enum __HAL_Timer16_FilterTypeDef +{ + TIMER16_FILTER_NONE = 0b00, /**< Фильтр отключен. */ + TIMER16_FILTER_2CLOCK = 0b01, /**< Фильтр на 2 такта. */ + TIMER16_FILTER_4CLOCK = 0b10, /**< Фильтр на 4 такта. */ + TIMER16_FILTER_8CLOCK = 0b11 /**< Фильтр на 8 тактов. */ +} HAL_Timer16_FilterTypeDef; + +/** + * @brief Режим энкодера. + */ +typedef enum __HAL_Timer16_EncoderTypeDef +{ + TIMER16_ENCODER_DISABLE = 0, /**< Режим энкодера выключен. */ + TIMER16_ENCODER_ENABLE = 1 /**< Режим энкодера включен. */ +} HAL_Timer16_EncoderTypeDef; + +/** + * @brief Генерация волновой формы. + */ +typedef enum __HAL_Timer16_WaveformGenTypeDef +{ + TIMER16_WAVEFORM_GENERATION_ENABLE = 0, /**< Выключить генерацию волновой формы. */ + TIMER16_WAVEFORM_GENERATION_DISABLE = 1 /**< Включить генерацию волновой формы. */ +} HAL_Timer16_WaveformGenTypeDef; + +/** + * @brief Полярность волновой формы. + */ +typedef enum __HAL_Timer16_WaveformPolarityTypeDef +{ + TIMER16_WAVEFORM_POLARITY_NONINVERTED = 0, /**< Неинвертированная полярность волновой формы. */ + TIMER16_WAVEFORM_POLARITY_INVERTED = TIMER16_CFGR_WAVPOL_M /**< Инвертированная полярность волновой формы. */ +} HAL_Timer16_WaveformPolarityTypeDef; + + +/** + * @brief Настройки источника тактирования. + */ +typedef struct __Timer16_ClockConfigTypeDef +{ + uint8_t Source; /**< Источник тактирования. */ + uint8_t Prescaler; /**< Делитель частоты. */ + +} Timer16_ClockConfigTypeDef; + +/** + * @brief Настройки генерации волновой формы. + */ +typedef struct __Timer16_WaveformConfigTypeDef +{ + HAL_Timer16_WaveformGenTypeDef Enable; /**< Включить или выключить генерацию волновой формы. */ + HAL_Timer16_WaveformPolarityTypeDef Polarity; /**< Полярность выходного сигнала. */ + +} Timer16_WaveformConfigTypeDef; + +/** + * @brief Настройки триггера. + */ +typedef struct __Timer16_TriggerConfigTypeDef +{ + uint8_t Source; /**< Источник триггера. */ + uint8_t ActiveEdge; /**< Активный фронт. */ + uint8_t TimeOut; /**< Функция тайм-аут. */ + +} Timer16_TriggerConfigTypeDef; + + +/** + * @brief Настройки фильтров. + */ +typedef struct __Timer16_FilterConfigTypeDef +{ + uint8_t ExternalClock; /**< Фильтр для внешнего тактового генератора. */ + uint8_t Trigger; /**< фильтр для триггера. */ + +} Timer16_FilterConfigTypeDef; + + +/** + * @brief Настройки Timer16 + */ +typedef struct __Timer16_HandleTypeDef +{ + TIMER16_TypeDef *Instance; /**< Базовый адрес регистров Timer16. #TIMER16_0, #TIMER16_1, #TIMER16_2. */ + Timer16_ClockConfigTypeDef Clock; /**< Настройки тактирования. */ + uint8_t CountMode; /**< Источник синхронизации. */ + uint8_t ActiveEdge; /**< Активный фронт. */ + uint8_t Preload; /**< Режим записи в ARR и CMP. */ + Timer16_TriggerConfigTypeDef Trigger; /**< Настройки триггера. */ + Timer16_FilterConfigTypeDef Filter; /**< Настройки фильтра. */ + Timer16_WaveformConfigTypeDef Waveform; /**< Настройки генерации волновой формы. */ + uint8_t EncoderMode; /**< Включить или выключить режим энкодера. */ + +} Timer16_HandleTypeDef; + +/** + * @brief Запустить таймер16 в продолжительном режиме. + */ +#define __HAL_TIMER16_START_CONTINUOUS(__HANDLE__) ((__HANDLE__)->Instance->CR |= TIMER16_CR_CNTSTRT_M) + +/** + * @brief Запустить таймер16 в однократном режиме. + */ +#define __HAL_TIMER16_START_SINGLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= TIMER16_CR_SNGSTRT_M) + + +void HAL_TIMER16_MspInit(Timer16_HandleTypeDef* htimer16); +void HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_SetActiveEdge(Timer16_HandleTypeDef *htimer16, uint8_t ActiveEdge); +void HAL_Timer16_SetSourceClock(Timer16_HandleTypeDef *htimer16, uint8_t SourceClock); +void HAL_Timer16_SetCountMode(Timer16_HandleTypeDef *htimer16, uint8_t CountMode); +void HAL_Timer16_ClockInit(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_SetPreload(Timer16_HandleTypeDef *htimer16, uint8_t Preload); +void HAL_Timer16_WaitARROK(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_WaitCMPOK(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_SetARR(Timer16_HandleTypeDef *htimer16, uint16_t Period); +void HAL_Timer16_SetCMP(Timer16_HandleTypeDef *htimer16, uint16_t Compare); +void HAL_Timer16_SelectTrigger(Timer16_HandleTypeDef *htimer16, uint8_t TriggerSource); +void HAL_Timer16_SetTriggerEdge(Timer16_HandleTypeDef *htimer16, uint8_t TriggerEdge); +void HAL_Timer16_SetTimeOut(Timer16_HandleTypeDef *htimer16, uint8_t TimeOut); +void HAL_Timer16_SetFilterExternalClock(Timer16_HandleTypeDef *htimer16, uint8_t FilterExternalClock); +void HAL_Timer16_SetFilterTrigger(Timer16_HandleTypeDef *htimer16, uint8_t FilterTrigger); +void HAL_Timer16_SetEncoderMode(Timer16_HandleTypeDef *htimer16, uint8_t EncoderMode); +void HAL_Timer16_WaveformPolarity(Timer16_HandleTypeDef *htimer16, HAL_Timer16_WaveformPolarityTypeDef WaveformPolarity); +void HAL_Timer16_SetPrescaler(Timer16_HandleTypeDef *htimer16, uint8_t Prescaler); +void HAL_Timer16_Init(Timer16_HandleTypeDef *htimer16); +uint16_t HAL_Timer16_GetCounterValue(Timer16_HandleTypeDef *htimer16); +uint8_t HAL_Timer16_CheckCMP(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_WaitCMP(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_Counter_Start(Timer16_HandleTypeDef *htimer16, uint32_t Period); +void HAL_Timer16_StartPWM(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare); +void HAL_Timer16_StartOneShot(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare); +void HAL_Timer16_StartSetOnes(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare); +void HAL_Timer16_Encoder_Start(Timer16_HandleTypeDef *htimer16, uint32_t Period); +void HAL_Timer16_Encoder_Stop(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_Stop(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_Counter_Start_IT(Timer16_HandleTypeDef *htimer16, uint32_t Period); +void HAL_Timer16_StartPWM_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare); +void HAL_Timer16_StartOneShot_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare); +void HAL_Timer16_StartSetOnes_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare); +void HAL_Timer16_Encoder_Start_IT(Timer16_HandleTypeDef *htimer16, uint32_t Period); +void HAL_Timer16_Encoder_Stop_IT(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_Stop_IT(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_WaitTrigger(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_SetInterruptMask(Timer16_HandleTypeDef *htimer16, uint32_t InterruptMask); +void HAL_Timer16_SetInterruptDOWN(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_SetInterruptUP(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_SetInterruptARROK(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_SetInterruptCMPOK(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_SetInterruptEXTTRIG(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_SetInterruptARRM(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_SetInterruptCMPM(Timer16_HandleTypeDef *htimer16); +void HAL_Timer16_InterruptInit(Timer16_HandleTypeDef *htimer16); + +/** + * @brief Получить статус прерываний Timer16. + * Функция возвращает статус прерываний в соответствии с маской разрешенный прерываний. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @return Статус прерываний. + */ +static inline __attribute__((always_inline)) uint32_t HAL_Timer16_GetInterruptStatus(Timer16_HandleTypeDef *htimer16) +{ + uint32_t interrupt_status = htimer16->Instance->ISR & htimer16->Instance->IER; + + return interrupt_status; +} + +/** + * @brief Очистить флаг прерывания. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Interrupt Номер прерывания Timer16 в регистре ICR. + */ +static inline __attribute__((always_inline)) void HAL_Timer16_ClearInterruptFlag(Timer16_HandleTypeDef *htimer16, uint32_t Interrupt) +{ + htimer16->Instance->ICR = 1 << Interrupt; +} + +/** + * @brief Очистить флаги прерываний по маске. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param InterruptMask Маска очищаемых флагов прерываний. + */ +static inline __attribute__((always_inline)) void HAL_Timer16_ClearInterruptMask(Timer16_HandleTypeDef *htimer16, uint32_t InterruptMask) +{ + htimer16->Instance->ICR = InterruptMask; +} + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h new file mode 100644 index 0000000..9b3f67e --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h @@ -0,0 +1,265 @@ +#ifndef MIK32_HAL_TIMER32 +#define MIK32_HAL_TIMER32 + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_pcc.h" +#include "mik32_hal_gpio.h" +#include +#include +#include "mik32_hal_def.h" +#include + +#define TIMER32_TIMEOUT 10000000 + +#define TIMER32_INTERRUPT_CLEAR_MASK 0x3FF + +/* Сдвиг настройки тактирования таймера в регистре Timer_CFG */ +#define MUX_TIM32_0 0 +#define MUX_TIM32_1 3 +#define MUX_TIM32_2 6 + +/* Значение в регистре Timer_CFG при тактировании таймера от TIM1 или TIM2 */ +#define TIMER32_TIM1_SYS_CLK 0b00 +#define TIMER32_TIM1_HCLK 0b01 +#define TIMER32_TIM2_OSC32K 0b00 +#define TIMER32_TIM2_LSI32K 0b10 + +typedef enum +{ + TIMER32_SOURCE_PRESCALER, /* Выход с делителя - частота шины AHB (hclk) */ + TIMER32_SOURCE_TIM1_SYS_CLK, /* Системная частота */ + TIMER32_SOURCE_TIM1_HCLK, /* частота шины AHB */ + TIMER32_SOURCE_TIM2_OSC32K, /* Внешний источник 32кГц */ + TIMER32_SOURCE_TIM2_LSI32K, /* Внутренний источник 32кГц */ + TIMER32_SOURCE_TX_PAD, /* Внешний вывод TX_PAD */ +} HAL_TIMER32_SourceTypeDef; + +typedef enum +{ + TIMER32_COUNTMODE_FORWARD = 0b00, + TIMER32_COUNTMODE_REVERSE = 0b01, + TIMER32_COUNTMODE_BIDIRECTIONAL = 0b10 +} HAL_TIMER32_CountModeTypeDef; + +typedef enum +{ + TIMER32_STATE_DISABLE = 0b00, + TIMER32_STATE_ENABLE = 0b01 +} HAL_TIMER32_StateTypeDef; + +typedef enum +{ + TIMER32_CHANNEL_STATE_DISABLE, + TIMER32_CHANNEL_STATE_ENABLE, +} HAL_TIMER32_CHANNEL_StateTypeDef; + +typedef enum +{ + TIMER32_CHANNEL_NON_INVERTED_PWM = 0, + TIMER32_CHANNEL_INVERTED_PWM = 1 +} HAL_TIMER32_CHANNEL_PWMInvertTypeDef; + +typedef enum +{ + TIMER32_CHANNEL_MODE_COMPARE = 0b01, /* Режим сравнения */ + TIMER32_CHANNEL_MODE_CAPTURE = 0b10, /* Режим захвата */ + TIMER32_CHANNEL_MODE_PWM = 0b11, /* ШИМ */ +} HAL_TIMER32_CHANNEL_ModeTypeDef; + +typedef enum +{ + TIMER32_CHANNEL_CAPTUREEDGE_RISING = 0, + TIMER32_CHANNEL_CAPTUREEDGE_FALLING = 1 +} HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef; + +typedef enum +{ + TIMER32_CHANNEL_FILTER_OFF = 0, + TIMER32_CHANNEL_FILTER_ON = 1 +} HAL_TIMER32_CHANNEL_NoiseTypeDef; + +typedef enum +{ + TIMER32_CHANNEL_0 = 0, + TIMER32_CHANNEL_1 = 1, + TIMER32_CHANNEL_2 = 2, + TIMER32_CHANNEL_3 = 3 +} HAL_TIMER32_CHANNEL_IndexTypeDef; + +typedef struct +{ + /* Источник тактирования таймера для счета*/ + HAL_TIMER32_SourceTypeDef Source; + + /* Делитель частоты. Частота делится на Prescaler + 1 */ + uint32_t Prescaler; + +} TIMER32_ClockConfigTypeDef; + +typedef struct +{ + TIMER32_TypeDef *Instance; + + /* Настройки тактирования */ + TIMER32_ClockConfigTypeDef Clock; + + /* Режим счета */ + HAL_TIMER32_CountModeTypeDef CountMode; + + /* Максимальное значение счета */ + uint32_t Top; + + HAL_TIMER32_StateTypeDef State; + + uint32_t InterruptMask; + +} TIMER32_HandleTypeDef; + +typedef struct +{ + TIMER32_TypeDef *TimerInstance; + + TIMER32_CHANNEL_TypeDef *Instance; + + HAL_TIMER32_CHANNEL_IndexTypeDef ChannelIndex; + + /* Инверсия ГИМ */ + HAL_TIMER32_CHANNEL_PWMInvertTypeDef PWM_Invert; + + /* Режим канала */ + HAL_TIMER32_CHANNEL_ModeTypeDef Mode; + + /* Активный фронт в режиме захвата*/ + HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef CaptureEdge; + + /* Значение сравнения канала */ + uint32_t OCR; + + /* Фильтр */ + HAL_TIMER32_CHANNEL_NoiseTypeDef Noise; + + uint8_t State; + +} TIMER32_CHANNEL_HandleTypeDef; + + +#define HAL_TIMER32_VALUE_GET(timer_instance) (*timer_instance).Instance->VALUE; +#define HAL_TIMER32_INTERRUPTFLAGS_CLEAR(timer_instance) (*timer_instance).Instance->INT_CLEAR = TIMER32_INTERRUPT_CLEAR_MASK; +#define HAL_TIMER32_VALUE_CLEAR(timer_instance) (*timer_instance).Instance->ENABLE |= TIMER32_ENABLE_TIM_CLR_M; + +static inline __attribute__((always_inline)) uint32_t HAL_Timer32_Channel_ICR_Get(TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + return timerChannel->Instance->ICR; +} +static inline __attribute__((always_inline)) uint32_t HAL_Timer32_InterruptFlags_Get(TIMER32_HandleTypeDef *timer) +{ + return timer->Instance->INT_FLAGS; +} +static inline __attribute__((always_inline)) uint32_t HAL_Timer32_Value_Get(TIMER32_HandleTypeDef *timer) +{ + return timer->Instance->VALUE; +} +static inline __attribute__((always_inline)) void HAL_Timer32_InterruptFlags_Clear(TIMER32_HandleTypeDef *timer) +{ + timer->Instance->INT_CLEAR = TIMER32_INTERRUPT_CLEAR_MASK; +} +static inline __attribute__((always_inline)) void HAL_Timer32_Value_Clear(TIMER32_HandleTypeDef *timer) +{ + timer->Instance->ENABLE |= TIMER32_ENABLE_TIM_CLR_M; +} +static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_Channel_WaitFlagCapture(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t timeout) +{ + while (timeout) + { + timeout--; + if (timerChannel->TimerInstance->INT_FLAGS & TIMER32_INT_IC_M(timerChannel->ChannelIndex)) + { + return HAL_OK; + } + } + + return HAL_TIMEOUT; +} +static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_Channel_WaitFlagCompare(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t timeout) +{ + while (timeout) + { + timeout--; + if (timerChannel->TimerInstance->INT_FLAGS & TIMER32_INT_OC_M(timerChannel->ChannelIndex)) + { + return HAL_OK; + } + } + + return HAL_TIMEOUT; +} +static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_WaitFlagOverflow(TIMER32_HandleTypeDef *timer, uint32_t timeout) +{ + while (timeout) + { + timeout--; + if (timer->Instance->INT_FLAGS & TIMER32_INT_OVERFLOW_M) + { + return HAL_OK; + } + } + + return HAL_TIMEOUT; +} +static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_WaitFlagUnderflow(TIMER32_HandleTypeDef *timer, uint32_t timeout) +{ + while (timeout) + { + timeout--; + if (timer->Instance->INT_FLAGS & TIMER32_INT_UNDERFLOW_M) + { + return HAL_OK; + } + } + + return HAL_TIMEOUT; +} + +void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32); +void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel); +HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer); +void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state); +void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top); +void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler); +void HAL_Timer32_Source_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_SourceTypeDef source); +void HAL_Timer32_InterruptMask_Set(TIMER32_HandleTypeDef *timer, uint32_t intMask); +void HAL_Timer32_InterruptMask_Clear(TIMER32_HandleTypeDef *timer, uint32_t intMask); +void HAL_Timer32_CountMode_Set(TIMER32_HandleTypeDef *timer, uint8_t countMode); +void HAL_Timer32_InterruptFlags_ClearMask(TIMER32_HandleTypeDef *timer, uint32_t clearMask); +HAL_StatusTypeDef HAL_Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerChannel); +HAL_StatusTypeDef HAL_Timer32_Channel_DeInit(TIMER32_CHANNEL_HandleTypeDef *timerChannel); +HAL_StatusTypeDef HAL_Timer32_Channel_Enable(TIMER32_CHANNEL_HandleTypeDef *timerChannel); +HAL_StatusTypeDef HAL_Timer32_Channel_Disable(TIMER32_CHANNEL_HandleTypeDef *timerChannel); +HAL_StatusTypeDef HAL_Timer32_Channel_PWM_Invert_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_PWMInvertTypeDef PWM_Invert); +HAL_StatusTypeDef HAL_Timer32_Channel_Mode_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_ModeTypeDef mode); +HAL_StatusTypeDef HAL_Timer32_Channel_CaptureEdge_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef captureEdge); +HAL_StatusTypeDef HAL_Timer32_Channel_OCR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t OCR); +HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t ICR); +HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Clear(TIMER32_CHANNEL_HandleTypeDef *timerChannel); +HAL_StatusTypeDef HAL_Timer32_Channel_Noise_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint8_t noise); +void HAL_Timer32_Start(TIMER32_HandleTypeDef *timer); +void HAL_Timer32_Stop(TIMER32_HandleTypeDef *timer); +void HAL_Timer32_Base_Start_IT(TIMER32_HandleTypeDef *timer); +void HAL_Timer32_Base_Stop_IT(TIMER32_HandleTypeDef *timer); +HAL_StatusTypeDef HAL_Timer32_PWM_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel); +void HAL_Timer32_PWM_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel); +HAL_StatusTypeDef HAL_Timer32_Compare_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel); +void HAL_Timer32_Compare_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel); +HAL_StatusTypeDef HAL_Timer32_Capture_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel); +void HAL_Timer32_Capture_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel); +void HAL_Timer32_Start_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask); +void HAL_Timer32_Stop_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask); + +#ifdef __cplusplus +} +#endif + +#endif // MIK32_HAL_TIMER32 diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_tsens.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_tsens.h new file mode 100644 index 0000000..661c10b --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_tsens.h @@ -0,0 +1,158 @@ +#ifndef MIK32_TSENS +#define MIK32_TSENS + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MIK32V0 + +#include "analog_reg.h" +#include "pad_config.h" +#include "mcu32_memory_map.h" +#include "power_manager.h" +#include "mik32_hal_def.h" +#include "mik32_hal_pcc.h" + + +#define TSENS_OPTIMAL_FREQUENCY 40000 /**< Рекомендуемая частота работы термосенсора. */ + +#define __HAL_TSENS_FORCE_RESET(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CFG &= ~TSENS_CFG_NRST_M) /**< Установить состояние сброса термосенсора. */ +#define __HAL_TSENS_RELEASE_RESET(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CFG |= TSENS_CFG_NRST_M) /**< Снять состояние сброса термосенсора. */ + +#define __HAL_TSENS_SINGLE_START(__HANDLE__) ((__HANDLE__)->Instance->TSENS_SINGLE = 1) /**< Запустить одиночное измерение температуры. */ +#define __HAL_TSENS_CONTINUOUS_START(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CONTINUOUS = 1) /**< Запуск непрерывного измерения температуры. */ +#define __HAL_TSENS_CONTINUOUS_STOP(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CONTINUOUS = 0) /**< Остановка непрерывного измерения температуры. */ +#define __HAL_TSENS_GET_EOC(__HANDLE__) (((__HANDLE__)->Instance->TSENS_VALUE & TSENS_VALUE_EOC_M) == TSENS_VALUE_EOC_M) /**< Получить состояние флага окончания преобразования (EOC). */ +#define __HAL_TSENS_READ_MEASUREMENT(__HANDLE__) ((__HANDLE__)->Instance->TSENS_VALUE & TSENS_VALUE_VALUE_M) /**< Получить результат измерения термосенсора. */ + +#define __HAL_TSENS_IRQ_ENABLE_LOWIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ |= TSENS_IRQ_LOW_MASK_M) /**< Разрешить прерывание по выходу за нижний порог температуры. */ +#define __HAL_TSENS_IRQ_DISABLE_LOWIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~TSENS_IRQ_LOW_MASK_M) /**< Запретить прерывание по выходу за нижний порог температуры. */ +#define __HAL_TSENS_IRQ_CLEAR_LOWIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = TSENS_CLEAR_IRQ_LOW_CLEAR_M) /**< Очистить флаг прерывания по выходу за нижний порог температуры (LOW_IRQ). */ +#define __HAL_TSENS_IRQ_GET_LOWIRQ(__HANDLE__) (((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_LOW_IRQ_M) == TSENS_IRQ_LOW_IRQ_M) /**< Получить состояние флага прерывания по выходу за нижний порог температуры (LOW_IRQ). */ +/** Получить состояние флага прерывания по выходу за нижний порог температуры (LOW_IRQ) с учетом маски разрешенных прерываний. */ +#define __HAL_TSENS_IRQ_GET_LOWIRQ_MASK(__HANDLE__) ((((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_LOW_IRQ_M) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == TSENS_IRQ_LOW_IRQ_M) + +#define __HAL_TSENS_IRQ_ENABLE_HIIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ |= TSENS_IRQ_HI_MASK_M) /**< Разрешить прерывание по выходу за верхний порог температуры. */ +#define __HAL_TSENS_IRQ_DISABLE_HIIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~TSENS_IRQ_HI_MASK_M) /**< Запретить прерывание по выходу за верхний порог температуры. */ +#define __HAL_TSENS_IRQ_CLEAR_HIIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = TSENS_CLEAR_IRQ_HI_CLEAR_M) /**< Очистить флаг прерывания по выходу за верхний порог температуры (HI_IRQ). */ +#define __HAL_TSENS_IRQ_GET_HIIRQ(__HANDLE__) (((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_HI_IRQ_M) == TSENS_IRQ_HI_IRQ_M) /**< Получить состояние флага прерывания по выходу за верхний порог температуры (HI_IRQ). */ +/** Получить состояние флага прерывания по выходу за верхний порог температуры (HI_IRQ) с учетом маски разрешенных прерываний. */ +#define __HAL_TSENS_IRQ_GET_HIIRQ_MASK(__HANDLE__) ((((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_HI_IRQ_M) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == TSENS_IRQ_HI_IRQ_M) + +#define __HAL_TSENS_IRQ_ENABLE_EOC(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ |= TSENS_IRQ_EOC_MASK_M) /**< Разрешить прерывание по окончанию преобразования. */ +#define __HAL_TSENS_IRQ_DISABLE_EOC(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~TSENS_IRQ_EOC_MASK_M) /**< Запретить прерывание по окончанию преобразования. */ +#define __HAL_TSENS_IRQ_CLEAR_EOC(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = TSENS_CLEAR_IRQ_EOC_CLEAR_M) /**< Очистить флаг прерывания по окончанию преобразования (EOC_IRQ). */ +#define __HAL_TSENS_IRQ_GET_EOC(__HANDLE__) (((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_EOC_IRQ_M) == TSENS_IRQ_EOC_IRQ_M) /**< Получить состояние флага прерывания по окончанию преобразования (EOC_IRQ). */ +/** Получить состояние флага прерывания по окончанию преобразования (EOC_IRQ) с учетом маски разрешенных прерываний. */ +#define __HAL_TSENS_IRQ_GET_EOC_MASK(__HANDLE__) ((((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_EOC_IRQ_M) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == TSENS_IRQ_EOC_IRQ_M) + +/** + * Разрешить прерывание . __INTERRUPT__ может быть одним из значений: + * - TSENS_IRQ_LOW_MASK_M: выход за нижний порог температуры; + * - TSENS_IRQ_HI_MASK_M: выход за верхний порог температуры; + * - TSENS_IRQ_EOC_MASK_M: окончание преобразования. + */ +#define __HAL_TSENS_IRQ_ENABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->TSENS_IRQ |= (__INTERRUPT__)) +/** + * Запретить прерывание. __INTERRUPT__ может быть одним из значений: + * - TSENS_IRQ_LOW_MASK_M: выход за нижний порог температуры; + * - TSENS_IRQ_HI_MASK_M: выход за верхний порог температуры; + * - TSENS_IRQ_EOC_MASK_M: окончание преобразования. + */ +#define __HAL_TSENS_IRQ_DISABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~(__INTERRUPT__)) +/** + * Очистить флаг прерывания. __FLAG__ может быть одним из значений: + * - TSENS_CLEAR_IRQ_LOW_CLEAR_M: выход за нижний порог температуры; + * - TSENS_CLEAR_IRQ_HI_CLEAR_M: выход за верхний порог температуры; + * - TSENS_CLEAR_IRQ_EOC_CLEAR_M: окончание преобразования. + */ +#define __HAL_TSENS_IRQ_CLEAR(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = (__FLAG__)) +/** + * Получить состояние флага прерывания. __FLAG__ может быть одним из значений: + * - TSENS_IRQ_LOW_IRQ_M: выход за нижний порог температуры; + * - TSENS_IRQ_HI_IRQ_M: выход за верхний порог температуры; + * - TSENS_IRQ_EOC_IRQ_M: окончание преобразования. + */ +#define __HAL_TSENS_IRQ_GET(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->TSENS_IRQ & (__FLAG__)) == (__FLAG__)) +/** + * Получить состояние флага прерывания с учетом маски разрешенных прерываний.. __FLAG__ может быть одним из значений: + * - TSENS_IRQ_LOW_IRQ_M: выход за нижний порог температуры; + * - TSENS_IRQ_HI_IRQ_M: выход за верхний порог температуры; + * - TSENS_IRQ_EOC_IRQ_M: окончание преобразования. + */ +#define __HAL_TSENS_IRQ_GET_MASK(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->TSENS_IRQ & (__FLAG__)) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == (__FLAG__)) + + +/* + * Define + * Константы-параметры функции установки источника тактирования TSENS + */ + +/** + * @brief Перечисление источников тактирования термосенсора. + */ +typedef enum __HAL_TSENS_ClockTypeDef +{ + HAL_TSENS_SYS_CLK = 0x0, /**< Системная частота (sys_clk). */ + HAL_TSENS_HCLK = 0x1, /**< Частота шины AHB (hclk). */ + HAL_TSENS_OSC32M = 0x2, /**< Частота внешнего высокочастотного осциллятора до 32 МГц. */ + HAL_TSENS_HSI32M = 0x3, /**< Частота внутреннего высокочастотного осциллятора 32 МГц. */ + HAL_TSENS_OSC32K = 0x4, /**< Частота внешнего осциллятора 32 кГц. */ + HAL_TSENS_LSI32K = 0x5 /**< Частота внутреннего осциллятора 32 кГц. */ +} HAL_TSENS_ClockTypeDef; + +/** + * @brief Определение структуры TSENS Handle. + */ +typedef struct __SPI_HandleTypeDef +{ + + ANALOG_REG_TypeDef *Instance; /**< Адрес регистров блока управления аналоговой подсистемой. */ + + HAL_TSENS_ClockTypeDef Clock; /**< Источник тактирования TSENS. */ + + uint32_t Frequency; /**< Частота работы температурного сенсора в Гц. Значение этого параметра может быть не больше 100кГц. */ + +} TSENS_HandleTypeDef; + +/** + * @brief Возвращаемая структура для функции @ref HAL_TSENS_SingleStart. + */ +typedef struct __WDT_ClockTypeDef +{ + HAL_StatusTypeDef statusHAL; /**< Статус HAL. */ + + uint32_t value; /**< Значение температуры в градусах Цельсия. Значение в 100 раз больше. */ + +} TSENS_ValueTypeDef; + + +void HAL_TSENS_MspInit(TSENS_HandleTypeDef *htsens); +HAL_StatusTypeDef HAL_TSENS_Init(TSENS_HandleTypeDef *htsens); +HAL_StatusTypeDef HAL_TSENS_ClockSource(TSENS_HandleTypeDef *htsens, HAL_TSENS_ClockTypeDef clk_source); +HAL_StatusTypeDef HAL_TSENS_ClockDivider(TSENS_HandleTypeDef *htsens, uint16_t clk_div); +HAL_StatusTypeDef HAL_TSENS_Clock(TSENS_HandleTypeDef *htsens, uint32_t f_enter); + + +HAL_StatusTypeDef HAL_TSENS_SetLowThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t low_tres); +HAL_StatusTypeDef HAL_TSENS_SetHiThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t hi_tres); +HAL_StatusTypeDef HAL_TSENS_SetLowThreshold(TSENS_HandleTypeDef *htsens, int low_temp_border); +HAL_StatusTypeDef HAL_TSENS_SetHiThreshold(TSENS_HandleTypeDef *htsens, int hi_temp_border); + + +uint32_t HAL_TSENS_GetTemperature(TSENS_HandleTypeDef *htsens); +void HAL_TSENS_ContinuousStart(TSENS_HandleTypeDef *htsens); +TSENS_ValueTypeDef HAL_TSENS_SingleStart(TSENS_HandleTypeDef *htsens, uint32_t timeout); +void HAL_TSENS_ContinuousStart_IT(TSENS_HandleTypeDef *htsens); +void HAL_TSENS_SingleStart_IT(TSENS_HandleTypeDef *htsens); +void HAL_TSENS_Stop_IT(TSENS_HandleTypeDef *htsens); + + +#endif // MIK32V0 + +#ifdef __cplusplus +} +#endif + +#endif // MIK32_TSENS \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_wdt.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_wdt.h new file mode 100644 index 0000000..9708e0f --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_wdt.h @@ -0,0 +1,120 @@ +#ifndef MCU32_HAL_WDT +#define MCU32_HAL_WDT + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_pcc.h" +#include "mcu32_memory_map.h" +#include "wdt.h" +#include "wdt_bus.h" +#include "power_manager.h" +#include "mik32_hal_def.h" +#include "stddef.h" + +#define WDT_CLOCK32K_VALUE 32768 /**< Частота осцилляторов OSC32K или LSI32K. */ +#define WDT_CLOCK32M_VALUE 32000000 /**< Частота осцилляторов OSC32M или HSI32M. */ +#define WDT_MAX_VALUE_CLOCK32K 511875 /**< Максимально возможный интервал времени в миллисекундах при тактировании от OSC32K или LSI32K. */ +#define WDT_MAX_VALUE_CLOCK32M 524 /**< Максимально возможный интервал времени в миллисекундах при тактировании от OSC32M или HSI32M. */ +#define WDT_TIMEOUT_DEFAULT 10000 /**< Значение задержки по умолчанию. */ + +/** @brief Проверить установлен ли указанный флаг SPI или нет. + * @param __HANDLE__ Указатель WDT Handle. + * @param __FLAG__ Флаг для проверки. + * Этот параметр должен быть одним из следующих значений: + * - @ref WDT_STA_ENABLED_M: флаг активности таймера + * - @ref WDT_STA_LOADING_M: флаг перезагрузки значения + * - @ref WDT_STA_RST_FLAG_M: флаг генерации сброса сторожевым таймером. Сбрасывается в 0 только при снятии и последующей подаче питания. + * + * @return Состояние флага @p __FLAG__ (TRUE или FALSE). + */ +#define __HAL_WDT_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->STA) & (__FLAG__)) == (__FLAG__)) + +/** + * @brief Задать источник тактирования сторожевого таймера. + * @param __WDT_CLOCK__ Bсточник тактирования сторожевого таймера. + * Этот параметр должен быть одним из значений перечисления @ref HAL_WDT_Clocks. + */ +#define __HAL_WDT_SET_CLOCK(__WDT_CLOCK__) (PM->WDT_CLK_MUX = (__WDT_CLOCK__) & PM_WDT_CLK_MUX_M) + +/** + * @brief Перечисление делителей входной частоты сторожевого таймера. + * + */ +typedef enum __HAL_WDT_Prescale +{ + HAL_WDT_PRESCALE_1 = 0, /**< Делитель входной частоты сторожевого таймера 1. */ + HAL_WDT_PRESCALE_2 = 1, /**< Делитель входной частоты сторожевого таймера 2. */ + HAL_WDT_PRESCALE_4 = 2, /**< Делитель входной частоты сторожевого таймера 4. */ + HAL_WDT_PRESCALE_16 = 3, /**< Делитель входной частоты сторожевого таймера 16. */ + HAL_WDT_PRESCALE_64 = 4, /**< Делитель входной частоты сторожевого таймера 64. */ + HAL_WDT_PRESCALE_256 = 5, /**< Делитель входной частоты сторожевого таймера 256. */ + HAL_WDT_PRESCALE_1024 = 6, /**< Делитель входной частоты сторожевого таймера 1024. */ + HAL_WDT_PRESCALE_4096 = 7 /**< Делитель входной частоты сторожевого таймера 4096. */ +} HAL_WDT_Prescale; + +/** + * @brief Перечисление источников тактирования сторожевого таймера. + */ +typedef enum __HAL_WDT_Clocks +{ + HAL_WDT_OSC32M, /**< Внешний 32МГц. */ + HAL_WDT_HSI32M, /**< Внутренний 32МГц. */ + HAL_WDT_OSC32K, /**< Внешний 32кГц. */ + HAL_WDT_LSI32K /**< Внутренний 32кГц. */ +} HAL_WDT_Clocks; + +/** + * @brief Определение структуры конфигурации WDT. + */ +typedef struct __WDT_InitTypeDef +{ + HAL_WDT_Clocks Clock; /**< Источник тактирования WDT. */ + + /** + * @brief Время до перезагрузки контроллера в миллисекундах. + * + * Значение не должно превышать 524 мс при тактировании от источника 32 Мгц и + * 511875 мс при тактировании от источника 32 кГц. + */ + uint32_t ReloadMs; + +} WDT_InitTypeDef; + +/** + * @brief Определение структуры WDT Handle. + */ +typedef struct __WDT_HandleTypeDef +{ + WDT_TypeDef *Instance; /**< Адрес регистров WDT. */ + + WDT_InitTypeDef Init; /**< Параметры WDT. */ + +} WDT_HandleTypeDef; + +/** + * @brief Возвращаемая структура для функции @ref HAL_WDT_MillisInClock. + */ +typedef struct __WDT_ClockTypeDef +{ + uint32_t tick; /**< Начальное значение таймера при запуске или перезапуске для отсчета WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.Init.ReloadMs" миллисекунд. */ + + int divIndex; /**< Значение делителя частоты таймера для отсчета @ref WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.Init.ReloadMs" миллисекунд. */ + +} WDT_ClockTypeDef; + + +void HAL_RTC_MspInit(WDT_HandleTypeDef* hwdt); +HAL_StatusTypeDef HAL_WDT_Init(WDT_HandleTypeDef *hwdt, uint32_t timeout); +HAL_StatusTypeDef HAL_WDT_Refresh(WDT_HandleTypeDef *hwdt, uint32_t timeout); +HAL_StatusTypeDef HAL_WDT_Start(WDT_HandleTypeDef *hwdt, uint32_t timeout); +HAL_StatusTypeDef HAL_WDT_Stop(WDT_HandleTypeDef *hwdt, uint32_t timeout); +void HAL_WDT_SetPrescale(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale prescale); +void HAL_WDT_SetPreload(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale preload); + +#ifdef __cplusplus +} +#endif + +#endif // MCU32_HAL_WDT \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/put here h files.txt b/cores/arduino/mik32/hal/peripherals/Include/put here h files.txt new file mode 100644 index 0000000..e69de29 diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal.c new file mode 100644 index 0000000..7c8a1b7 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal.c @@ -0,0 +1,15 @@ +#include "mik32_hal.h" + + +__attribute__((weak)) void HAL_MspInit() +{ + __HAL_PCC_PAD_CONFIG_CLK_ENABLE(); + __HAL_PCC_EPIC_CLK_ENABLE(); +} + +HAL_StatusTypeDef HAL_Init() +{ + HAL_MspInit(); + + return HAL_OK; +} \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_adc.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_adc.c new file mode 100644 index 0000000..55f1113 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_adc.c @@ -0,0 +1,201 @@ +#include "mik32_hal_adc.h" + +__attribute__((weak)) void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + __HAL_PCC_ANALOG_REGS_CLK_ENABLE(); + + if ((hadc->Init.EXTClb == ADC_EXTCLB_ADCREF) && (hadc->Init.EXTRef == ADC_EXTREF_ON)) + { + #ifdef MIK32V0 + GPIO_InitStruct.Pin = GPIO_PIN_10; + #else // MIK32V2 + GPIO_InitStruct.Pin = GPIO_PIN_11; + #endif // MIK32V0 + } + + GPIO_InitStruct.Mode = HAL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + + switch (hadc->Init.Sel) + { + case ADC_CHANNEL0: + GPIO_InitStruct.Pin = GPIO_PIN_5; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + break; + + case ADC_CHANNEL1: + GPIO_InitStruct.Pin = GPIO_PIN_7; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + break; + + case ADC_CHANNEL2: + GPIO_InitStruct.Pin = GPIO_PIN_2; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + break; + + case ADC_CHANNEL3: + GPIO_InitStruct.Pin = GPIO_PIN_4; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + break; + + case ADC_CHANNEL4: + GPIO_InitStruct.Pin = GPIO_PIN_7; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + break; + + case ADC_CHANNEL5: + GPIO_InitStruct.Pin = GPIO_PIN_9; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + break; + + case ADC_CHANNEL6: + GPIO_InitStruct.Pin = GPIO_PIN_11; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + break; + + case ADC_CHANNEL7: + GPIO_InitStruct.Pin = GPIO_PIN_13; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + break; + } + +} + +void HAL_ADC_CLBEnable(ADC_HandleTypeDef *hadc) +{ + hadc->Instance->REFV_CONFIG |= 1 << REF_CLB_EN_S; +} + +void HAL_ADC_CLBDisable(ADC_HandleTypeDef *hadc) +{ + hadc->Instance->REFV_CONFIG &= ~(1 << REF_CLB_EN_S); +} + +void HAL_ADC_VCLBSet(ADC_HandleTypeDef *hadc, uint8_t v_coef) +{ + hadc->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_VCOEF_S); + hadc->Instance->REFV_CONFIG |= ((v_coef & 0xF) << REF_CLB_VCOEF_S); +} + +void HAL_ADC_ICLBSet(ADC_HandleTypeDef *hadc, uint8_t i_coef) +{ + hadc->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_ICOEF_S); + hadc->Instance->REFV_CONFIG |= ((i_coef & 0xF) << REF_CLB_ICOEF_S); +} + +void HAL_ADC_ResetEnable(ADC_HandleTypeDef *hadc) +{ +#ifdef MIK32V0 + hadc->Instance->ADC_CONFIG |= (1 << ADC_CONFIG_RESETN_S); +#else // MIK32V2 + hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) | + ((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) | + (1 << ADC_CONFIG_RESETN_S); +#endif // MIK32V0 +} + +void HAL_ADC_ResetDisable(ADC_HandleTypeDef *hadc) +{ + +#ifdef MIK32V0 + hadc->Instance->ADC_CONFIG &= ~(1 << ADC_CONFIG_RESETN_S); +#else // MIK32V2 + hadc->Instance->ADC_CONFIG = ((hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_RESETN_M)) & (~ADC_CONFIG_SAH_TIME_M)) | + ((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M); +#endif // MIK32V0 +} + +void HAL_ADC_Disable(ADC_HandleTypeDef *hadc) +{ + hadc->Instance->ADC_CONFIG &= ~(1 << ADC_CONFIG_EN_S); + HAL_ADC_ResetDisable(hadc); +} + +void HAL_ADC_Enable(ADC_HandleTypeDef *hadc) +{ +#ifdef MIK32V0 + hadc->Instance->ADC_CONFIG |= (1 << ADC_CONFIG_EN_S); +#else // MIK32V2 + hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) | + ((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) | + (1 << ADC_CONFIG_EN_S); + +#endif // MIK32V0 + HAL_ADC_ResetEnable(hadc); +} + +void HAL_ADC_ChannelSet(ADC_HandleTypeDef *hadc) +{ + +#ifdef MIK32V0 + hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SEL_M)) | (hadc->Init.Sel << ADC_CONFIG_SEL_S); /* Настройка канала АЦП */ +#else // MIK32V2 + hadc->Instance->ADC_CONFIG = ((hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) & (~ADC_CONFIG_SEL_M)) | + (hadc->Init.Sel << ADC_CONFIG_SEL_S) | + ((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M); +#endif // MIK32V0 +} + +void HAL_ADC_Init(ADC_HandleTypeDef *hadc) +{ + HAL_ADC_MspInit(hadc); +#ifdef MIK32V0 + hadc->Instance->ADC_CONFIG = 0; +#else // MIK32V2 + hadc->Instance->ADC_CONFIG = 0x3C00; +#endif // MIK32V0 + + HAL_ADC_Enable(hadc); + + HAL_ADC_ChannelSet(hadc); /* Настройка канала АЦП. Перевод используемого вывода в аналоговый режим */ + +#ifdef MIK32V0 + hadc->Instance->ADC_CONFIG |= (hadc->Init.EXTRef << ADC_CONFIG_EXTREF_S) | /* Настройка источника опорного напряжения */ + (hadc->Init.EXTClb << ADC_CONFIG_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */ +#else // MIK32V2 + hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) | + ((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) | + (hadc->Init.EXTRef << ADC_CONFIG_EXTREF_S) | /* Настройка источника опорного напряжения */ + (hadc->Init.EXTClb << ADC_CONFIG_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */ +#endif // MIK32V0 +} + +void HAL_ADC_Single(ADC_HandleTypeDef *hadc) +{ + hadc->Instance->ADC_SINGLE = 1; +} + +void HAL_ADC_ContinuousDisabled(ADC_HandleTypeDef *hadc) +{ + hadc->Instance->ADC_CONTINUOUS = 0; +} + +void HAL_ADC_ContinuousEnable(ADC_HandleTypeDef *hadc) +{ + hadc->Instance->ADC_CONTINUOUS = 1; +} + +void HAL_ADC_WaitValid(ADC_HandleTypeDef *hadc) +{ + /* Ожидание актуальных данных - ADC_VALID = 1 */ + while (!(hadc->Instance->ADC_VALID)) + ; +} + +uint16_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc) +{ + uint16_t value = hadc->Instance->ADC_VALUE; + + return value; +} + +uint16_t HAL_ADC_WaitAndGetValue(ADC_HandleTypeDef *hadc) +{ + HAL_ADC_WaitValid(hadc); + + uint16_t value = HAL_ADC_GetValue(hadc); + + return value; +} diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_crc32.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_crc32.c new file mode 100644 index 0000000..554516d --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_crc32.c @@ -0,0 +1,143 @@ +#include "mik32_hal_crc32.h" + + +__attribute__((weak)) void HAL_CRC32_MspInit(CRC_HandleTypeDef* hcrc) +{ + __HAL_PCC_CRC32_CLK_ENABLE(); +} + +void HAL_CRC_SetPoly(CRC_HandleTypeDef *hcrc) +{ + /* Задается полином */ + hcrc->Instance->POLY = hcrc->Poly; +} + +void HAL_CRC_SetInputReverse(CRC_HandleTypeDef *hcrc) +{ + /* Найстройка перестановки битов/байтов входных данных */ + hcrc->Instance->CTRL &= ~(0b11 << CRC_CTRL_TOT_S); + hcrc->Instance->CTRL |= hcrc->InputReverse << CRC_CTRL_TOT_S; +} + +void HAL_CRC_SetOutputInversion(CRC_HandleTypeDef *hcrc) +{ + hcrc->Instance->CTRL &= ~(1 << CRC_CTRL_FXOR_S); + hcrc->Instance->CTRL |= hcrc->OutputInversion << CRC_CTRL_FXOR_S; +} + +void HAL_CRC_SetOutputReverse(CRC_HandleTypeDef *hcrc) +{ + /* Найстройка перестановки битов/байтов выходных данных */ + hcrc->Instance->CTRL &= ~(0b11 << CRC_CTRL_TOTR_S); + hcrc->Instance->CTRL |= hcrc->OutputReverse << CRC_CTRL_TOTR_S; +} + +void HAL_CRC_SetInit(CRC_HandleTypeDef *hcrc) +{ + /* Назначение регистра данных: 1 – записываем начальное значение */ + hcrc->Instance->CTRL |= CRC_CTRL_WAS_M; + + /* Pапись в регистр данных 32-разрядное начальное значение */ + hcrc->Instance->DATA32 = hcrc->Init; + + /* Назначение регистра данных: 0 – записываем данные */ + hcrc->Instance->CTRL &= ~CRC_CTRL_WAS_M; +} + +void HAL_CRC_Init(CRC_HandleTypeDef *hcrc) +{ + HAL_CRC32_MspInit(hcrc); + + /* Найстройка перестановки битов/байтов входных данных */ + HAL_CRC_SetInputReverse(hcrc); + + /* Найстройка перестановки битов/байтов выходных данных */ + HAL_CRC_SetOutputReverse(hcrc); + + /* Инверсия контрольной суммы */ + HAL_CRC_SetOutputInversion(hcrc); + + /* Задается полином */ + HAL_CRC_SetPoly(hcrc); +} + +void HAL_CRC_WaitBusy(CRC_HandleTypeDef *hcrc) +{ + /* Ожидание 1 такта для установления флага BUSY в 1 после записи в регистр данных слова */ + for (uint8_t i = 0; i < 100; i++); + /* Ожидание когда флаг BUSY станет 0 - автомат закончил вычисления */ + while (hcrc->Instance->CTRL & CRC_CTRL_BUSY_M); +} + +void HAL_CRC_WriteData(CRC_HandleTypeDef *hcrc, uint8_t message[], uint32_t message_length) +{ + if(message_length > CRC_MAX_BYTES) + { + #ifdef MIK32_CRC_DEBUG + xprintf("Ошибка: переполнение буфера\n"); + #endif + + return; + } + + /* Запись начального значения Init */ + HAL_CRC_SetInit(hcrc); + + uint32_t i = 0; + while (i < message_length) + { + if (i + 3 < message_length) + { + hcrc->Instance->DATA32 = (message[i+3] << 0) | + (message[i+2] << 8) | + (message[i+1] << 16) | + (message[i] << 24); + i += 4; + } + else if (i + 1 < message_length) + { + hcrc->Instance->DATA16 = (message[i+1] << 0) | + (message[i] << 8); + i += 2; + } + else + { + hcrc->Instance->DATA8 = message[i]; + i += 1; + } + } +} + +void HAL_CRC_WriteData32(CRC_HandleTypeDef *hcrc, uint32_t message[], uint32_t message_length) +{ + if(message_length > CRC_MAX_WORDS) + { + #ifdef MIK32_CRC_DEBUG + xprintf("Ошибка: переполнение буфера\n"); + #endif + + return; + } + + + /* Запись начального значения Init */ + HAL_CRC_SetInit(hcrc); + + uint32_t data; + for(uint32_t i = 0; i < message_length; i++) + { + data = message[i]; + hcrc->Instance->DATA32 = data; + } +} + +uint32_t HAL_CRC_ReadCRC(CRC_HandleTypeDef *hcrc) +{ + uint32_t CRCValue; + /* Ожидание завершения вычисления CRC */ + HAL_CRC_WaitBusy(hcrc); + + CRCValue = CRC->DATA32; + + return CRCValue; +} diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_crypto.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_crypto.c new file mode 100644 index 0000000..3e42dbe --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_crypto.c @@ -0,0 +1,336 @@ +#include "mik32_hal_crypto.h" + +/** + * @brief Включение тактирования модуля Crypto. + * @note Эта weak функция может быть переопределена пользователем. + * @param hcrypto Указатель на структуру с настройками Crypto. + */ +__attribute__((weak)) void HAL_CRYPTO_MspInit(Crypto_HandleTypeDef* hcrypto) +{ + __HAL_PCC_CRYPTO_CLK_ENABLE(); +} + +/** + * @brief Сброс счётчиков загружаемых/выгружаемых данных. + * @param hcrypto Указатель на структуру с настройками Crypto. + */ +void HAL_Crypto_CounterReset(Crypto_HandleTypeDef *hcrypto) +{ + hcrypto->Instance->CONFIG |= CRYPTO_CONFIG_C_RESET_M; +} + +/** + * @brief Ожидать когда модуль станет доступен. + * @param hcrypto Указатель на структуру с настройками Crypto. + */ +void HAL_Crypto_WaitReady(Crypto_HandleTypeDef *hcrypto) +{ + while (!(hcrypto->Instance->CONFIG & CRYPTO_CONFIG_READY_M)); +} + +/** + * @brief Задать алгоритм шифрования. + * @param hcrypto Указатель на структуру с настройками Crypto. + * @param Algorithm Алгоритм шифрования. + */ +void HAL_Crypto_SetAlgorithm(Crypto_HandleTypeDef *hcrypto, uint8_t Algorithm) +{ + hcrypto->Algorithm = Algorithm; + + uint32_t ConfigTemp = hcrypto->Instance->CONFIG; + + ConfigTemp &= ~CRYPTO_CONFIG_CORE_SEL_M; /* Обнуление DECODE */ + + ConfigTemp |= Algorithm << CRYPTO_CONFIG_CORE_SEL_S; + + hcrypto->Instance->CONFIG = ConfigTemp; +} + +/** + * @brief Задать режим шифрования. + * @param hcrypto Указатель на структуру с настройками Crypto. + * @param CipherMode Режим шифрования. + */ +void HAL_Crypto_SetCipherMode(Crypto_HandleTypeDef *hcrypto, uint8_t CipherMode) +{ + hcrypto->CipherMode = CipherMode; + + uint32_t ConfigTemp = hcrypto->Instance->CONFIG; + + ConfigTemp &= ~CRYPTO_CONFIG_MODE_SEL_M; /* Обнуление MODE_SEL */ + + ConfigTemp |= CipherMode << CRYPTO_CONFIG_MODE_SEL_S; + + hcrypto->Instance->CONFIG = ConfigTemp; +} + +/** + * @brief Задать режим перестановки слова. + * @param hcrypto Указатель на структуру с настройками Crypto. + * @param SwapMode Режим перестановки слова. + */ +void HAL_Crypto_SetSwapMode(Crypto_HandleTypeDef *hcrypto, uint8_t SwapMode) +{ + hcrypto->SwapMode = SwapMode; + + uint32_t ConfigTemp = hcrypto->Instance->CONFIG; + + ConfigTemp &= ~CRYPTO_CONFIG_SWAP_MODE_M; /* Обнуление SWAP_MODE */ + + ConfigTemp |= SwapMode << CRYPTO_CONFIG_SWAP_MODE_S; + + hcrypto->Instance->CONFIG = ConfigTemp; +} + +/** + * @brief Задать порядок загрузки/выгрузки данных. + * @param hcrypto Указатель на структуру с настройками Crypto. + * @param OrderMode Порядок загрузки/выгрузки данных. + */ +void HAL_Crypto_SetOrderMode(Crypto_HandleTypeDef *hcrypto, uint8_t OrderMode) +{ + hcrypto->OrderMode = OrderMode; + + uint32_t ConfigTemp = hcrypto->Instance->CONFIG; + + ConfigTemp &= ~CRYPTO_CONFIG_ORDER_MODE_M; /* Обнуление ORDER_MODE */ + + ConfigTemp |= OrderMode << CRYPTO_CONFIG_ORDER_MODE_S; + + hcrypto->Instance->CONFIG = ConfigTemp; +} + +/** + * @brief Задать вектор инициализации. + * @param hcrypto Указатель на структуру с настройками Crypto. + * @param InitVector Вектор инициализации (IV). + * @param IvLength Количество слов в InitVector. + */ +void HAL_Crypto_SetIV(Crypto_HandleTypeDef *hcrypto, uint32_t InitVector[], uint32_t IvLength) +{ + + for (uint32_t i = 0; i < IvLength; i++) + { + hcrypto->Instance->INIT = InitVector[i]; + } + + /* В режиме шифрования CTR длина вектора инициализации равна половине блока и такое же количество нулей */ + if(hcrypto->CipherMode == CRYPTO_CIPHER_MODE_CTR) + { + for (uint32_t i = 0; i < IvLength; i++) + { + hcrypto->Instance->INIT = 0; + } + } + +} + +/** + * @brief Задать мастер-ключ. + * @param hcrypto Указатель на структуру с настройками Crypto. + * @param crypto_key Ключ. + * + * @warning Ключ должен быть инициализирован в режиме шифрования (CONFIG.DECODE = 0). + */ +void HAL_Crypto_SetKey(Crypto_HandleTypeDef *hcrypto, uint32_t crypto_key[]) +{ + uint32_t key_length = 0; + + switch (hcrypto->Algorithm) + { + case CRYPTO_ALG_KUZNECHIK: + key_length = CRYPTO_KEY_KUZNECHIK; + break; + case CRYPTO_ALG_MAGMA: + key_length = CRYPTO_KEY_MAGMA; + break; + case CRYPTO_ALG_AES: + key_length = CRYPTO_KEY_AES; + break; + } + + /* Ключ должен быть инициализирован в режиме шифрования */ + hcrypto->Instance->CONFIG &= ~CRYPTO_CONFIG_DECODE_M; + + for (uint32_t i = 0; i < key_length; i++) + { + hcrypto->Instance->KEY = crypto_key[i]; + } + + HAL_Crypto_WaitReady(hcrypto); +} + +/** + * @brief Инициализировать Crypto в соответствии с настройками @ref Crypto_HandleTypeDef *hcrypto. + * @param hcrypto Указатель на структуру с настройками Crypto. + */ +void HAL_Crypto_Init(Crypto_HandleTypeDef *hcrypto) +{ + HAL_CRYPTO_MspInit(hcrypto); + + HAL_Crypto_SetAlgorithm(hcrypto, hcrypto->Algorithm); /* Настройка алгоритма шифрования */ + HAL_Crypto_SetCipherMode(hcrypto, hcrypto->CipherMode); /* Настройка режима шифрования */ + HAL_Crypto_SetSwapMode(hcrypto, hcrypto->SwapMode); /* Настройка перестановки слова */ + HAL_Crypto_SetOrderMode(hcrypto, hcrypto->OrderMode); /* Настройка порядка загрузки/выгрузки */ + + + #ifdef MIK32_CRYPTO_DEBUG + + switch (hcrypto->Algorithm) + { + case CRYPTO_ALG_KUZNECHIK: + xprintf("KUZNECHIK- "); + break; + case CRYPTO_ALG_MAGMA: + xprintf("MAGMA - "); + break; + case CRYPTO_ALG_AES: + xprintf("AES - "); + break; + } + + switch (hcrypto->CipherMode) + { + case CRYPTO_CIPHER_MODE_ECB: + xprintf("ECB\n"); + break; + case CRYPTO_CIPHER_MODE_CBC: + xprintf("CBC\n"); + break; + case CRYPTO_CIPHER_MODE_CTR: + xprintf("CTR\n"); + break; + } + + #endif +} + +/** + * @brief Зашифровать текст. + * + * Зашифрованный текст передается в массив cipher_text. + * + * @param hcrypto Указатель на структуру с настройками Crypto. + * @param plain_text Массив с данными незашифрованного текста. + * @param cipher_text Массив с данными для зашифрованного текста. + * @param text_length Количество слов в тексте. + */ +void HAL_Crypto_Encode(Crypto_HandleTypeDef *hcrypto, uint32_t plain_text[], uint32_t cipher_text[], uint32_t text_length) +{ + uint8_t block_size = 0; + + switch (hcrypto->Algorithm) + { + case CRYPTO_ALG_KUZNECHIK: + block_size = CRYPTO_BLOCK_KUZNECHIK; + break; + case CRYPTO_ALG_MAGMA: + block_size = CRYPTO_BLOCK_MAGMA; + break; + case CRYPTO_ALG_AES: + block_size = CRYPTO_BLOCK_AES; + break; + } + + if(((text_length % block_size) != 0)/* && (hcrypto->CipherMode != CRYPTO_CIPHER_MODE_CTR) */) + { + #ifdef MIK32_CRYPTO_DEBUG + xprintf("Длина текста не кратна длине блока\n"); + #endif + + return; + } + + /* Режим шифрования */ + hcrypto->Instance->CONFIG &= ~CRYPTO_CONFIG_DECODE_M; + + for (volatile uint32_t block_index = 0; block_index < text_length; block_index += block_size) + { + for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++) + { + if (word_index >= text_length) + { + break; + } + hcrypto->Instance->BLOCK = plain_text[word_index]; + + } + + HAL_Crypto_WaitReady(hcrypto); + + for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++) + { + if (word_index >= text_length) + { + break; + } + cipher_text[word_index] = hcrypto->Instance->BLOCK; + } + } + +} + +/** + * @brief Расшифровать текст. + * + * Расшифрованный текст передается в массив plain_text. + * + * @param hcrypto Указатель на структуру с настройками Crypto. + * @param cipher_text Массив с данными зашифрованного текста. + * @param plain_text Массив с данными для незашифрованного текста. + * @param text_length Количество слов в тексте. + */ +void HAL_Crypto_Decode(Crypto_HandleTypeDef *hcrypto, uint32_t cipher_text[], uint32_t plain_text[], uint32_t text_length) +{ + uint8_t block_size = 0; + + switch (hcrypto->Algorithm) + { + case CRYPTO_ALG_KUZNECHIK: + block_size = CRYPTO_BLOCK_KUZNECHIK; + break; + case CRYPTO_ALG_MAGMA: + block_size = CRYPTO_BLOCK_MAGMA; + break; + case CRYPTO_ALG_AES: + block_size = CRYPTO_BLOCK_AES; + break; + } + + if(((text_length % block_size) != 0)/* && (hcrypto->CipherMode != CRYPTO_CIPHER_MODE_CTR)*/) + { + #ifdef MIK32_CRYPTO_DEBUG + xprintf("Длина текста не кратна длине блока\n"); + #endif + + return; + } + + /* Режим расшифровки */ + hcrypto->Instance->CONFIG |= CRYPTO_CONFIG_DECODE_M; + + for (volatile uint32_t block_index = 0; block_index < text_length; block_index += block_size) + { + for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++) + { + if (word_index >= text_length) + { + break; + } + hcrypto->Instance->BLOCK = cipher_text[word_index]; + } + + HAL_Crypto_WaitReady(hcrypto); + + for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++) + { + if (word_index >= text_length) + { + break; + } + plain_text[word_index] = hcrypto->Instance->BLOCK; + } + } + +} + diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_dac.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_dac.c new file mode 100644 index 0000000..96deecd --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_dac.c @@ -0,0 +1,125 @@ +#include "mik32_hal_dac.h" + +__attribute__((weak)) void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + __HAL_PCC_ANALOG_REGS_CLK_ENABLE(); + + if ((hdac->Init.EXTClb == DAC_EXTCLB_DACREF) && (hdac->Init.EXTRef == DAC_EXTREF_ON)) + { + GPIO_InitStruct.Pin = GPIO_PIN_11; + } + GPIO_InitStruct.Mode = HAL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + + if (hdac->Instance_dac == &(ANALOG_REG->DAC0)) + { + GPIO_InitStruct.Pin = GPIO_PIN_12; + } + + if (hdac->Instance_dac == &(ANALOG_REG->DAC1)) + { + GPIO_InitStruct.Pin = GPIO_PIN_13; + } + + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); +} + +void HAL_DAC_CLBEnable(DAC_HandleTypeDef *hdac) +{ + hdac->Instance->REFV_CONFIG |= 1 << REF_CLB_EN_S; +} + +void HAL_DAC_CLBDisable(DAC_HandleTypeDef *hdac) +{ + hdac->Instance->REFV_CONFIG &= ~(1 << REF_CLB_EN_S); +} + +void HAL_DAC_VCLBSet(DAC_HandleTypeDef *hdac, uint8_t v_coef) +{ + hdac->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_VCOEF_S); + hdac->Instance->REFV_CONFIG |= ((v_coef & 0xF) << REF_CLB_VCOEF_S); +} + +void HAL_DAC_ICLBSet(DAC_HandleTypeDef *hdac, uint8_t i_coef) +{ + hdac->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_ICOEF_S); + hdac->Instance->REFV_CONFIG |= ((i_coef & 0xF) << REF_CLB_ICOEF_S); +} + +void HAL_DAC_SetDiv(DAC_HandleTypeDef *hdac, uint8_t div) +{ + //div &= ~(1<<7); // div должно быть 7-битным + + hdac->Init.DIV = div; + + uint32_t DAC_CFG = hdac->Instance_dac->CFG; + + DAC_CFG &= ~DAC_CFG_DIV_M; + DAC_CFG |= DAC_CFG_DIV_M; + + hdac->Instance_dac->CFG = DAC_CFG; + +} + +void HAL_DAC_ResetEnable(DAC_HandleTypeDef *hdac) +{ + hdac->Instance_dac->CFG |= DAC_CFG_RESN_M; +} + +void HAL_DAC_ResetDisable(DAC_HandleTypeDef *hdac) +{ + hdac->Instance_dac->CFG &= ~DAC_CFG_RESN_M; +} + +void HAL_DAC_Disable(DAC_HandleTypeDef *hdac) +{ + hdac->Instance_dac->CFG &= ~DAC_CFG_EN18_M; + HAL_DAC_ResetDisable(hdac); +} + +void HAL_DAC_Enable(DAC_HandleTypeDef *hdac) +{ + hdac->Instance_dac->CFG |= DAC_CFG_EN18_M; + HAL_DAC_ResetEnable(hdac); +} + +void HAL_DAC_Init(DAC_HandleTypeDef *hdac) +{ + HAL_DAC_MspInit(hdac); + + /* Очищение регистра настроек ЦАП */ + hdac->Instance_dac->CFG = 0; + + HAL_DAC_Enable(hdac); + + /* Перевод вывода DAC_REF в аналоговый режим */ + if((hdac->Init.EXTRef == DAC_EXTREF_ON) || (hdac->Init.EXTClb == DAC_EXTCLB_DACREF)) + { + PAD_CONFIG->PORT_1_CFG |= (DAC_PORT_AS_FUNC3 << 2 * DAC_REF_PORT_1_11); + } + + /* Перевод вывода ЦАП в аналоговый режим */ + if(hdac->Instance_dac == HAL_DAC1) + { + PAD_CONFIG->PORT_1_CFG |= (DAC_PORT_AS_FUNC3 << 2 * DAC1_PORT_1_12); + } + if(hdac->Instance_dac == HAL_DAC2) + { + PAD_CONFIG->PORT_1_CFG |= (DAC_PORT_AS_FUNC3 << 2 * DAC2_PORT_1_13); + } + + HAL_DAC_SetDiv(hdac, hdac->Init.DIV); /* Задание делителя */ + + hdac->Instance_dac->CFG |= (hdac->Init.EXTRef << DAC_CFG_EXTEN_S) | /* Настройка источника опорного напряжения */ + (hdac->Init.EXTClb << DAC_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */ + + +} + +void HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint16_t DAC_Value) +{ + DAC_Value &= ~(0xF << 12); + hdac->Instance_dac->VALUE = DAC_Value; +} \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_dma.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_dma.c new file mode 100644 index 0000000..92ec7b1 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_dma.c @@ -0,0 +1,284 @@ +#include "mik32_hal_dma.h" + +/** + * @brief Данная переменная хранит последнее записанное значение в регистр CHx_CFG. + * @warning Не следует изменять значение данной переменной. + */ +static uint32_t CFGWriteBuffer[4] = {0}; + +/** + * @brief Данная переменная используется для хранения значения битовых полей CONFIG_STATUS[8:6]. + * @warning Не следует изменять значение данной переменной. + */ +static uint32_t ConfigStatusWriteBuffer = 0; + + +/** + * @brief Включение тактирования модуля OTP. + * + * Эта функция может быть переопределена пользователем. + * @param hdma Указатель на структуру для инициализации DMA. + */ +__attribute__((weak)) void HAL_DMA_MspInit(DMA_InitTypeDef* hdma) +{ + __HAL_PCC_DMA_CLK_ENABLE(); +} + +/** + * @brief Задать номер канала. + * @param hdma_channel Указатель на структуру для инициализации канала DMA. + * @param ChannelIndex Номер канала. + */ +void HAL_DMA_SetChannel(DMA_ChannelHandleTypeDef *hdma_channel, HAL_DMA_ChannelIndexTypeDef ChannelIndex) +{ + hdma_channel->ChannelInit.Channel = ChannelIndex; +} + +/** + * @brief Очистить все флаги локального прерывания. + * @param hdma Указатель на структуру для инициализации DMA. + */ +void HAL_DMA_ClearLocalIrq(DMA_InitTypeDef *hdma) +{ + ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M); + ConfigStatusWriteBuffer |= DMA_CONFIG_CLEAR_LOCAL_IRQ_M; + hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer; + ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M); +} + +/** + * @brief Очистить флаг глобального прерывания. + * @param hdma Указатель на структуру для инициализации DMA. + */ +void HAL_DMA_ClearGlobalIrq(DMA_InitTypeDef *hdma) +{ + ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M); + ConfigStatusWriteBuffer |= DMA_CONFIG_CLEAR_GLOBAL_IRQ_M; + hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer; + ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M); +} + +/** + * @brief Очистить флаг прерывания ошибки. + * @param hdma Указатель на структуру для инициализации DMA. + */ +void HAL_DMA_ClearErrorIrq(DMA_InitTypeDef *hdma) +{ + ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M); + ConfigStatusWriteBuffer |= DMA_CONFIG_CLEAR_ERROR_IRQ_M; + hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer; + ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M); +} + +/** + * @brief Очистить все флаги прерываний. + * + * Очищаются флаги локальных прерываний, глобального прерывания, прерывания ошибки. + * @param hdma Указатель на структуру для инициализации DMA. + */ +void HAL_DMA_ClearIrq(DMA_InitTypeDef *hdma) +{ + HAL_DMA_ClearLocalIrq(hdma); + HAL_DMA_ClearGlobalIrq(hdma); + HAL_DMA_ClearErrorIrq(hdma); +} + +/** + * @brief Задать разрешение чтения текущего статуса канала. + * + * При значении #DMA_CURRENT_VALUE_ENABLE регистры CHx_DST, CHx_SRC, CHx_LEN возвращают текущие значения, + * а в CHx_CFG при считывании меняются битовые поля. При значении #DMA_CURRENT_VALUE_DISABLE регистры возвращают значения при настройке. + * @param hdma Указатель на структуру для инициализации DMA. + * @param CurrentValue Разрешение или запрет чтения текущего статуса канала. + */ +void HAL_DMA_SetCurrentValue(DMA_InitTypeDef *hdma, HAL_DMA_CurrentValueTypeDef CurrentValue) +{ + hdma->CurrentValue = CurrentValue; + ConfigStatusWriteBuffer &= ~DMA_CONFIG_CURRENT_VALUE_M; + ConfigStatusWriteBuffer |= CurrentValue << DMA_CONFIG_CURRENT_VALUE_S; + hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer; +} + +/** + * @brief Разрешить или запретить глобальное прерывание. + * @param hdma Указатель на структуру для инициализации DMA. + * @param Permission Разрешение (#DMA_IRQ_ENABLE) или запрет (#DMA_IRQ_DISABLE) прерывания. + */ +void HAL_DMA_GlobalIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission) +{ + ConfigStatusWriteBuffer &= ~DMA_CONFIG_GLOBAL_IRQ_ENA_M; + ConfigStatusWriteBuffer |= Permission << DMA_CONFIG_GLOBAL_IRQ_ENA_S; + hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer; +} + +/** + * @brief Разрешить или запретить прерывание ошибки. + * @param hdma Указатель на структуру для инициализации DMA. + * @param Permission Разрешение (#DMA_IRQ_ENABLE) или запрет (#DMA_IRQ_DISABLE) прерывания. + */ +void HAL_DMA_ErrorIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission) +{ + ConfigStatusWriteBuffer &= ~DMA_CONFIG_ERROR_IRQ_ENA_M; + ConfigStatusWriteBuffer |= Permission << DMA_CONFIG_ERROR_IRQ_ENA_S; + hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer; +} + +/** + * @brief Разрешить или запретить локальное прерывание. + * + * Прерывание формируется, когда канал завершил задачу. + * @param hdma_channel Структура для инициализации канала DMA. + * @param Permission Разрешение (#DMA_IRQ_ENABLE) или запрет (#DMA_IRQ_DISABLE) прерывания. + */ +void HAL_DMA_LocalIRQEnable(DMA_ChannelHandleTypeDef* hdma_channel, HAL_DMA_IRQTypeDef Permission) +{ + uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel; + + CFGWriteBuffer[ChannelIndex] &= ~DMA_CH_CFG_IRQ_EN_M; + CFGWriteBuffer[ChannelIndex] |= Permission << DMA_CH_CFG_IRQ_EN_S; + + hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex]; +} + +/** + * @brief Инициализация DMA в соответствии с настройками структуры hdma. + * @param hdma Указатель на структуру для инициализации DMA. + * @return Статус функции после её выполнения (HAL Status). + */ +HAL_StatusTypeDef HAL_DMA_Init(DMA_InitTypeDef *hdma) +{ + if (hdma == NULL) + { + return HAL_ERROR; + } + + HAL_DMA_MspInit(hdma); + + ConfigStatusWriteBuffer = 0; + + HAL_DMA_ClearIrq(hdma); + HAL_DMA_SetCurrentValue(hdma, hdma->CurrentValue); + + return HAL_OK; +} + +/** + * @brief Ожидание готовности канала. + * @param hdma_channel Структура для инициализации канала DMA. + * @param Timeout Количество циклов ожидания. Стандартное значение #DMA_TIMEOUT_DEFAULT. + * @return Статус функции после её выполнения (HAL Status). + */ +HAL_StatusTypeDef HAL_DMA_Wait(DMA_ChannelHandleTypeDef* hdma_channel, uint32_t Timeout) +{ + uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel; + + uint32_t mask = (1 << ChannelIndex) << DMA_STATUS_READY_S; + + while (Timeout-- != 0) + { + if ((hdma_channel->dma->Instance->CONFIG_STATUS & mask) != 0) + { + return HAL_OK; + } + } + + return HAL_TIMEOUT; +} + +/** + * @brief Получить статус готовности канала. + * @param hdma_channel Структура для инициализации канала DMA. + * @return Статус готовности канала. 0 - канал занят, 1 - канал готов к работе. + */ +int HAL_DMA_GetChannelReadyStatus(DMA_ChannelHandleTypeDef* hdma_channel) +{ + uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel; + + uint32_t status = ((hdma_channel->dma->Instance->CONFIG_STATUS) & ((1 << ChannelIndex) << DMA_STATUS_READY_S)); + status = (status >> DMA_STATUS_READY_S ) >> ChannelIndex; + return status; +} + +/** + * @brief Получить статус локального прерывания канала. + * @param hdma_channel Структура для инициализации канала DMA. + * @return Статус локального прерывания канала. 0 - прерывания нет, 1 - прерывание есть. + */ +int HAL_DMA_GetChannelIrq(DMA_ChannelHandleTypeDef* hdma_channel) +{ + uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel; + uint32_t ChannelIrq = (hdma_channel->dma->Instance->CONFIG_STATUS) & ((1 << ChannelIndex) << DMA_STATUS_CHANNEL_IRQ_S); + ChannelIrq = ( ChannelIrq >> DMA_STATUS_CHANNEL_IRQ_S ) >> ChannelIndex; + return ChannelIrq; +} + +/** + * @brief Получить статус состояния канала при ошибках на шине. + * @param hdma_channel Структура для инициализации канала DMA. + * @return Статус состояния канала при ошибках на шине. 0 - нет ошибки, 1 - есть ошибка. + */ +int HAL_DMA_GetBusError(DMA_ChannelHandleTypeDef* hdma_channel) +{ + uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel; + uint32_t BusError = ((hdma_channel->dma->Instance->CONFIG_STATUS) & ((1 << ChannelIndex) << DMA_STATUS_CHANNEL_BUS_ERROR_S)); + BusError = ( BusError >> DMA_STATUS_CHANNEL_BUS_ERROR_S ) >> ChannelIndex; + return BusError; +} + +/** + * @brief Принудительная остановка работы канала. + * @param hdma_channel Структура для инициализации канала DMA. + */ +void HAL_DMA_ChannelDisable(DMA_ChannelHandleTypeDef *hdma_channel) +{ + uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel; + CFGWriteBuffer[ChannelIndex] &= ~(DMA_CH_CFG_ENABLE_M); + hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex]; +} + +/** + * @brief Инициализация работы канала. + * @param hdma_channel Структура для инициализации канала DMA. + */ +void HAL_DMA_ChannelEnable(DMA_ChannelHandleTypeDef *hdma_channel) +{ + uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel; + CFGWriteBuffer[ChannelIndex] |= DMA_CH_CFG_ENABLE_M; + hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex]; +} + +/** + * @brief Запуск работы канала с настройками из структуры hdma_channel. + * @param hdma_channel Структура для инициализации канала DMA. + * @param SRC Адрес источника. + * @param DST Адрес назначения + * @param Len Количество байт пересылки. Значение следует записывать на 1 меньше числа пересылаемых байт. + * Например, для отправки 8 байт значение Len = 7. + */ +void HAL_DMA_Start(DMA_ChannelHandleTypeDef *hdma_channel, void* SRC, void* DST, uint32_t Len) +{ + uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel; + + hdma_channel->dma->Instance->CHANNELS[ChannelIndex].SRC = (uint32_t) SRC; + hdma_channel->dma->Instance->CHANNELS[ChannelIndex].DST = (uint32_t) DST; + hdma_channel->dma->Instance->CHANNELS[ChannelIndex].LEN = Len; + + + CFGWriteBuffer[ChannelIndex] |= DMA_CH_CFG_ENABLE_M + | (hdma_channel->ChannelInit.Priority << DMA_CH_CFG_PRIOR_S) + | (hdma_channel->ChannelInit.ReadMode << DMA_CH_CFG_READ_MODE_S) + | (hdma_channel->ChannelInit.ReadInc << DMA_CH_CFG_READ_INCREMENT_S) + | (hdma_channel->ChannelInit.ReadSize << DMA_CH_CFG_READ_SIZE_S) + | (hdma_channel->ChannelInit.ReadBurstSize << DMA_CH_CFG_READ_BURST_SIZE_S) + | (hdma_channel->ChannelInit.ReadRequest << DMA_CH_CFG_READ_REQUETS_S) + | (hdma_channel->ChannelInit.ReadAck << DMA_CH_CFG_READ_ACK_EN_S) + | (hdma_channel->ChannelInit.WriteMode << DMA_CH_CFG_WRITE_MODE_S) + | (hdma_channel->ChannelInit.WriteInc << DMA_CH_CFG_WRITE_INCREMENT_S) + | (hdma_channel->ChannelInit.WriteSize << DMA_CH_CFG_WRITE_SIZE_S) + | (hdma_channel->ChannelInit.WriteBurstSize << DMA_CH_CFG_WRITE_BURST_SIZE_S) + | (hdma_channel->ChannelInit.WriteRequest << DMA_CH_CFG_WRITE_REQUETS_S) + | (hdma_channel->ChannelInit.WriteAck << DMA_CH_CFG_WRITE_ACK_EN_S); + + hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex]; +} + diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_eeprom.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_eeprom.c new file mode 100644 index 0000000..1d603e2 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_eeprom.c @@ -0,0 +1,197 @@ +#include "mik32_hal_eeprom.h" + +const uint8_t N_LD_DEFAULT = 1; +const uint8_t N_R_2_DEFAULT = 1; + +HAL_StatusTypeDef HAL_EEPROM_Init(HAL_EEPROM_HandleTypeDef *eeprom) +{ + if (eeprom->Instance != EEPROM_REGS) + { + return HAL_ERROR; + } + + eeprom->Instance->EECON = 0; + HAL_EEPROM_SetMode(eeprom, eeprom->Mode); + HAL_EEPROM_SetErrorCorrection(eeprom, eeprom->ErrorCorrection); + HAL_EEPROM_SetInterrupt(eeprom, eeprom->EnableInterrupt); + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_EEPROM_Erase( + HAL_EEPROM_HandleTypeDef *eeprom, + uint16_t address, + uint8_t erasedWordsCount, + HAL_EEPROM_WriteBehaviourTypeDef erasedPages, + uint32_t timeout) +{ + eeprom->Instance->EECON |= EEPROM_EECON_BWE_M | (erasedPages << EEPROM_EECON_WRBEH_S); + + if (eeprom->Mode == HAL_EEPROM_MODE_TWO_STAGE) + { + eeprom->Instance->EEA = address; + for (int i = 0; i < erasedWordsCount; i++) + { + eeprom->Instance->EEDAT = 0; + } + } + else + { + HAL_StatusTypeDef status = HAL_OK; + for (int i = 0; i < erasedWordsCount; i++) + { + eeprom->Instance->EEA = address + i * 4; + eeprom->Instance->EEDAT = 0; + if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK) + return status; + } + } + + eeprom->Instance->EECON |= EEPROM_EECON_OP(EEPROM_EECON_OP_ER) | EEPROM_EECON_EX_M; + + return HAL_EEPROM_WaitBusy(eeprom, timeout); +} + +HAL_StatusTypeDef HAL_EEPROM_Write( + HAL_EEPROM_HandleTypeDef *eeprom, + uint16_t address, + uint32_t *data, + uint8_t length, + HAL_EEPROM_WriteBehaviourTypeDef writedPages, + uint32_t timeout) +{ + eeprom->Instance->EECON |= EEPROM_EECON_BWE_M | (writedPages << EEPROM_EECON_WRBEH_S); + + if (eeprom->Mode == HAL_EEPROM_MODE_TWO_STAGE) + { + eeprom->Instance->EEA = address; + for (int i = 0; i < length; i++) + { + eeprom->Instance->EEDAT = data[i]; + } + } + else + { + HAL_StatusTypeDef status = HAL_OK; + for (int i = 0; i < length; i++) + { + eeprom->Instance->EEA = address + i * 4; + eeprom->Instance->EEDAT = data[i]; + if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK) + return status; + } + } + + eeprom->Instance->EECON |= EEPROM_EECON_OP(EEPROM_EECON_OP_PR) | EEPROM_EECON_EX_M; + + return HAL_EEPROM_WaitBusy(eeprom, timeout); +} + +HAL_StatusTypeDef HAL_EEPROM_Read(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint32_t *data, uint8_t length, uint32_t timeout) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (eeprom->Mode == HAL_EEPROM_MODE_TWO_STAGE) + { + eeprom->Instance->EEA = address; + for (uint32_t i = 0; i < length; i++) + { + data[i] = eeprom->Instance->EEDAT; + } + } + else + { + + for (uint32_t i = 0; i < length; i++) + { + eeprom->Instance->EEA = address + i * 4; + if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK) + return status; + data[i] = eeprom->Instance->EEDAT; + } + } + + return status; +} + +void HAL_EEPROM_SetMode(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ModeTypeDef mode) +{ + eeprom->Mode = mode; + + if (eeprom->Mode == HAL_EEPROM_MODE_THREE_STAGE) + { + eeprom->Instance->EECON |= EEPROM_EECON_APBNWS_M; + } + else + { + eeprom->Instance->EECON &= ~EEPROM_EECON_APBNWS_M; + } +} + +void HAL_EEPROM_SetErrorCorrection(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ErrorCorrectionTypeDef errorCorrection) +{ + eeprom->ErrorCorrection = errorCorrection; + + if (eeprom->ErrorCorrection == HAL_EEPROM_ECC_DISABLE) + { + eeprom->Instance->EECON |= EEPROM_EECON_DISECC_M; + } + else + { + eeprom->Instance->EECON &= ~EEPROM_EECON_DISECC_M; + } +} + +void HAL_EEPROM_SetInterrupt(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_EnableInterruptTypeDef enableInterrupt) +{ + eeprom->EnableInterrupt = enableInterrupt; + + if (eeprom->EnableInterrupt == HAL_EEPROM_SERR_ENABLE) + { + eeprom->Instance->EECON |= EEPROM_EECON_IESERR_M; + } + else + { + eeprom->Instance->EECON &= ~EEPROM_EECON_IESERR_M; + } +} + +const int32_t N_EP_1_denominator = 1000 * 1000 * 1000 / (2 * 1000 * 1000); + +const int32_t N_EP_2_reduce = 5 * 1000; +const int32_t N_EP_2_numerator = 15 * 1000 / N_EP_2_reduce; +const int32_t N_EP_2_denominator = 1000 * 1000 * 1000 / N_EP_2_reduce; + +void HAL_EEPROM_CalculateTimings(HAL_EEPROM_HandleTypeDef *eeprom, int32_t frequency) +{ + eeprom->Timings.N_LD = N_LD_DEFAULT; + eeprom->Timings.N_R_2 = N_R_2_DEFAULT; + + eeprom->Timings.N_EP_1 = frequency / N_EP_1_denominator; + + eeprom->Timings.N_EP_2 = (frequency * N_EP_2_numerator) / N_EP_2_denominator; + + int32_t n_r_1_step_1 = (frequency / 1000) * 51; + int32_t n_r_1_step_2 = n_r_1_step_1 / (1000 * 1000); + + if ((n_r_1_step_1 % (1000 * 1000)) != 0) + { + n_r_1_step_2 += 1; + } + + eeprom->Timings.N_R_1 = n_r_1_step_2; +} + +HAL_StatusTypeDef HAL_EEPROM_GetECC(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint8_t *buf_value_ecc, uint32_t timeout) +{ + HAL_StatusTypeDef status = HAL_OK; + eeprom->Instance->EEA = address; + if (eeprom->Mode == HAL_EEPROM_MODE_THREE_STAGE) + { + + if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK) + return status; + } + *buf_value_ecc = eeprom->Instance->EERB; + return status; +} \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c new file mode 100644 index 0000000..ea3e1ae --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c @@ -0,0 +1,260 @@ +#include "mik32_hal_gpio.h" + +/** Для обхода бага МК, чтение из регистра IRQ_LINE_MUX всегда возвращает 0 + * \note Используется в функциях HAL_GPIO_InitInterruptLine и HAL_GPIO_DeInitInterruptLine + */ +volatile uint32_t current_irq_line_mux = 0; + +/** + * @brief Инициализация модуля GPIO_x в соответствии с указанными параметрами в GPIO_Init. + * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). + * @param GPIO_Init указатель на структуру GPIO_InitTypeDef, которая содержит информацию о конфигурации для указанного модуля GPIO. + * @return статус HAL. + * @warning функция не включает тактирование выбранного модуля GPIO. Включить тактирование можно, например, с помощью макроса @ref __HAL_PCC_GPIO_2_CLK_ENABLE. + */ +HAL_StatusTypeDef HAL_GPIO_Init(GPIO_TypeDef *GPIO_x, GPIO_InitTypeDef *GPIO_Init) +{ + uint32_t *port_cfg = 0; + uint32_t *port_ds = 0; + uint32_t *port_pupd = 0; + + uint32_t position = 0; + uint32_t current_pin = 0; + + switch ((uint32_t)GPIO_x) + { + case (uint32_t)GPIO_0: + port_cfg = (uint32_t *)&(PAD_CONFIG->PORT_0_CFG); + port_ds = (uint32_t *)&(PAD_CONFIG->PORT_0_DS); + port_pupd = (uint32_t *)&(PAD_CONFIG->PORT_0_PUPD); + break; + case (uint32_t)GPIO_1: + port_cfg = (uint32_t *)&(PAD_CONFIG->PORT_1_CFG); + port_ds = (uint32_t *)&(PAD_CONFIG->PORT_1_DS); + port_pupd = (uint32_t *)&(PAD_CONFIG->PORT_1_PUPD); + break; + case (uint32_t)GPIO_2: + port_cfg = (uint32_t *)&(PAD_CONFIG->PORT_2_CFG); + port_ds = (uint32_t *)&(PAD_CONFIG->PORT_2_DS); + port_pupd = (uint32_t *)&(PAD_CONFIG->PORT_2_PUPD); + break; + + default: + return HAL_ERROR; + break; + } + // magic_foo(pinMask, port_cfg, port_pupd, port_ds) + while (((GPIO_Init->Pin) >> position) != 0) + { + current_pin = GPIO_Init->Pin & (1 << position); + + if (current_pin) + { + *port_cfg = (*port_cfg & (~PAD_CONFIG_PIN_M(position))) | PAD_CONFIG_PIN(position, GPIO_Init->Mode & 0b11); + + if ((GPIO_Init->Mode == HAL_GPIO_MODE_GPIO_INPUT) || (GPIO_Init->Mode == HAL_GPIO_MODE_GPIO_OUTPUT)) + { + if (GPIO_Init->Mode == HAL_GPIO_MODE_GPIO_INPUT) + { + GPIO_x->DIRECTION_IN = 1 << position; + } + else + { + GPIO_x->DIRECTION_OUT = 1 << position; + } + } + + *port_ds = (*port_ds & (~PAD_CONFIG_PIN_M(position))) | PAD_CONFIG_PIN(position, GPIO_Init->DS); + *port_pupd = (*port_pupd & (~PAD_CONFIG_PIN_M(position))) | PAD_CONFIG_PIN(position, GPIO_Init->Pull); + } + + position++; + } + + return HAL_OK; +} + +/** + * @brief Инициализация модуля GPIO_x. + * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). + * @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки. + * @param mode режим вывода. + * @param pull режим подтяжки вывода. + * @param driveStrength перечисление режимов нагрузочной способности. + * @return Статус HAL. + */ +HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, HAL_GPIO_ModeTypeDef mode, HAL_GPIO_PullTypeDef pull, HAL_GPIO_DSTypeDef driveStrength) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = pin; + GPIO_InitStruct.Mode = mode; + GPIO_InitStruct.Pull = pull; + GPIO_InitStruct.DS = driveStrength; + return HAL_GPIO_Init(GPIO_x, &GPIO_InitStruct); +} + +/** + * @brief Считать текущее состояние выводов порта GPIO_x. + * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). + * @param pin маска выводов порта GPIO_x, с которых считывание значение. + * @return @ref GPIO_PIN_HIGH если с одного или больше выводов, указанных в pin, считалась 1. Иначе @ref GPIO_PIN_LOW. + */ +GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin) +{ + GPIO_PinState bitStatus; + + if ((GPIO_x->SET & pin) != (uint32_t)GPIO_PIN_LOW) + { + bitStatus = GPIO_PIN_HIGH; + } + else + { + bitStatus = GPIO_PIN_LOW; + } + return bitStatus; +} + +/** + * @brief Задать логический уровень выходного сигнала для указанных выводов порта GPIO_x. + * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). + * @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки. + * @param pinState значение состояние вывода, в которое будут установлены указанные выводы. + * Этот параметр должен быть одним из значений: + * - @ref GPIO_PIN_LOW низкий выходной уровень + * - @ref GPIO_PIN_HIGH высокий выходной уровень + */ +void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState) +{ + if (pinState == GPIO_PIN_LOW) + { + GPIO_x->CLEAR = pin; + } + else + { + GPIO_x->SET = pin; + } +} + +/** + * @brief Переключить логический уровень выходного сигнала для указанных выводов порта GPIO_x. + * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). + * @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки. + */ +void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin) +{ + GPIO_x->OUTPUT_ ^= pin; +} + +/** + * @brief Функция инициализации линии прерывания. + * \param mux настройка мультиплексора линии прерывания. + * \param mode режим линии прерывания. + * @return Статус HAL. + * \note Номер линии прерывания можно получить после настройки мультиплексора. + * Введите в mux GPIO_MUX_GPIO_X_X, где X - номера порта и вывода, + * и нажмите Ctrl+Пробел: появятся варианты констант для данного вывода, + * далее достаточно выбрать константу для доступной линии. + * В mode введите GPIO_INT_MODE и нажмите Ctrl+Пробел: появятся варианты типов прерываний канала. + */ +HAL_StatusTypeDef HAL_GPIO_InitInterruptLine(HAL_GPIO_Line_Config mux, HAL_GPIO_InterruptMode mode) +{ + int irq_line_num = mux >> GPIO_IRQ_LINE_S; + mode &= 0b111; + if (irq_line_num > 7) + return HAL_ERROR; + + current_irq_line_mux &= ~GPIO_IRQ_LINE_MUX_M(irq_line_num); + current_irq_line_mux |= GPIO_IRQ_LINE_MUX(mux, irq_line_num); + GPIO_IRQ->LINE_MUX = current_irq_line_mux; + + if (mode & GPIO_MODE_BIT_LEVEL_M) // GPIO_INT_MODE_HIGH, GPIO_INT_MODE_RISING + { + GPIO_IRQ->LEVEL_SET = (1 << irq_line_num); // нарастающий фронт или логический уровень 1 + } + else + { + GPIO_IRQ->LEVEL_CLEAR = (1 << irq_line_num); // спадающий фронт или логический уровень 0 + } + + if (mode & GPIO_MODE_BIT_EDGE_M) // GPIO_INT_MODE_FALLING, GPIO_INT_MODE_RISING, GPIO_INT_MODE_CHANGE + { + GPIO_IRQ->EDGE = (1 << irq_line_num); // тип прерывания - событие (фронт/спад) + } + else + { + GPIO_IRQ->LEVEL = (1 << irq_line_num); // тип прерывания - логический уровень + } + + if (mode & GPIO_MODE_BIT_ANYEDGE_M) // GPIO_INT_MODE_CHANGE + { + GPIO_IRQ->ANY_EDGE_SET = (1 << irq_line_num); // разрешено прерывание по любому фронту + } + else + { + GPIO_IRQ->ANY_EDGE_CLEAR = (1 << irq_line_num); // запрещено прерывание по любому фронту + } + + GPIO_IRQ->ENABLE_SET = (1 << irq_line_num); + + return HAL_OK; +} + +/** + * @brief Функция деинициализации линии прерывания, запрещает прерывание и возвращает настройки по умолчанию для указанной лини. + * @param irqLine номер линии прерывания. + * @return Статус HAL. + */ +HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine) +{ + int irq_line_num = irqLine >> GPIO_IRQ_LINE_S; + + if (irq_line_num > 7) + return HAL_ERROR; + + GPIO_IRQ->ENABLE_CLEAR = (1 << irq_line_num); + + current_irq_line_mux &= ~GPIO_IRQ_LINE_MUX_M(irq_line_num); + GPIO_IRQ->LINE_MUX = current_irq_line_mux; + + GPIO_IRQ->LEVEL = (1 << irq_line_num); + GPIO_IRQ->LEVEL_CLEAR = (1 << irq_line_num); + GPIO_IRQ->ANY_EDGE_CLEAR = (1 << irq_line_num); + + return HAL_OK; +} + +/** + * @brief Получить состояние линии прерывания. + * @param irqLine номер линии прерывания. + * @return Возвращает 1 если сработало прерывание данной линии, иначе 0. + */ +uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine) +{ + int irq_line_num = irqLine >> GPIO_IRQ_LINE_S; + return (GPIO_IRQ->INTERRUPT & (1 << (irq_line_num))) != 0; +} + +/** + * @brief Функция чтения логического уровня вывода, подключенного к линии прерывания. + * @param irqLine номер линии прерывания. + * @return Логический уровень вывода. + */ +GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine) +{ + int irq_line_num = irqLine >> GPIO_IRQ_LINE_S; + return (GPIO_PinState)((GPIO_IRQ->STATE & (1 << (irq_line_num))) >> irq_line_num); +} + +/** + * @brief Функция сброса регистра состояния прерываний. + * @note Когда срабатывает прерывание на одной из линии, в регистре INTERRUPT + * выставляется 1 в разряде, соответствующем линии прерывания. + * После обработки прерывания необходимо сбросить данный регистр + * в обработчике прерывания trap_handler(). + * Если после обработки прерывания регистр не был сброшен, + * обработчик будет вызван снова, программа будет бесконечно вызывать обработчик. + */ +void HAL_GPIO_ClearInterrupts() +{ + GPIO_IRQ->CLEAR = 0b11111111; +} diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_i2c.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_i2c.c new file mode 100644 index 0000000..2a2cd16 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_i2c.c @@ -0,0 +1,1396 @@ +#include "mik32_hal_i2c.h" + +__attribute__((weak)) void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + if (hi2c->Instance == I2C_0) + { + __HAL_PCC_I2C_0_CLK_ENABLE(); + + GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + + if (hi2c->Instance == I2C_1) + { + __HAL_PCC_I2C_1_CLK_ENABLE(); + + GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + } + +} + +void HAL_I2C_Disable(I2C_HandleTypeDef *hi2c) +{ + hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; +} + +void HAL_I2C_Reset(I2C_HandleTypeDef *hi2c) +{ + hi2c->ErrorCode = I2C_ERROR_NONE; + + hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; + hi2c->Instance->CR1 |= I2C_CR1_PE_M; +} + +void HAL_I2C_Enable(I2C_HandleTypeDef *hi2c) +{ + hi2c->Instance->CR1 |= I2C_CR1_PE_M; +} + +void HAL_I2C_AnalogFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_AnalogFilterTypeDef AnalogFilter) +{ + hi2c->Init.AnalogFilter = AnalogFilter; + hi2c->Instance->CR1 &= ~I2C_CR1_ANFOFF_M; + hi2c->Instance->CR1 |= AnalogFilter << I2C_CR1_ANFOFF_S; +} + +void HAL_I2C_DigitalFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_DigitalFilterTypeDef DigitalFilter) +{ + /* DNF можно менять только при PE = 0 */ + hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; + + hi2c->Init.DigitalFilter = DigitalFilter; + hi2c->Instance->CR1 &= ~I2C_CR1_DNF_M; + hi2c->Instance->CR1 |= I2C_CR1_DNF(DigitalFilter); +} + +void HAL_I2C_SetClockSpeed(I2C_HandleTypeDef *hi2c) +{ + /* TIMING можно менять только при PE = 0 */ + hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; + + /* + * Инициализация i2c + * TIMING - регистр таймингов + * + * SCLDEL(0-15) - Задержка между изменением SDA и фронтом SCL в режиме ведущего и ведомого при NOSTRETCH = 0 + * + * SDADEL(0-15) - Задержка между спадом SCL и изменением SDA в режиме ведущего и ведомого при NOSTRETCH = 0 + * + * SCLL(0-255) - Время удержания SCL в состоянии логического «0» в режиме ведущего + * + * SCLH(0-255) - Время удержания SCL в состоянии логической «1» в режиме ведущего + * + * PRESC(0-15) - Делитель частоты I2CCLK. Используется для вычисления периода сигнала TPRESC для счетчиков предустановки, + * удержания, уровня «0» и «1» + * + */ + hi2c->Instance->TIMINGR = I2C_TIMINGR_SCLDEL(hi2c->Clock.SCLDEL) | I2C_TIMINGR_SDADEL(hi2c->Clock.SDADEL) | + I2C_TIMINGR_SCLL(hi2c->Clock.SCLL) | I2C_TIMINGR_SCLH(hi2c->Clock.SCLH) | I2C_TIMINGR_PRESC(hi2c->Clock.PRESC); +} + +void HAL_I2C_NoStretchMode(I2C_HandleTypeDef *hi2c, HAL_I2C_NoStretchModeTypeDef NoStretchMode) +{ + /* NOSTRETCH можно менять только при PE = 0 */ + hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; + + hi2c->Init.NoStretchMode = NoStretchMode; + hi2c->Instance->CR1 &= ~I2C_CR1_NOSTRETCH_M; + hi2c->Instance->CR1 |= NoStretchMode << I2C_CR1_NOSTRETCH_S; +} + +void HAL_I2C_OwnAddress1(I2C_HandleTypeDef *hi2c) +{ + /* OA1, OA1MODE можно менять при OA1EN = 0 */ + hi2c->Instance->OAR1 = 0; + + /* Запись собственного адреса 1 */ + if (hi2c->Init.OwnAddress1 <= I2C_ADDRESS_7BIT_MAX) /* Настройка 7 битного адреса */ + { + hi2c->Instance->OAR1 &= ~I2C_OAR1_OA1MODE_M; /* 7 битный режим */ + hi2c->Instance->OAR1 |= ((hi2c->Init.OwnAddress1 & 0x7F) << 1) << I2C_OAR1_OA1_S; + } + else /* Настройка 10 битного адреса */ + { + hi2c->Instance->OAR1 |= I2C_OAR1_OA1MODE_M; /* 10 битный режим */ + hi2c->Instance->OAR1 |= (hi2c->Init.OwnAddress1 & 0x3FF) << I2C_OAR1_OA1_S; + } + + /* Запись собственного адреса 1 */ + if (hi2c->Init.OwnAddress1 <= I2C_ADDRESS_7BIT_MAX) /* 7 битный адрес */ + { + hi2c->Instance->OAR1 |= ((hi2c->Init.OwnAddress1 & 0x7F) << 1) << I2C_OAR1_OA1_S; + } + else /* 10 битный адрес */ + { + hi2c->Instance->OAR1 |= (hi2c->Init.OwnAddress1 & 0x3FF) << I2C_OAR1_OA1_S; + } + + + + + // switch (hi2c->Init.AddressingMode) + // { + // case I2C_ADDRESSINGMODE_7BIT: + // hi2c->Instance->OAR1 |= ((hi2c->Init.OwnAddress1 & 0x7F) << 1) << I2C_OAR1_OA1_S; + // break; + // case I2C_ADDRESSINGMODE_10BIT: + // hi2c->Instance->OAR1 |= (hi2c->Init.OwnAddress1 & 0x3FF) << I2C_OAR1_OA1_S; + // break; + + // default: + // break; + // } + + hi2c->Instance->OAR1 |= I2C_OAR1_OA1EN_M; + +} + +void HAL_I2C_OwnAddress2(I2C_HandleTypeDef *hi2c) +{ + /* OA2, OA2MODE, OA2MSK можно менять при OA2EN = 0 */ + hi2c->Instance->OAR2 = 0; + + hi2c->Instance->OAR2 |= hi2c->Init.OwnAddress2Mask << I2C_OAR2_OA2MSK_S; + + /* Запись собственного адреса 2 */ + hi2c->Instance->OAR2 |= (hi2c->Init.OwnAddress2 & 0x7F) << I2C_OAR2_OA2_S; + + /* Включить дополнительный собственный адрес 2 */ + if (hi2c->Init.DualAddressMode == I2C_DUALADDRESS_ENABLE) + { + hi2c->Instance->OAR2 |= I2C_OAR2_OA2EN_M; + } + +} + +void HAL_I2C_GeneralCall(I2C_HandleTypeDef *hi2c, HAL_I2C_GeneralCallTypeDef GeneralCall) +{ + hi2c->Init.GeneralCall = GeneralCall; + hi2c->Instance->CR1 &= ~I2C_CR1_GCEN_M; + hi2c->Instance->CR1 |= GeneralCall << I2C_CR1_GCEN_S; +} + +void HAL_I2C_SBCMode(I2C_HandleTypeDef *hi2c, HAL_I2C_SBCModeTypeDef SBCMode) +{ + hi2c->Init.SBCMode = SBCMode; + hi2c->Instance->CR1 &= ~I2C_CR1_SBC_M; + hi2c->Instance->CR1 |= SBCMode << I2C_CR1_SBC_S; +} + +void HAL_I2C_SlaveInit(I2C_HandleTypeDef *hi2c) +{ + /* Основной и дополнительный собственный адрес */ + HAL_I2C_OwnAddress1(hi2c); + HAL_I2C_OwnAddress2(hi2c); + + /* GCEN - general call */ + HAL_I2C_GeneralCall(hi2c, hi2c->Init.GeneralCall); + + /* Configure SBC in I2C_CR1* */ + HAL_I2C_SBCMode(hi2c, hi2c->Init.SBCMode); + + /* Enable interrupts and/or DMA in I2C_CR1 */ +} + +void HAL_I2C_MasterInit(I2C_HandleTypeDef *hi2c) +{ + /* Enable interrupts and/or DMA in I2C_CR1 */ + +} + +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) +{ + HAL_I2C_MspInit(hi2c); + + /* Clear PE in I2C_CR1 */ + HAL_I2C_Disable(hi2c); + + /* Configure ANFOFF and DNF[3:0] in I2C_CR1 */ + HAL_I2C_AnalogFilterInit(hi2c, hi2c->Init.AnalogFilter); + HAL_I2C_DigitalFilterInit(hi2c, hi2c->Init.DigitalFilter); + + /* Configure PRESC[3:0], SDADEL[3:0], SCLDEL[3:0], SCLH[7:0],SCLL[7:0] in l2C_TIMINGR */ + HAL_I2C_SetClockSpeed(hi2c); + + if (hi2c->Init.Mode == HAL_I2C_MODE_MASTER) + { + /* Configure NOSTRETCH in I2C_CR1 */ + HAL_I2C_NoStretchMode(hi2c, I2C_NOSTRETCH_DISABLE); + } + else + { + /* Configure NOSTRETCH in I2C_CR1 */ + HAL_I2C_NoStretchMode(hi2c, hi2c->Init.NoStretchMode); + } + + + /* Set PE in I2C_CR1 */ + HAL_I2C_Enable(hi2c); + + switch (hi2c->Init.Mode) + { + case HAL_I2C_MODE_SLAVE: + HAL_I2C_SlaveInit(hi2c); + break; + + case HAL_I2C_MODE_MASTER: + HAL_I2C_MasterInit(hi2c); + break; + + default: + return HAL_ERROR; + break; + } + + hi2c->State = HAL_I2C_STATE_READY; + return HAL_OK; +} + +void HAL_I2C_AutoEnd(I2C_HandleTypeDef *hi2c, HAL_I2C_AutoEndModeTypeDef AutoEnd) +{ + hi2c->Instance->CR2 &= ~I2C_CR2_AUTOEND_M; + hi2c->Instance->CR2 |= AutoEnd << I2C_CR2_AUTOEND_S; +} + +HAL_StatusTypeDef HAL_I2C_Master_WaitTC(I2C_HandleTypeDef *hi2c, uint32_t Timeout) +{ + /* Ожидание совпадения адреса */ + while (Timeout--) + { + if (hi2c->Instance->ISR & I2C_ISR_TC_M) + { + return HAL_OK; + } + } + + hi2c->ErrorCode = I2C_ERROR_TIMEOUT; + return HAL_TIMEOUT; +} + +HAL_StatusTypeDef HAL_I2C_Master_WaitTCR(I2C_HandleTypeDef *hi2c, uint32_t Timeout) +{ + /* Ожидание совпадения адреса */ + while (Timeout--) + { + if (hi2c->Instance->ISR & I2C_ISR_TCR_M) + { + return HAL_OK; + } + } + + hi2c->ErrorCode = I2C_ERROR_TIMEOUT; + return HAL_TIMEOUT; +} + +HAL_StatusTypeDef HAL_I2C_Master_WaitTXIS(I2C_HandleTypeDef *hi2c, uint32_t Timeout) +{ + uint32_t status_isr = 0; + + /* Ожидание совпадения адреса */ + while (Timeout--) + { + status_isr = hi2c->Instance->ISR; + + if (status_isr & I2C_ISR_NACKF_M) + { + hi2c->ErrorCode = I2C_ERROR_NACK; + return HAL_ERROR; + } + + if (status_isr & (I2C_ISR_BERR_M | I2C_ISR_ARLO_M)) + { + if (status_isr & I2C_ISR_BERR_M) + { + hi2c->ErrorCode = I2C_ERROR_BERR; + return HAL_ERROR; + } + + if (status_isr & I2C_ISR_ARLO_M) + { + hi2c->ErrorCode = I2C_ERROR_ARLO; + return HAL_ERROR; + } + } + + + if (status_isr & I2C_ISR_TXIS_M) + { + return HAL_OK; + } + } + + hi2c->ErrorCode = I2C_ERROR_TIMEOUT; + return HAL_TIMEOUT; +} + +HAL_StatusTypeDef HAL_I2C_Master_WaitRXNE(I2C_HandleTypeDef *hi2c, uint32_t Timeout) +{ + uint32_t status_isr = 0; + /* Ожидание совпадения адреса */ + while (Timeout--) + { + status_isr = hi2c->Instance->ISR; + + if (status_isr & (I2C_ISR_BERR_M | I2C_ISR_ARLO_M)) + { + if (status_isr & I2C_ISR_BERR_M) + { + hi2c->ErrorCode = I2C_ERROR_BERR; + return HAL_ERROR; + } + + if (status_isr & I2C_ISR_ARLO_M) + { + hi2c->ErrorCode = I2C_ERROR_ARLO; + return HAL_ERROR; + } + } + + if (status_isr & I2C_ISR_RXNE_M) + { + return HAL_OK; + } + } + + hi2c->ErrorCode = I2C_ERROR_TIMEOUT; + return HAL_TIMEOUT; +} + +void HAL_I2C_Master_SlaveAddress(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress) +{ + hi2c->Instance->CR2 &= ~I2C_CR2_SADD_M; + + if (SlaveAddress <= I2C_ADDRESS_7BIT_MAX) /* 7 битный адрес */ + { + hi2c->Instance->CR2 &= ~I2C_CR2_ADD10_M; + hi2c->Instance->CR2 |= ((SlaveAddress & 0x7F) << 1) << I2C_CR2_SADD_S; + } + else /* 10 битный адрес */ + { + hi2c->Instance->CR2 |= I2C_CR2_ADD10_M; + hi2c->Instance->CR2 &= ~I2C_CR2_HEAD10R_M; /* ведущий отправляет полную последовательность для чтения для 10 битного адреса */ + hi2c->Instance->CR2 |= (SlaveAddress & 0x3FF) << I2C_CR2_SADD_S; + } + +} + +HAL_StatusTypeDef HAL_I2C_WaitBusy(I2C_HandleTypeDef *hi2c, uint32_t Timeout) +{ + /* Ожидание совпадения адреса */ + while (hi2c->Instance->ISR & I2C_ISR_BUSY_M) + { + if (Timeout-- == 0) + { + hi2c->ErrorCode = I2C_ERROR_TIMEOUT; + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +void HAL_I2C_Master_NBYTES(I2C_HandleTypeDef *hi2c) +{ + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + /* Подготовка перед отправкой */ + + if ((hi2c->TransferSize - hi2c->TransferCount) <= I2C_NBYTE_MAX) + { + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(hi2c->TransferSize - hi2c->TransferCount); + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + HAL_I2C_AutoEnd(hi2c, hi2c->Init.AutoEnd); + } + else /* DataSize > 255 */ + { + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(I2C_NBYTE_MAX); + /* При RELOAD = 1 AUTOEND игнорируется */ + hi2c->Instance->CR2 |= I2C_CR2_RELOAD_M; + } +} + +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize, uint32_t Timeout) +{ + HAL_StatusTypeDef error_code = HAL_OK; + uint32_t nbytes = 0; + + /* Подготовка перед отправкой */ + if (DataSize <= I2C_NBYTE_MAX) + { + nbytes = DataSize; + DataSize = 0; + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(nbytes); + + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + HAL_I2C_AutoEnd(hi2c, hi2c->Init.AutoEnd); + } + else /* DataSize > 255 */ + { + nbytes = I2C_NBYTE_MAX; + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(nbytes); + + DataSize-=I2C_NBYTE_MAX; + + /* При RELOAD = 1 AUTOEND игнорируется */ + + hi2c->Instance->CR2 |= I2C_CR2_RELOAD_M; + } + /* Задать адрес и режим адресации */ + HAL_I2C_Master_SlaveAddress(hi2c, SlaveAddress); + /* Задать направление передачи - запись */ + hi2c->Instance->CR2 &= ~I2C_CR2_RD_WRN_M; + /* Старт */ + hi2c->Instance->CR2 |= I2C_CR2_START_M; + + while (1) + { + + for (uint32_t i = 0; i < nbytes; i++) + { + if ((error_code = HAL_I2C_Master_WaitTXIS(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + hi2c->Instance->TXDR = *pData; + pData++; + } + + if (DataSize == 0) + { + /* Все данные отправлены */ + if (hi2c->Instance->CR2 & I2C_CR2_AUTOEND_M) + { + /* BUSY */ + error_code = HAL_I2C_WaitBusy(hi2c, Timeout); /* Ожидание сигнала STOP */ + } + else + { + /* TC */ + error_code = HAL_I2C_Master_WaitTC(hi2c, Timeout); /* Ожидание сигнала конца передачи. STOP не отправляется */ + } + + break; + } + + if ((error_code = HAL_I2C_Master_WaitTCR(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + + if (DataSize <= I2C_NBYTE_MAX) + { + nbytes = DataSize; + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(nbytes); + DataSize = 0; + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + HAL_I2C_AutoEnd(hi2c, hi2c->Init.AutoEnd); + } + else + { + nbytes = I2C_NBYTE_MAX; + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(nbytes); + DataSize -= I2C_NBYTE_MAX; + hi2c->Instance->CR2 |= I2C_CR2_RELOAD_M; + } + + + } + + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize, uint32_t Timeout) +{ + HAL_StatusTypeDef error_code = HAL_OK; + uint32_t nbytes = 0; + + /* Подготовка перед отправкой */ + if (DataSize <= I2C_NBYTE_MAX) + { + nbytes = DataSize; + DataSize = 0; + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(nbytes); + + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + HAL_I2C_AutoEnd(hi2c, hi2c->Init.AutoEnd); + } + else /* DataSize > 255 */ + { + nbytes = I2C_NBYTE_MAX; + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(nbytes); + + DataSize-=I2C_NBYTE_MAX; + + /* При RELOAD = 1 AUTOEND игнорируется */ + + hi2c->Instance->CR2 |= I2C_CR2_RELOAD_M; + } + /* Задать адрес и режим адресации */ + HAL_I2C_Master_SlaveAddress(hi2c, SlaveAddress); + /* Задать направление передачи - чтение */ + hi2c->Instance->CR2 |= I2C_CR2_RD_WRN_M; + /* Старт */ + hi2c->Instance->CR2 |= I2C_CR2_START_M; + + + while(1) + { + for (uint32_t i = 0; i < nbytes; i++) + { + if ((error_code = HAL_I2C_Master_WaitRXNE(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + + *pData = hi2c->Instance->RXDR; + pData++; + } + + if (DataSize == 0) + { + /* Все данные прочитаны */ + if (hi2c->Instance->CR2 & I2C_CR2_AUTOEND_M) + { + /* BUSY */ + error_code = HAL_I2C_WaitBusy(hi2c, Timeout); /* Ожидание сигнала STOP */ + } + else + { + /* TC */ + error_code = HAL_I2C_Master_WaitTC(hi2c, Timeout); /* Ожидание сигнала конца передачи. STOP не отправляется */ + } + + break; + } + + if ((error_code = HAL_I2C_Master_WaitTCR(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + + if (hi2c->Instance->ISR & I2C_ISR_TCR_M) + { + if (DataSize <= I2C_NBYTE_MAX) + { + nbytes = DataSize; + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(nbytes); + DataSize = 0; + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + HAL_I2C_AutoEnd(hi2c, hi2c->Init.AutoEnd); + } + else + { + nbytes = I2C_NBYTE_MAX; + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(nbytes); + DataSize -= I2C_NBYTE_MAX; + hi2c->Instance->CR2 |= I2C_CR2_RELOAD_M; + } + } + + + } + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Slave_WaitADDR(I2C_HandleTypeDef *hi2c, uint32_t Timeout) +{ + /* Ожидание совпадения адреса */ + while (!(hi2c->Instance->ISR & I2C_ISR_ADDR_M)) + { + if (Timeout-- == 0) + { + hi2c->ErrorCode = I2C_ERROR_TIMEOUT; + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_I2C_Slave_WaitTXIS(I2C_HandleTypeDef *hi2c, uint32_t Timeout) +{ + uint32_t status_isr = 0; + /* Ожидание флага TXIS */ + + if (hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M) + { + while (Timeout--) + { + status_isr = hi2c->Instance->ISR; + + if (status_isr & (I2C_ISR_BERR_M | I2C_ISR_ARLO_M | I2C_ISR_OVR_M)) + { + if (status_isr & I2C_ISR_BERR_M) + { + hi2c->ErrorCode = I2C_ERROR_BERR; + return HAL_ERROR; + } + + if (status_isr & I2C_ISR_ARLO_M) + { + hi2c->ErrorCode = I2C_ERROR_ARLO; + return HAL_ERROR; + } + + if (status_isr & I2C_ISR_OVR_M) + { + hi2c->ErrorCode = I2C_ERROR_OVR; + return HAL_ERROR; + } + } + + if (status_isr & I2C_ISR_NACKF_M) + { + hi2c->ErrorCode = I2C_ERROR_NACK; + return HAL_ERROR; + } + + if (status_isr & I2C_ISR_STOPF_M) + { + hi2c->ErrorCode = I2C_ERROR_STOP; + return HAL_ERROR; + } + + if (status_isr & I2C_ISR_TXIS_M) + { + return HAL_OK; + } + } + } + else + { + while (Timeout--) + { + status_isr = hi2c->Instance->ISR; + + if (status_isr & (I2C_ISR_BERR_M | I2C_ISR_ARLO_M)) + { + if (status_isr & I2C_ISR_BERR_M) + { + hi2c->ErrorCode = I2C_ERROR_BERR; + return HAL_ERROR; + } + + if (status_isr & I2C_ISR_ARLO_M) + { + hi2c->ErrorCode = I2C_ERROR_ARLO; + return HAL_ERROR; + } + } + + if (hi2c->Instance->ISR & I2C_ISR_TXIS_M) + { + return HAL_OK; + } + } + } + + hi2c->ErrorCode = I2C_ERROR_TIMEOUT; + return HAL_TIMEOUT; +} + +HAL_StatusTypeDef HAL_I2C_Slave_WaitRXNE(I2C_HandleTypeDef *hi2c, uint32_t Timeout) +{ + uint32_t status_isr = 0; + /* Ожидание RXNE */ + if (hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M) + { + while (Timeout--) + { + status_isr = hi2c->Instance->ISR; + + if (status_isr & (I2C_ISR_BERR_M | I2C_ISR_ARLO_M | I2C_ISR_OVR_M)) + { + if (status_isr & I2C_ISR_BERR_M) + { + hi2c->ErrorCode = I2C_ERROR_BERR; + return HAL_ERROR; + } + + if (status_isr & I2C_ISR_ARLO_M) + { + hi2c->ErrorCode = I2C_ERROR_ARLO; + return HAL_ERROR; + } + + if (status_isr & I2C_ISR_OVR_M) + { + hi2c->ErrorCode = I2C_ERROR_OVR; + return HAL_ERROR; + } + } + + if (status_isr & I2C_ISR_STOPF_M) + { + hi2c->ErrorCode = I2C_ERROR_STOP; + return HAL_ERROR; + } + + + if (status_isr & I2C_ISR_RXNE_M) + { + return HAL_OK; + } + + } + + } + else + { + while (Timeout--) + { + status_isr = hi2c->Instance->ISR; + + if (status_isr & (I2C_ISR_BERR_M | I2C_ISR_ARLO_M)) + { + if (status_isr & I2C_ISR_BERR_M) + { + hi2c->ErrorCode = I2C_ERROR_BERR; + return HAL_ERROR; + } + + if (status_isr & I2C_ISR_ARLO_M) + { + hi2c->ErrorCode = I2C_ERROR_ARLO; + return HAL_ERROR; + } + } + + if (status_isr & I2C_ISR_RXNE_M) + { + return HAL_OK; + } + + } + } + + + + hi2c->ErrorCode = I2C_ERROR_TIMEOUT; + return HAL_TIMEOUT; +} + +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout) +{ + HAL_StatusTypeDef error_code = HAL_OK; + + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + + if (!(hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M)) /* NOSTRETCH = 0 */ + { + /* Ожидание вызова адреса */ + if ((error_code = HAL_I2C_Slave_WaitADDR(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + /* Сброс флага ADDR */ + hi2c->Instance->ICR |= I2C_ICR_ADDRCF_M; + + if(hi2c->Instance->OAR1 & I2C_OAR1_OA1MODE_M) + { + /* Ожидание вызова адреса */ + if ((error_code = HAL_I2C_Slave_WaitADDR(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + } + + /* Сброс содержимого TXDR */ + hi2c->Instance->ISR |= I2C_ISR_TXE_M; + + /* Сброс флага ADDR */ + hi2c->Instance->ICR |= I2C_ICR_ADDRCF_M; + + } + + /* Первая запись делается заранее */ + hi2c->Instance->TXDR = pData[0]; + /* Запись байта */ + for (uint32_t tx_count = 1; tx_count < DataSize; tx_count++) + { + if ((error_code = HAL_I2C_Slave_WaitTXIS(hi2c, Timeout)) != HAL_OK) + { + /* Сброс содержимого TXDR */ + hi2c->Instance->ISR |= I2C_ISR_TXE_M; + // hi2c->Instance->ICR |= I2C_ICR_TXIS_M; + + /* Сброс флага детектирования STOP на шине */ + hi2c->Instance->ICR |= I2C_ICR_STOPCF_M; + return error_code; + } + + hi2c->Instance->TXDR = pData[tx_count]; + } + + if ((error_code = HAL_I2C_WaitBusy(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + + + /* Сброс содержимого TXDR */ + hi2c->Instance->ISR |= I2C_ISR_TXE_M; + // hi2c->Instance->ICR |= I2C_ICR_TXIS_M; + + /* Сброс флага детектирования STOP на шине */ + hi2c->Instance->ICR |= I2C_ICR_STOPCF_M; + + + return error_code; + +} + +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout) +{ + HAL_StatusTypeDef error_code = HAL_OK; + + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + + if (!(hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M)) /* NOSTRETCH = 0 - с растягиванием SCL*/ + { + /* Ожидание вызова адреса */ + if ((error_code = HAL_I2C_Slave_WaitADDR(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + + /* Сброс флага ADDR */ + hi2c->Instance->ICR |= I2C_ICR_ADDRCF_M; + } + else if (hi2c->Instance->CR1 & I2C_CR1_SBC_M) /* Режим SBC несовместим с режимом NOSTRETCH */ + { + return HAL_ERROR; + } + + + /* Чтение байта */ + for (uint32_t rx_count = 0; rx_count < DataSize; rx_count++) + { + if ((error_code = HAL_I2C_Slave_WaitRXNE(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + pData[rx_count] = hi2c->Instance->RXDR; + } + + if ((error_code = HAL_I2C_WaitBusy(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + + /* Сброс флага детектирования STOP на шине */ + hi2c->Instance->ICR |= I2C_ICR_STOPCF_M; + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Slave_WaitTCR(I2C_HandleTypeDef *hi2c, uint32_t Timeout) +{ + /* Ожидание совпадения адреса */ + while (Timeout--) + { + if (hi2c->Instance->ISR & I2C_ISR_TCR_M) + { + return HAL_OK; + } + } + + return HAL_TIMEOUT; +} + +void HAL_I2C_Slave_ACK(I2C_HandleTypeDef *hi2c) +{ + /* Формирование ACK */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK_M; +} + +void HAL_I2C_Slave_NACK(I2C_HandleTypeDef *hi2c) +{ + /* Формирование NACK */ + hi2c->Instance->CR2 |= I2C_CR2_NACK_M; +} + +__attribute__ ((weak)) HAL_StatusTypeDef HAL_I2C_Slave_SBC(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t ByteCount) +{ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK_M; /* Формирование ACK */ + return HAL_OK; +} + +HAL_StatusTypeDef HAL_I2C_Slave_ReceiveSBC(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout) +{ + HAL_StatusTypeDef error_code = HAL_OK; + + if (!(hi2c->Instance->CR1 & I2C_CR1_SBC_M)) + { + return HAL_ERROR; + } + else if (hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M) + { + /* Режим SBC несовместим с режимом NOSTRETCH */ + return HAL_ERROR; + } + + + /* Ожидание вызова адреса */ + if ((error_code = HAL_I2C_Slave_WaitADDR(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + hi2c->Instance->CR2 |= I2C_CR2_RELOAD_M; + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(0x1); + /* Сброс флага ADDR */ + hi2c->Instance->ICR |= I2C_ICR_ADDRCF_M; + + /* Чтение байта */ + for (uint32_t rx_count = 0; rx_count < DataSize; rx_count++) + { + /* Ожидание приема байта */ + if ((error_code = HAL_I2C_Slave_WaitTCR(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + + pData[rx_count] = hi2c->Instance->RXDR; + + if ((error_code = HAL_I2C_Slave_SBC(hi2c, pData, DataSize, rx_count)) != HAL_OK) + { + return error_code; + } + + if (rx_count <= DataSize-1) + { + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(0x1); + } + } + + + if ((error_code = HAL_I2C_WaitBusy(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + + /* Сброс флага детектирования STOP на шине */ + hi2c->Instance->ICR |= I2C_ICR_STOPCF_M; + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize) +{ + HAL_StatusTypeDef error_code = HAL_OK; + + /* Подготовка перед отправкой */ + if (DataSize <= I2C_NBYTE_MAX) + { + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(DataSize); + + HAL_I2C_AutoEnd(hi2c, hi2c->Init.AutoEnd); + } + else /* DataSize > 255 */ + { + return HAL_ERROR; + } + /* Задать адрес и режим адресации */ + HAL_I2C_Master_SlaveAddress(hi2c, SlaveAddress); + /* Задать направление передачи - запись */ + hi2c->Instance->CR2 &= ~I2C_CR2_RD_WRN_M; + + /* Разрешение поддержки DMA при передаче */ + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN_M; + + /* Настройка и включение канала DMA */ + HAL_DMA_Start(hi2c->hdmatx, pData, (void*)&hi2c->Instance->TXDR, DataSize - 1); + + /* Старт */ + hi2c->Instance->CR2 |= I2C_CR2_START_M; + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize) +{ + HAL_StatusTypeDef error_code = HAL_OK; + + /* Подготовка перед приемом */ + if (DataSize <= I2C_NBYTE_MAX) + { + hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M; + hi2c->Instance->CR2 |= I2C_CR2_NBYTES(DataSize); + + HAL_I2C_AutoEnd(hi2c, hi2c->Init.AutoEnd); + } + else /* DataSize > 255 */ + { + return HAL_ERROR; + } + /* Задать адрес и режим адресации */ + HAL_I2C_Master_SlaveAddress(hi2c, SlaveAddress); + /* Задать направление передачи - чтение */ + hi2c->Instance->CR2 |= I2C_CR2_RD_WRN_M; + + /* Разрешение поддержки DMA при передаче */ + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN_M; + + /* Настройка и включение канала DMA */ + HAL_DMA_Start(hi2c->hdmarx, (void*)&hi2c->Instance->RXDR, pData, DataSize - 1); + + /* Старт */ + hi2c->Instance->CR2 |= I2C_CR2_START_M; + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout) +{ + HAL_StatusTypeDef error_code = HAL_OK; + + // /* Первая запись делается заранее */ + // hi2c->Instance->TXDR = pData[0]; + + /* Разрешение поддержки DMA при передаче */ + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN_M; + + /* Настройка и включение канала DMA */ + HAL_DMA_Start(hi2c->hdmatx, pData, (void*)&hi2c->Instance->TXDR, DataSize - 1); + + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + + if (!(hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M)) /* NOSTRETCH = 0 */ + { + /* Ожидание вызова адреса */ + if ((error_code = HAL_I2C_Slave_WaitADDR(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + /* Сброс флага ADDR */ + hi2c->Instance->ICR |= I2C_ICR_ADDRCF_M; + + if(hi2c->Instance->OAR1 & I2C_OAR1_OA1MODE_M) + { + /* Ожидание вызова адреса */ + if ((error_code = HAL_I2C_Slave_WaitADDR(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + } + + /* Сброс содержимого TXDR */ + hi2c->Instance->ISR |= I2C_ISR_TXE_M; + + /* Сброс флага ADDR */ + hi2c->Instance->ICR |= I2C_ICR_ADDRCF_M; + + } + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout) +{ + HAL_StatusTypeDef error_code = HAL_OK; + + /* Разрешение поддержки DMA при передаче */ + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN_M; + + /* Настройка и включение канала DMA */ + HAL_DMA_Start(hi2c->hdmarx, (void*)&hi2c->Instance->RXDR, pData, DataSize - 1); + + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + + if (!(hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M)) /* NOSTRETCH = 0 - с растягиванием SCL*/ + { + /* Ожидание вызова адреса */ + if ((error_code = HAL_I2C_Slave_WaitADDR(hi2c, Timeout)) != HAL_OK) + { + return error_code; + } + + /* Сброс флага ADDR */ + hi2c->Instance->ICR |= I2C_ICR_ADDRCF_M; + } + else if (hi2c->Instance->CR1 & I2C_CR1_SBC_M) /* Режим SBC несовместим с режимом NOSTRETCH */ + { + return HAL_ERROR; + } + + + return error_code; +} + + +void HAL_I2C_InterruptDisable(I2C_HandleTypeDef *hi2c, uint32_t IntDisMask) +{ + IntDisMask &= I2C_INTMASK; + hi2c->Instance->CR1 &= ~IntDisMask; +} + +void HAL_I2C_InterruptEnable(I2C_HandleTypeDef *hi2c, uint32_t IntEnMask) +{ + IntEnMask &= I2C_INTMASK; + hi2c->Instance->CR1 |= IntEnMask; +} + +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize) +{ + HAL_StatusTypeDef error_code = HAL_OK; + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->pBuffPtr = pData; + hi2c->TransferSize = DataSize; + hi2c->TransferCount = 0; + + HAL_I2C_Master_NBYTES(hi2c); + + /* Задать адрес и режим адресации */ + HAL_I2C_Master_SlaveAddress(hi2c, SlaveAddress); + /* Задать направление передачи - запись */ + hi2c->Instance->CR2 &= ~I2C_CR2_RD_WRN_M; + + /* Выключить все прерывания I2C */ + HAL_I2C_InterruptDisable(hi2c, I2C_INTMASK); + /* Включение прерываний */ + HAL_I2C_InterruptEnable(hi2c, I2C_CR1_ERRIE_M + | I2C_CR1_TCIE_M + | I2C_CR1_NACKIE_M + | I2C_CR1_TXIE_M + ); + + /* Старт */ + hi2c->Instance->CR2 |= I2C_CR2_START_M; + + return error_code; + +} + +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize) +{ + HAL_StatusTypeDef error_code = HAL_OK; + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->pBuffPtr = pData; + hi2c->TransferSize = DataSize; + hi2c->TransferCount = 0; + + HAL_I2C_Master_NBYTES(hi2c); + + /* Задать адрес и режим адресации */ + HAL_I2C_Master_SlaveAddress(hi2c, SlaveAddress); + /* Задать направление передачи - чтение */ + hi2c->Instance->CR2 |= I2C_CR2_RD_WRN_M; + HAL_I2C_InterruptDisable(hi2c, I2C_INTMASK); + HAL_I2C_InterruptEnable(hi2c, I2C_CR1_ERRIE_M + | I2C_CR1_TCIE_M + | I2C_CR1_ADDRIE_M + | I2C_CR1_RXIE_M + ); + /* Старт */ + hi2c->Instance->CR2 |= I2C_CR2_START_M; + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize) +{ + HAL_StatusTypeDef error_code = HAL_OK; + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->pBuffPtr = pData; + hi2c->TransferSize = DataSize; + hi2c->TransferCount = 0; + + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + + if ((hi2c->Instance->CR1 & I2C_CR1_SBC_M) && (hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M)) /* Режим SBC несовместим с режимом NOSTRETCH */ + { + return HAL_ERROR; + } + + // /* Сброс содержимого TXDR */ + // hi2c->Instance->ISR |= I2C_ISR_TXE_M; + + /* Первая запись делается заранее */ + hi2c->Instance->TXDR = pData[hi2c->TransferCount++]; + hi2c->pBuffPtr++; + + HAL_I2C_InterruptDisable(hi2c, I2C_INTMASK); + HAL_I2C_InterruptEnable(hi2c, I2C_CR1_ERRIE_M + | I2C_CR1_STOPIE_M + | I2C_CR1_ADDRIE_M + | I2C_CR1_TXIE_M + ); + + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_NOSTRETCH_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize) +{ + HAL_StatusTypeDef error_code = HAL_OK; + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->pBuffPtr = pData; + hi2c->TransferSize = DataSize; + hi2c->TransferCount = 0; + + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + + if ((hi2c->Instance->CR1 & I2C_CR1_SBC_M) && (hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M)) /* Режим SBC несовместим с режимом NOSTRETCH */ + { + return HAL_ERROR; + } + + // /* Сброс содержимого TXDR */ + // hi2c->Instance->ISR |= I2C_ISR_TXE_M; + + /* Первая запись делается заранее */ + hi2c->Instance->TXDR = pData[hi2c->TransferCount++]; + hi2c->pBuffPtr++; + + HAL_I2C_InterruptDisable(hi2c, I2C_INTMASK); + HAL_I2C_InterruptEnable(hi2c, I2C_CR1_ERRIE_M + | I2C_CR1_STOPIE_M + | I2C_CR1_TXIE_M + ); + + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize) +{ + HAL_StatusTypeDef error_code = HAL_OK; + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->pBuffPtr = pData; + hi2c->TransferSize = DataSize; + hi2c->TransferCount = 0; + + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + + if ((hi2c->Instance->CR1 & I2C_CR1_SBC_M) && (hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M)) /* Режим SBC несовместим с режимом NOSTRETCH */ + { + return HAL_ERROR; + } + + + HAL_I2C_InterruptDisable(hi2c, I2C_INTMASK); + HAL_I2C_InterruptEnable(hi2c, I2C_CR1_ERRIE_M + | I2C_CR1_STOPIE_M + | I2C_CR1_ADDRIE_M + | I2C_CR1_RXIE_M + ); + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Slave_Receive_NOSTRETCH_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize) +{ + HAL_StatusTypeDef error_code = HAL_OK; + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->pBuffPtr = pData; + hi2c->TransferSize = DataSize; + hi2c->TransferCount = 0; + + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; + + if ((hi2c->Instance->CR1 & I2C_CR1_SBC_M) && (hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M)) /* Режим SBC несовместим с режимом NOSTRETCH */ + { + return HAL_ERROR; + } + + + HAL_I2C_InterruptDisable(hi2c, I2C_INTMASK); + HAL_I2C_InterruptEnable(hi2c, I2C_CR1_ERRIE_M + | I2C_CR1_STOPIE_M + | I2C_CR1_RXIE_M + ); + + return error_code; +} + +HAL_StatusTypeDef HAL_I2C_Slave_ReceiveSBC_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize) +{ + HAL_StatusTypeDef error_code = HAL_OK; + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->pBuffPtr = pData; + hi2c->TransferSize = DataSize; + hi2c->TransferCount = 0; + + if (!(hi2c->Instance->CR1 & I2C_CR1_SBC_M)) + { + return HAL_ERROR; + } + else if (hi2c->Instance->CR1 & I2C_CR1_NOSTRETCH_M) + { + /* Режим SBC несовместим с режимом NOSTRETCH */ + return HAL_ERROR; + } + + hi2c->Instance->CR2 |= I2C_CR2_RELOAD_M; + + HAL_I2C_InterruptDisable(hi2c, I2C_INTMASK); + HAL_I2C_InterruptEnable(hi2c, I2C_CR1_ERRIE_M + | I2C_CR1_STOPIE_M + | I2C_CR1_ADDRIE_M + | I2C_CR1_RXIE_M + ); + + + return error_code; +} + + +// void HAL_I2C_IRQHandler(I2C_HandleTypeDef *hi2c) +// { +// uint32_t int_mask = hi2c->Instance->CR1 & I2C_INTMASK; /* разрешенные прерывания */ +// uint32_t interrupt_status = hi2c->Instance->ISR; /* Флаги */ + +// if ((interrupt_status & I2C_ISR_ADDR_M) && (int_mask & I2C_CR1_ADDRIE_M)) +// { +// HAL_I2C_ADDR_Callback(hi2c); +// } + +// if ((interrupt_status & (I2C_ISR_BERR_M | I2C_ISR_ARLO_M | I2C_ISR_OVR_M)) && (int_mask & I2C_CR1_ERRIE_M)) +// { +// HAL_I2C_ERR_Callback(hi2c); +// } + +// if ((interrupt_status & I2C_ISR_NACKF_M) && (int_mask & I2C_CR1_NACKIE_M)) +// { +// HAL_I2C_NACK_Callback(hi2c); +// } + +// if ((interrupt_status & I2C_ISR_STOPF_M) && (int_mask & I2C_CR1_STOPIE_M)) +// { +// HAL_I2C_STOP_Callback(hi2c); +// } + +// if ((interrupt_status & I2C_ISR_TXIS_M) && (int_mask & I2C_CR1_TXIE_M)) +// { +// HAL_I2C_TXIS_Callback(hi2c); +// } + +// if ((interrupt_status & I2C_ISR_RXNE_M) && (int_mask & I2C_CR1_RXIE_M)) +// { +// HAL_I2C_RXNE_Callback(hi2c); +// } + +// if ((interrupt_status & I2C_ISR_TCR_M) && (int_mask & I2C_CR1_TCIE_M)) +// { +// HAL_I2C_TCR_Callback(hi2c); +// } + +// if ((interrupt_status & I2C_ISR_TC_M) && (int_mask & I2C_CR1_TCIE_M)) +// { +// HAL_I2C_TC_Callback(hi2c); +// } + +// } + diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_irq.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_irq.c new file mode 100644 index 0000000..1dad131 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_irq.c @@ -0,0 +1,56 @@ +#include "mik32_hal_irq.h" + +// #define MIK32_IRQ_DEBUG + +void HAL_IRQ_EnableInterrupts() +{ + set_csr(mstatus, MSTATUS_MIE); + set_csr(mie, MIE_MEIE); +} + +void HAL_IRQ_DisableInterrupts() +{ + clear_csr(mie, MIE_MEIE); +} + +void HAL_EPIC_MaskEdgeSet(uint32_t InterruptMask) +{ + EPIC->MASK_EDGE_SET |= InterruptMask; +} + +void HAL_EPIC_MaskEdgeClear(uint32_t InterruptMask) +{ + EPIC->MASK_EDGE_CLEAR |= InterruptMask; +} + +void HAL_EPIC_MaskLevelSet(uint32_t InterruptMask) +{ + EPIC->MASK_LEVEL_SET |= InterruptMask; +} + +void HAL_EPIC_MaskLevelClear(uint32_t InterruptMask) +{ + EPIC->MASK_LEVEL_CLEAR |= InterruptMask; +} + +uint32_t HAL_EPIC_GetStatus() +{ + return EPIC->STATUS; +} + +uint32_t HAL_EPIC_GetRawStatus() +{ + return EPIC->RAW_STATUS; +} + + + + + + + + + + + + diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_otp.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_otp.c new file mode 100644 index 0000000..a75016c --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_otp.c @@ -0,0 +1,388 @@ +#include "mik32_hal_otp.h" +#include "mik32_hal.h" + +/** + * @brief Включение тактирования модуля OTP. + * + * Эта функция может быть переопределена пользователем. + * + * @param hotp Указатель на структуру с настройками OTP. + */ +__attribute__((weak)) void HAL_OTP_MspInit(OTP_HandleTypeDef* hotp) +{ + __HAL_PCC_OTP_CONTROLLER_CLK_ENABLE(); +} + +/** + * @brief Включить/выключить режим пониженного энергопотребления. + * + * @param hotp Указатель на структуру с настройками OTP. + * @param PowerOff Режим пониженного энергопотребления. + */ +void HAL_OTP_PowerOff(OTP_HandleTypeDef *hotp, uint8_t PowerOff) +{ + uint32_t OtpadjConfig = hotp->Instance->OTPADJ; + + OtpadjConfig &= ~OTP_OTPADJ_POWER_OFF_I_M; + OtpadjConfig |= PowerOff << OTP_OTPADJ_POWER_OFF_I_S; + + hotp->Instance->OTPADJ = OtpadjConfig; + + /* После выхода из режима пониженного энергопотребления необходимо выдержать паузу */ + for (volatile int i = 0; i < 1000; i++); +} + +/** + * @brief Задать напряжение на UPP матрице. + * + * @param hotp Указатель на структуру с настройками OTP. + * @param UppReadVoltage Напряжение на UPP матрице. + */ +void HAL_OTP_SetUppRead(OTP_HandleTypeDef *hotp, uint8_t UppReadVoltage) +{ + uint32_t OtpadjConfig = hotp->Instance->OTPADJ; + + OtpadjConfig &= ~OTP_OTPADJ_SEL_UPP_READ_I_M; + OtpadjConfig |= UppReadVoltage << OTP_OTPADJ_SEL_UPP_READ_I_S; + + hotp->Instance->OTPADJ = OtpadjConfig; +} + +/** + * @brief Задать ток считывания. + * + * @param hotp Указатель на структуру с настройками OTP. + * @param ReadCur Ток считывания. + */ +void HAL_OTP_SetReadCur(OTP_HandleTypeDef *hotp, uint8_t ReadCur) +{ + uint32_t OtpadjConfig = hotp->Instance->OTPADJ; + + OtpadjConfig &= ~OTP_OTPADJ_SEL_READ_CUR_I_M; + OtpadjConfig |= ReadCur << OTP_OTPADJ_SEL_READ_CUR_I_S; + + hotp->Instance->OTPADJ = OtpadjConfig; +} + +/** + * @brief Инициализация рекомендуемых временных интервалов. + * + * @param hotp Указатель на структуру с настройками OTP. + */ +void HAL_OPT_TimeInit(OTP_HandleTypeDef *hotp) +{ + uint8_t APBMDivider = PM->DIV_APB_M; + uint8_t AHBDivider = PM->DIV_AHB; + uint32_t OscillatorSystem = PM->AHB_CLK_MUX & PM_AHB_CLK_MUX_M; + + uint32_t OtpadjConfig = hotp->Instance->OTPADJ; + uint32_t otpwt1_config = hotp->Instance->OTPWT1; + uint32_t otpwt2_config = hotp->Instance->OTPWT2; + + /* Рекомендуемое значение для N_RA, N_RH, N_SU, N_H. ceil(40/Period), где Period в нс */ + uint32_t Div = 0; + /* Тактирование от 32МГц */ + if((OscillatorSystem == PM_AHB_CLK_MUX_HSI32M_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32M_M)) + { + Div = 1000; + } + + /* Тактирование от 32кГц */ + if((OscillatorSystem == PM_AHB_CLK_MUX_LSI32K_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32K_M)) + { + Div = 1000000; + } + + uint32_t recommended_value = 0; + if((40 * 32) % (((APBMDivider + 1) * (AHBDivider + 1)) * Div) == 0) + { + recommended_value = (40 * 32) / (((APBMDivider + 1) * (AHBDivider + 1)) * Div); + } + else + { + recommended_value = (40 * 32) / (((APBMDivider + 1) * (AHBDivider + 1)) * Div) + 1; + } + + + /* Рекомендуемое значение N_W = 50 000 000 нс / Pclk, где Pclk – период тактового сигнала в нс */ + uint32_t recommended_N_W = 0; + if((OscillatorSystem == PM_AHB_CLK_MUX_HSI32M_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32M_M)) + { + recommended_N_W = (5 * 32 * 10000) / ((APBMDivider + 1) * (AHBDivider + 1)); + } + + /* Тактирование от 32кГц */ + if((OscillatorSystem == PM_AHB_CLK_MUX_LSI32K_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32K_M)) + { + recommended_N_W = (5 * 32 * 10) / ((APBMDivider + 1) * (AHBDivider + 1)); + } + + OtpadjConfig &= ~OTP_OTPADJ_N_RSU_M; /* При частоте менее 200МГц рекомендуемое значение 0 */ + + OtpadjConfig &= ~OTP_OTPADJ_N_RA_M; + OtpadjConfig |= recommended_value << OTP_OTPADJ_N_RA_S; + + OtpadjConfig &= ~OTP_OTPADJ_N_RH_M; + OtpadjConfig |= recommended_value << OTP_OTPADJ_N_RH_S; + + otpwt1_config &= ~OTP_OTPWT1_N_SU_M; + otpwt1_config |= recommended_value << OTP_OTPWT1_N_SU_S; + + otpwt1_config &= ~OTP_OTPWT1_N_H_M; + otpwt1_config |= recommended_value << OTP_OTPWT1_N_H_S; + + otpwt2_config &= ~OTP_OTPWT2_N_W_M; + otpwt2_config |= recommended_N_W << OTP_OTPWT2_N_W_S; + + hotp->Instance->OTPADJ = OtpadjConfig; + hotp->Instance->OTPWT1 = otpwt1_config; + hotp->Instance->OTPWT2 = otpwt2_config; + +} + +/** + * @brief + * + * @param hotp Указатель на структуру с настройками OTP. + * @param ReadMode Режим чтения + */ +void HAL_OPT_SetReadMode(OTP_HandleTypeDef *hotp, uint8_t ReadMode) +{ + uint32_t OtpconConfig = hotp->Instance->OTPCON; + + OtpconConfig &= ~OTP_OTPCON_APBNWS_M; + OtpconConfig |= ReadMode << OTP_OTPCON_APBNWS_S; + + hotp->Instance->OTPCON = OtpconConfig; + hotp->ReadMode = ReadMode; +} + +/** + * @brief Инициализировать OTP. + * + * @param hotp Указатель на структуру с настройками OTP. + */ +void HAL_OTP_Init(OTP_HandleTypeDef *hotp) +{ + + HAL_OTP_MspInit(hotp); + + // /* Настройка временных ограничений */ + HAL_OPT_TimeInit(hotp); + + // /* Выбор напряжения на UPP матрицы */ + HAL_OTP_SetUppRead(hotp, OTP_UPP_READ_2_5V); + + /* Режим чтения */ + HAL_OPT_SetReadMode(hotp, hotp->ReadMode); +} + +/** + * @brief Ожидать сброса флага BSY. + * + * Флаг BSY = 1 - Блок занят (выполняется запрошенная операция). + * Используется при операции записи и чтении в 3 этапа. + * + * @param hotp Указатель на структуру с настройками OTP. + */ +void HAL_OTP_WaitBSY(OTP_HandleTypeDef *hotp) +{ + /* Опрос флага BSY пока он не станет очищен */ + while (hotp->Instance->OTPSTA & OTP_OTPSTA_BSY_M); +} + +/** + * @brief Записать массив данных в тестовый столбец. + * + * @warning Если в массиве Data количество бит больше размера столбца, начиная с Address, то запись продолжится с начала столбца. + * + * @param hotp Указатель на структуру с настройками OTP. + * @param Address Начальная ячейка столбца. Значение может быть в пределах от 0 до 7. + * @param Data Данные для записи в тестовый столбец. + * @param DataLength Размер массива Data. + */ +void HAL_OTP_WriteTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength) +{ + /* OTPA[4:3] = 10b - тестовый столбец OTP */ + hotp->Instance->OTPA = 0b10000 + (Address & 0b111); + + for (uint32_t i = 0; i < DataLength; i++) + { + hotp->Instance->OTPDAT = Data[i]; + HAL_OTP_WaitBSY(hotp); + } +} + +/** + * @brief Записать данные в тестовую строку. + * + * @param hotp Указатель на структуру с настройками OTP. + * @param Data Данные для записи в тестовую строку. + */ +void HAL_OTP_WriteTestRow(OTP_HandleTypeDef *hotp, uint32_t Data) +{ + /* OTPA[4:3] = 01b - тестовая строка OTP */ + hotp->Instance->OTPA = 0b01000; + + hotp->Instance->OTPDAT = Data; + HAL_OTP_WaitBSY(hotp); +} + +/** + * @brief Записать бит в тестовую ячейку. + * + * @param hotp Указатель на структуру с настройками OTP. + * @param Data Бит для записи в тестовую ячейку. + */ +void HAL_OTP_WriteTestBit(OTP_HandleTypeDef *hotp, uint32_t Data) +{ + /* OTPA[4:3] = 11b - последняя тестовая ячейка в тестовой строке */ + hotp->Instance->OTPA = 0b11000; + + hotp->Instance->OTPDAT = Data; + HAL_OTP_WaitBSY(hotp); +} + +/** + * @brief Записать данные в основной массив OTP. + * @param hotp Указатель на структуру с настройками OTP. + * @param Address Начальная строка. Значение может быть в пределах от 0 до 7. + * @param Data Данные для записи в основной массив OTP. + * @param DataLength Размер массива Data. + */ +void HAL_OTP_Write(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength) +{ + /* OTPA[4:3] = 00b - основной массив OTP */ + hotp->Instance->OTPA = 0b00000 + (Address & 0b111); + + for (uint32_t i = 0; i < DataLength; i++) + { + hotp->Instance->OTPDAT = Data[i]; + HAL_OTP_WaitBSY(hotp); + } +} + +/** + * @brief Прочитать данные из тестового столбца. + * @param hotp Указатель на структуру с настройками OTP. + * @param Address Начальная ячейка столбца. Значение может быть в пределах от 0 до 7. + * @param DataRead Массив для считывания данных тестового столбца. + * @param DataLength Размер массива DataRead. + */ +void HAL_OTP_ReadTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength) +{ + if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */ + { + /* OTPA[4:3] = 10b - тестовый столбец OTP */ + uint8_t address_mask = 0b00111; + uint8_t address_column_mask = (1 << 4); + + for (uint32_t i = 0; i < DataLength; i++) + { + hotp->Instance->OTPA = ((Address + i) & address_mask) | address_column_mask; + HAL_OTP_WaitBSY(hotp); + DataRead[i] = hotp->Instance->OTPDAT; + } + } + else /* Чтение в 2 этапа. Со вставкой тактов ожидания. Без опроса BSY. С автоинкрементированием адреса OTPA. */ + { + /* OTPA[4:3] = 10b - тестовый столбец OTP */ + uint8_t address_column = 0b10000 + (Address & 0b111); + hotp->Instance->OTPA = address_column; + DataRead[0] = hotp->Instance->OTPDAT; + + for (uint32_t i = 0; i < DataLength; i++) + { + DataRead[i] = hotp->Instance->OTPDAT; + } + } + + +} + +/** + * @brief Прочитать данные из тестовой строки. + * @param hotp Указатель на структуру с настройками OTP. + * @return Тестовая строка. + */ +uint32_t HAL_OTP_ReadTestRow(OTP_HandleTypeDef *hotp) +{ + uint32_t DataRead = 0; + + /* OTPA[4:3] = 01b - тестовая строка OTP */ + hotp->Instance->OTPA = 0b01000; + + if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */ + { + HAL_OTP_WaitBSY(hotp); + } + else + { + DataRead = hotp->Instance->OTPDAT; + } + + DataRead = hotp->Instance->OTPDAT; + + return DataRead; +} + +/** + * @brief Прочитать бит из тестовой ячейки. + * @param hotp hotp - Указатель на структуру с настройками OTP. + * @return Бит из тестовой ячейки. + */ +uint32_t HAL_OTP_ReadTestBit(OTP_HandleTypeDef *hotp) +{ + uint32_t DataRead = 0; + + /* OTPA[4:3] = 11b - последняя тестовая ячейка в тестовой строке */ + hotp->Instance->OTPA = 0b11000; + + if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */ + { + HAL_OTP_WaitBSY(hotp); + } + else + { + DataRead = hotp->Instance->OTPDAT; + } + + DataRead = hotp->Instance->OTPDAT; + + return DataRead; +} + +/** + * @brief Прочитать данные из основного массива OTP. + * @param hotp Указатель на структуру с настройками OTP. + * @param Address Начальная строка основного массива OTP. Значение может быть в пределах от 0 до 7. + * @param DataRead Массив для считывания данных основного массива OTP. + * @param DataLength Размер массива DataRead. + */ +void HAL_OTP_Read(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength) +{ + if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */ + { + /* OTPA[4:3] = 00b - основной массив OTP */ + uint8_t address_mask = 0b00111; + + for (uint32_t i = 0; i < DataLength; i++) + { + hotp->Instance->OTPA = (Address + i) & address_mask; + HAL_OTP_WaitBSY(hotp); + DataRead[i] = hotp->Instance->OTPDAT; + } + } + else /* Чтение в 2 этапа. Со вставкой тактов ожидания. Без опроса BSY. С автоинкрементированием адреса OTPA. */ + { + /* OTPA[4:3] = 00b - основной массив OTP */ + hotp->Instance->OTPA = 0b00000 + (Address & 0b111); + DataRead[0] = hotp->Instance->OTPDAT; + + for (uint32_t i = 0; i < DataLength; i++) + { + DataRead[i] = hotp->Instance->OTPDAT; + } + } + +} diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_pcc.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_pcc.c new file mode 100644 index 0000000..0d0c6fa --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_pcc.c @@ -0,0 +1,399 @@ +#include "mik32_hal_pcc.h" + +/** + * @brief Включить источник тактирования. + * @param Oscillator Источник тактирования для включения. + * @warning Аргумент функции не является маской. + * + */ +void HAL_PCC_OscEnable(HAL_PCC_OscillatorTypeTypeDef Oscillator) +{ + switch (Oscillator) + { + case PCC_OSCILLATORTYPE_HSI32M: + WU->CLOCKS_SYS &= ~(1 << WU_CLOCKS_SYS_HSI32M_EN_S); // Включить HSI32M + break; + case PCC_OSCILLATORTYPE_OSC32M: + WU->CLOCKS_SYS &= ~(1 << WU_CLOCKS_SYS_OSC32M_EN_S); // Включить OSC32M + break; + case PCC_OSCILLATORTYPE_LSI32K: + WU->CLOCKS_BU &= ~(1 << WU_CLOCKS_BU_LSI32K_EN_S); // Включить LSI32K + break; + case PCC_OSCILLATORTYPE_OSC32K: + WU->CLOCKS_BU &= ~(1 << WU_CLOCKS_BU_OSC32K_EN_S); // Включить OSC32K + break; + default: + break; + } +} + +/** + * @brief Выключить источник тактирования. + * @param Oscillator Источник тактирования для выключения. + * @warning Аргумент функции не является маской. + * + */ +void HAL_PCC_OscDisable(uint32_t Oscillator) +{ + switch (Oscillator) + { + case PCC_OSCILLATORTYPE_HSI32M: + WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_HSI32M_EN_S); // Выключить HSI32M + break; + case PCC_OSCILLATORTYPE_OSC32M: + WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_OSC32M_EN_S); // Выключить OSC32M + break; + case PCC_OSCILLATORTYPE_LSI32K: + WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_LSI32K_EN_S); // Выключить LSI32K + break; + case PCC_OSCILLATORTYPE_OSC32K: + WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_OSC32K_EN_S); // Выключить OSC32K + break; + } +} + +/** + * @brief Выбрать опорный источник тактирования монитора частоты. + * + * Функция предназначена для назначения опорного источника тактирования монитора частоты. + * + * @param Force32KClk Опорный источник тактирования монитора частоты. + * @return Состояние об ошибках. + * @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций, + * то функция вернет ошибку HAL_TIMEOUT, а выбранный источник не будет назначен. + * + */ +HAL_StatusTypeDef HAL_PCC_FreqMonRefSet(HAL_PCC_FreqMonitorSourceTypeDef Force32KClk) +{ + uint32_t clockswitch_timeout = 0; + uint32_t ref_clk_m = 0; + uint32_t ref_clk_flag_m = 0; + + switch (Force32KClk) + { + case PCC_FREQ_MONITOR_SOURCE_AUTO: + WU->CLOCKS_SYS &= ~WU_CLOCKS_SYS_FORCE_32K_CLK_M; + return HAL_OK; + case PCC_FREQ_MONITOR_SOURCE_OSC32K: + ref_clk_m = WU_CLOCKS_SYS_FORCE_32K_CLK_OSC32K_M; + ref_clk_flag_m = PM_FREQ_STATUS_OSC32K_M; + break; + case PCC_FREQ_MONITOR_SOURCE_LSI32K: + ref_clk_m = WU_CLOCKS_SYS_FORCE_32K_CLK_LSI32K_M; + ref_clk_flag_m = PM_FREQ_STATUS_LSI32K_M; + break; + default: + return HAL_ERROR; + } + + while (!(PM->FREQ_STATUS & ref_clk_flag_m)) + { + clockswitch_timeout++; + if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + WU->CLOCKS_SYS = (WU->CLOCKS_SYS & ~(WU_CLOCKS_SYS_FORCE_32K_CLK_M)) | ref_clk_m; + for (volatile int i = 0; i < 100; i++) + ; + return HAL_OK; +} + +/** + * @brief Выбрать приоритетный источник тактирования системы. + * + * Функция предназначена для назначения приоритетного источника тактирования системы. Если ForceOscSys = #PCC_FORCE_OSC_SYS_FIXED, + * то источник тактирования системы не будет автоматически переключаться, при пропадании сигнала. + * + * @param OscillatorSystem Источник тактирования системы. + * @param ForceOscSys Запрет автоматического переключения с выбранного источника тактирования. + * @return Состояние об ошибках. + * @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций, + * то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник будет назначен приоритетным. Разрешение автоматического + * переключения будет установлено как #PCC_FORCE_OSC_SYS_UNFIXED. + * + */ +HAL_StatusTypeDef HAL_PCC_SetOscSystem(uint32_t OscillatorSystem, HAL_PCC_ForceOscSysTypeDef ForceOscSys) +{ + uint32_t clockswitch_timeout = 0; + uint32_t sys_clk_m = 0; + uint32_t osc_clk_flag_m = 0; + + /* Настройка источника тактирования системы */ + switch (OscillatorSystem) + { + case PCC_OSCILLATORTYPE_HSI32M: + sys_clk_m = PM_AHB_CLK_MUX_HSI32M_M; + osc_clk_flag_m = PM_FREQ_STATUS_HSI32M_M; + break; + case PCC_OSCILLATORTYPE_OSC32M: + sys_clk_m = PM_AHB_CLK_MUX_OSC32M_M; + osc_clk_flag_m = PM_FREQ_STATUS_OSC32M_M; + break; + case PCC_OSCILLATORTYPE_LSI32K: + sys_clk_m = PM_AHB_CLK_MUX_LSI32K_M; + osc_clk_flag_m = PM_FREQ_STATUS_LSI32K_M; + break; + case PCC_OSCILLATORTYPE_OSC32K: + sys_clk_m = PM_AHB_CLK_MUX_OSC32K_M; + osc_clk_flag_m = PM_FREQ_STATUS_OSC32K_M; + break; + default: + return HAL_ERROR; + } + + while (!(PM->FREQ_STATUS & osc_clk_flag_m)) + { + clockswitch_timeout++; + if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE) + { + PM->AHB_CLK_MUX = sys_clk_m | PM_AHB_FORCE_MUX_UNFIXED; + return HAL_TIMEOUT; + } + } + + PM->AHB_CLK_MUX = sys_clk_m | (ForceOscSys << PM_AHB_FORCE_MUX_S); + + for (volatile int i = 0; i < 100; i++) + ; + + return HAL_OK; +} + +/** + * @brief Выбрать приоритетный источник тактирования RTC. + * + * Функция предназначена для назначения приоритетного источника RTC. + * + * @param Oscillator Источник тактирования RTC. + * @return Состояние об ошибках. + * @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций, + * то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник не будет назначен приоритетным. + * + */ +HAL_StatusTypeDef HAL_PCC_RTCClock(HAL_PCC_RTCClockSourceTypeDef Oscillator) +{ + uint32_t clockswitch_timeout = 0; + uint32_t rtc_clk_m = 0; + uint32_t osc_clk_flag_m = 0; + + switch (Oscillator) + { + case PCC_RTC_CLOCK_SOURCE_AUTO: + WU->CLOCKS_BU &= ~WU_CLOCKS_BU_RTC_CLK_MUX_M; + return HAL_OK; + case PCC_RTC_CLOCK_SOURCE_LSI32K: + rtc_clk_m = WU_CLOCKS_BU_RTC_CLK_MUX_LSI32K_M; + osc_clk_flag_m = PM_FREQ_STATUS_LSI32K_M; + break; + case PCC_RTC_CLOCK_SOURCE_OSC32K: + rtc_clk_m = WU_CLOCKS_BU_RTC_CLK_MUX_OSC32K_M; + osc_clk_flag_m = PM_FREQ_STATUS_OSC32K_M; + break; + default: + return HAL_ERROR; + } + + while (!(PM->FREQ_STATUS & osc_clk_flag_m)) + { + clockswitch_timeout++; + if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Выбор источника тактирования RTC */ + WU->CLOCKS_BU = (WU->CLOCKS_BU & ~WU_CLOCKS_BU_RTC_CLK_MUX_M) | rtc_clk_m; + WU->RTC_CONRTOL = WU_RTC_CONTROL_RESET_CLEAR_M; + + for (volatile int i = 0; i < 100; i++) + ; + + return HAL_OK; +} + +/** + * @brief Выбрать источник тактирования RTC в составе ядра. + * + * Функция предназначена для выбора приоритетного источника RTC в составе ядра. + * + * @param Oscillator Источник тактирования RTC в составе ядра. + * @return Состояние об ошибках. + * @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций, + * то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник не будет выбран. + * + */ +HAL_StatusTypeDef HAL_PCC_CPURTCClock(HAL_PCC_CPURTCClockSourceTypeDef Oscillator) +{ + uint32_t clockswitch_timeout = 0; + uint32_t rtc_clk_m = 0; + uint32_t osc_clk_flag_m = 0; + + switch (Oscillator) + { + case PCC_CPU_RTC_CLOCK_SOURCE_LSI32K: + rtc_clk_m = PM_CPU_RTC_CLK_MUX_LSI32K_M; + osc_clk_flag_m = PM_FREQ_STATUS_LSI32K_M; + break; + case PCC_CPU_RTC_CLOCK_SOURCE_OSC32K: + rtc_clk_m = PM_CPU_RTC_CLK_MUX_OSC32K_M; + osc_clk_flag_m = PM_FREQ_STATUS_OSC32K_M; + break; + default: + return HAL_ERROR; + } + + while (!(PM->FREQ_STATUS & osc_clk_flag_m)) + { + clockswitch_timeout++; + if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + PM->CPU_RTC_CLK_MUX = rtc_clk_m; + + for (volatile int i = 0; i < 100; i++) + ; + + return HAL_OK; +} + +/** + * @brief Задать делитель шины AHB. + * @param DividerAHB Делитель. + * + * Делитель является 32-х битным числом. Частота шины AHB определяется по формуле: @f$ \frac{F_{sys\_clk}}{DividerAHB + 1} @f$. + */ +void HAL_PCC_DividerAHB(uint32_t DividerAHB) +{ + PM->DIV_AHB = DividerAHB; +} + +/** + * @brief Задать делитель шины APB_M. + * @param DividerAPB_M Делитель. + * + * Делитель является 32-х битным числом. Частота шины APB_M определяется по формуле: @f$ \frac{F_{AHB}}{DividerAPB\_M + 1} @f$. + */ +void HAL_PCC_DividerAPB_M(uint32_t DividerAPB_M) +{ + PM->DIV_APB_M = DividerAPB_M; +} + +/** + * @brief Задать делитель шины APB_P. + * @param DividerAPB_P Делитель. + * + * Делитель является 32-х битным числом. Частота шины APB_M определяется по формуле: @f$ \frac{F_{AHB}}{DividerAPB\_P + 1} @f$. + */ +void HAL_PCC_DividerAPB_P(uint32_t DividerAPB_P) +{ + PM->DIV_APB_P = DividerAPB_P; +} + +/** + * @brief Настроить тактирование и монитор частоты. + * + * Функция для настройки тактирования и монитора частоты в соответствии с заданными настройками в PCC_Init. + * + * @param PCC_Init Структура с настройками. + * @return Структура с состояниями об ошибках. + * @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций, + * то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник не будет применен. Если такая ошибка возникла при + * при выборе системного источника, то выбранный источник будет назначен приоритетным. Разрешение автоматического + * переключения будет установлено как #PCC_FORCE_OSC_SYS_UNFIXED. + * + */ +PCC_ConfigErrorsTypeDef HAL_PCC_Config(PCC_InitTypeDef *PCC_Init) +{ + PCC_ConfigErrorsTypeDef errors = {HAL_OK}; + + /* Включить все источники тактирования */ + WU->CLOCKS_SYS &= ~(0b11 << WU_CLOCKS_SYS_OSC32M_EN_S); // Включить OSC32M и HSI32M + WU->CLOCKS_BU &= ~(0b11 << WU_CLOCKS_BU_OSC32K_EN_S); // Включить OSC32K и LSI32K + + WU->CLOCKS_SYS = WU_CLOCKS_SYS_ADJ_HSI32M(PCC_Init->HSI32MCalibrationValue); // Поправочный коэффициент HSI32M + WU->CLOCKS_BU = WU_CLOCKS_BU_ADJ_LSI32K(PCC_Init->LSI32KCalibrationValue); // Поправочный коэффициент LSI32K + + /* Опорный источник для монитора частоты */ + errors.FreqMonRef = HAL_PCC_FreqMonRefSet(PCC_Init->FreqMon.Force32KClk); + + /* Настройка источника тактирования системы */ + errors.SetOscSystem = HAL_PCC_SetOscSystem(PCC_Init->FreqMon.OscillatorSystem, PCC_Init->FreqMon.ForceOscSys); + + /* Делители частоты */ + HAL_PCC_DividerAHB(PCC_Init->AHBDivider); + HAL_PCC_DividerAPB_M(PCC_Init->APBMDivider); + HAL_PCC_DividerAPB_P(PCC_Init->APBPDivider); + + /* Выбор источника тактирования RTC */ + errors.RTCClock = HAL_PCC_RTCClock(PCC_Init->RTCClockSelection); + + /* Выбор источника тактирования RTC в составе ядра*/ + errors.CPURTCClock = HAL_PCC_CPURTCClock(PCC_Init->RTCClockCPUSelection); + + + + /* Отключение неиспользуемых источников тактирования */ + /* Источники 32МГц */ + /* Внутренний */ + if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_HSI32M)) + { + WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_HSI32M_EN_S); // Выключить HSI32M + } + + // /* Внешний */ + if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_OSC32M)) + { + WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_OSC32M_EN_S); // Выключить OSC32M + } + + /* Источники 32кГц */ + /* Внутренний */ + if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_LSI32K)) + { + WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_LSI32K_EN_S); // Выключить LSI32K + } + + /* Внешний */ + if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_OSC32K)) + { + WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_OSC32K_EN_S); // Выключить OSC32K + } + + return errors; +} + +/** + * @brief Получить частоту приоритетного системного источника тактирования в Гц. + * @return Частота приоритетного системного источника в Гц. + * @warning Система может тактироваться не от приоритетного источника. Например, если источник не был назначен принудительно и сигнал от источника отсутствует. + * В таком случае автоматически выбирается источник в соответствии со следующим приоритетом: OSC32M, HSI32M, OSC32K, LSI32K. + */ +uint32_t HAL_PCC_GetSysClockFreq() +{ + uint32_t system_clock = 0; + + switch (PM->AHB_CLK_MUX & PM_AHB_CLK_MUX_M) + { + case PM_AHB_CLK_MUX_OSC32M_M: + system_clock = OSC_SYSTEM_VALUE; + break; + case PM_AHB_CLK_MUX_OSC32K_M: + system_clock = OSC_CLOCK_VALUE; + break; + case PM_AHB_CLK_MUX_HSI32M_M: + system_clock = HSI_VALUE; + break; + case PM_AHB_CLK_MUX_LSI32K_M: + system_clock = LSI_VALUE; + break; + } + + return system_clock; +} \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_rtc.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_rtc.c new file mode 100644 index 0000000..bd640b9 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_rtc.c @@ -0,0 +1,271 @@ +#include "mik32_hal_rtc.h" + +__attribute__((weak)) void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) +{ + __HAL_PCC_RTC_CLK_ENABLE(); +} + +void HAL_RTC_WaitFlag(RTC_HandleTypeDef *hrtc) +{ + uint32_t retry_limit = 10000; + for (uint32_t i = 0; i < retry_limit; i++) + { + if ((hrtc->Instance->CTRL & RTC_CTRL_FLAG_M) == 0) + { + return; + } + } + + while (hrtc->Instance->CTRL & RTC_CTRL_FLAG_M); + + + #ifdef MIK32_RTC_DEBUG + xprintf("Ожидание установки CTRL.FLAG в 0 превышено\n"); + #endif +} + +void HAL_RTC_Disable(RTC_HandleTypeDef *hrtc) +{ + // Для записи даты нужно сбросить бит EN в регистре CTRL + RTC->CTRL &= ~RTC_CTRL_EN_M; + HAL_RTC_WaitFlag(hrtc); +} + +void HAL_RTC_Enable(RTC_HandleTypeDef *hrtc) +{ + // Установка бита EN включает модуль RTC + RTC->CTRL |= RTC_CTRL_EN_M; + HAL_RTC_WaitFlag(hrtc); +} + +void HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime) +{ + uint8_t DOW, TH, H, TM, M, TS, S; + DOW = sTime->Dow; + TH = sTime->Hours / 10; + H = sTime->Hours % 10; + TM = sTime->Minutes / 10; + M = sTime->Minutes % 10; + TS = sTime->Seconds / 10; + S = sTime->Seconds % 10; + + uint32_t RTC_time = (DOW << RTC_TIME_DOW_S) | // День недели + (TH << RTC_TIME_TH_S) | // Десятки часов + (H << RTC_TIME_H_S) | // Единицы часов + (TM << RTC_TIME_TM_S) | // Десятки минут + (M << RTC_TIME_M_S) | // Единицы минут + (TS << RTC_TIME_TS_S) | // Десятки секунд + (S << RTC_TIME_S_S) | // Единицы секунд + (0 << RTC_TIME_TOS_S); // Десятые секунды + + #ifdef MIK32_RTC_DEBUG + xprintf("Установка времени RTC\n"); + #endif + + hrtc->Instance->TIME = RTC_time; + HAL_RTC_WaitFlag(hrtc); +} + +void HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate) +{ + uint8_t TC, C, TY, Y, TM, M, TD, D; + TC = sDate->Century / 10; + C = sDate->Century % 10; + TY = sDate->Year / 10; + Y = sDate->Year % 10; + TM = sDate->Month / 10; + M = sDate->Month % 10; + TD = sDate->Day / 10; + D = sDate->Day % 10; + + uint32_t RTC_data = (TC << RTC_DATE_TC_S) | // Десятки века + (C << RTC_DATE_C_S) | // Единицы века + (TY << RTC_DATE_TY_S) | // Десятки года + (Y << RTC_DATE_Y_S) | // Единицы года + (TM << RTC_DATE_TM_S) | // Десятки месяца + (M << RTC_DATE_M_S) | // Единицы месяца + (TD << RTC_DATE_TD_S) | // Десятки числа + (D << RTC_DATE_D_S); // Единицы числа + + #ifdef MIK32_RTC_DEBUG + xprintf("Установка даты RTC\n"); + #endif + + hrtc->Instance->DATE = RTC_data; + HAL_RTC_WaitFlag(hrtc); +} + +void HAL_RTC_Alarm_SetTime(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm) +{ + uint8_t DOW, TH, H, TM, M, TS, S; + DOW = sAlarm->AlarmTime.Dow; + TH = sAlarm->AlarmTime.Hours / 10; + H = sAlarm->AlarmTime.Hours % 10; + TM = sAlarm->AlarmTime.Minutes / 10; + M = sAlarm->AlarmTime.Minutes % 10; + TS = sAlarm->AlarmTime.Seconds / 10; + S = sAlarm->AlarmTime.Seconds % 10; + + uint32_t RTC_alarm_time = (DOW << RTC_TIME_DOW_S) | // День недели + (TH << RTC_TIME_TH_S) | // Десятки часов + (H << RTC_TIME_H_S) | // Единицы часов + (TM << RTC_TIME_TM_S) | // Десятки минут + (M << RTC_TIME_M_S) | // Единицы минут + (TS << RTC_TIME_TS_S) | // Десятки секунд + (S << RTC_TIME_S_S) | // Единицы секунд + (0 << RTC_TIME_TOS_S); // Десятые секунды + + #ifdef MIK32_RTC_DEBUG + xprintf("Установка времени будильника\n"); + #endif + + hrtc->Instance->TALRM = RTC_alarm_time | sAlarm->MaskAlarmTime; + HAL_RTC_WaitFlag(hrtc); +} + +void HAL_RTC_Alarm_SetDate(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm) +{ + uint8_t TC, C, TY, Y, TM, M, TD, D; + TC = sAlarm->AlarmDate.Century / 10; + C = sAlarm->AlarmDate.Century % 10; + TY = sAlarm->AlarmDate.Year / 10; + Y = sAlarm->AlarmDate.Year % 10; + TM = sAlarm->AlarmDate.Month / 10; + M = sAlarm->AlarmDate.Month % 10; + TD = sAlarm->AlarmDate.Day / 10; + D = sAlarm->AlarmDate.Day % 10; + + uint32_t RTC_alarm_data = (TC << RTC_DATE_TC_S) | // Десятки века + (C << RTC_DATE_C_S) | // Единицы века + (TY << RTC_DATE_TY_S) | // Десятки года + (Y << RTC_DATE_Y_S) | // Единицы года + (TM << RTC_DATE_TM_S) | // Десятки месяца + (M << RTC_DATE_M_S) | // Единицы месяца + (TD << RTC_DATE_TD_S) | // Десятки числа + (D << RTC_DATE_D_S); // Единицы числа + + #ifdef MIK32_RTC_DEBUG + xprintf("Установка даты будильника\n"); + #endif + + hrtc->Instance->DALRM = RTC_alarm_data | sAlarm->MaskAlarmDate; + HAL_RTC_WaitFlag(hrtc); +} + +void HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm) +{ + HAL_RTC_Alarm_SetTime(hrtc, sAlarm); + HAL_RTC_Alarm_SetDate(hrtc, sAlarm); +} + +void HAL_RTC_AlarmDisable(RTC_HandleTypeDef *hrtc) +{ + hrtc->Instance->TALRM &= ~(RTC_TALRM_CS_M | RTC_TALRM_CM_M | RTC_TALRM_CH_M | RTC_TALRM_CDOW_M); + HAL_RTC_WaitFlag(hrtc); + + hrtc->Instance->DALRM &= ~(RTC_DALRM_CD_M | RTC_DALRM_CM_M | RTC_DALRM_CY_M | RTC_DALRM_CC_M); + HAL_RTC_WaitFlag(hrtc); +} + +void HAL_RTC_ClearAlrmFlag(RTC_HandleTypeDef *hrtc) +{ + /* Сброс флага ALRM в RTC */ + hrtc->Instance->CTRL &= ~RTC_CTRL_ALRM_M; + HAL_RTC_WaitFlag(hrtc); +} + +int HAL_RTC_GetAlrmFlag(RTC_HandleTypeDef *hrtc) +{ + return (hrtc->Instance->CTRL & RTC_CTRL_ALRM_M) >> RTC_CTRL_ALRM_S; +} + +RTC_DateTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc) +{ + uint8_t TC, C, TY, Y, TM, M, TD, D; + uint32_t rtc_date_read = hrtc->Instance->DATE; + RTC_DateTypeDef sDate = {0}; + + TC = (rtc_date_read & RTC_DATE_TC_M) >> RTC_DATE_TC_S; + C = (rtc_date_read & RTC_DATE_C_M) >> RTC_DATE_C_S; + TY = (rtc_date_read & RTC_DATE_TY_M) >> RTC_DATE_TY_S; + Y = (rtc_date_read & RTC_DATE_Y_M) >> RTC_DATE_Y_S; + TM = (rtc_date_read & RTC_DATE_TM_M) >> RTC_DATE_TM_S; + M = (rtc_date_read & RTC_DATE_M_M) >> RTC_DATE_M_S; + TD = (rtc_date_read & RTC_DATE_TD_M) >> RTC_DATE_TD_S; + D = (rtc_date_read & RTC_DATE_D_M) >> RTC_DATE_D_S; + + sDate.Century = TC * 10 + C; + sDate.Year = TY * 10 + Y; + sDate.Month = TM * 10 + M; + sDate.Day = TD * 10 + D; + + #ifdef MIK32_RTC_DEBUG + xprintf("\n%d%d век\n", TC, C); + xprintf("%d%d.%d%d.%d%d\n", TD, D, TM, M, TY, Y); + #endif + + return sDate; +} + +RTC_TimeTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc) +{ + RTC_TimeTypeDef sTime; + + sTime.Dow = hrtc->Instance->DOW; + sTime.Hours = hrtc->Instance->TH * 10 + hrtc->Instance->H; + sTime.Minutes = hrtc->Instance->TM * 10 + hrtc->Instance->M; + sTime.Seconds = hrtc->Instance->TS * 10 + hrtc->Instance->S; + + #ifdef MIK32_RTC_DEBUG + switch (hrtc->Instance->DOW) + { + case 1: + xprintf("Понедельник\n"); + break; + case 2: + xprintf("Вторник\n"); + break; + case 3: + xprintf("Среда\n"); + break; + case 4: + xprintf("Четверг\n"); + break; + case 5: + xprintf("Пятница\n"); + break; + case 6: + xprintf("Суббота\n"); + break; + case 7: + xprintf("Воскресенье\n"); + break; + } + xprintf("%d%d:%d%d:%d%d.%d\n", hrtc->Instance->TH, hrtc->Instance->H, hrtc->Instance->TM, + hrtc->Instance->M, hrtc->Instance->TS, hrtc->Instance->S, hrtc->Instance->TOS); + #endif + + return sTime; +} + +void HAL_RTC_SetInterruptAlarm(RTC_HandleTypeDef *hrtc, uint32_t InterruptEnable) +{ + hrtc->Interrupts.Alarm = InterruptEnable; + + uint32_t config = hrtc->Instance->CTRL; + config &= ~RTC_CTRL_INTE_M; + config |= InterruptEnable << RTC_CTRL_INTE_S; + hrtc->Instance->CTRL = config; + + HAL_RTC_WaitFlag(hrtc); +} + +void HAL_RTC_InterruptInit(RTC_HandleTypeDef *hrtc) +{ + HAL_RTC_SetInterruptAlarm(hrtc, hrtc->Interrupts.Alarm); +} + +int HAL_RTC_GetINTE(RTC_HandleTypeDef *hrtc) +{ + return (hrtc->Instance->CTRL & RTC_CTRL_INTE_M) >> RTC_CTRL_INTE_S; +} diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spi.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spi.c new file mode 100644 index 0000000..5982196 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spi.c @@ -0,0 +1,628 @@ +#include "mik32_hal_spi.h" + +/** + * @brief Инициализация SPI MSP. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + */ +__attribute__((weak)) void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + if (hspi->Instance == SPI_0) + { + __HAL_PCC_SPI_0_CLK_ENABLE(); + + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + + switch (hspi->Init.ChipSelect) + { + case SPI_CS_0: + GPIO_InitStruct.Pin = GPIO_PIN_4; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + break; + + case SPI_CS_1: + GPIO_InitStruct.Pin = GPIO_PIN_14; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + break; + + case SPI_CS_2: + GPIO_InitStruct.Pin = GPIO_PIN_15; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + break; + + case SPI_CS_3: + GPIO_InitStruct.Pin = GPIO_PIN_6; + HAL_GPIO_Init(GPIO_2, &GPIO_InitStruct); + break; + } + + /* В режиме ведущего вывод SPIx_N_SS_IN должен быть в режиме SPI с подтяжкой к питанию. */ + GPIO_InitStruct.Pin = GPIO_PIN_3; + if (hspi->Init.SPI_Mode == HAL_SPI_MODE_MASTER) + { + GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP; + } + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + + if (hspi->Instance == SPI_1) + { + __HAL_PCC_SPI_1_CLK_ENABLE(); + + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + + switch (hspi->Init.ChipSelect) + { + case SPI_CS_0: + GPIO_InitStruct.Pin = GPIO_PIN_4; + break; + + case SPI_CS_1: + GPIO_InitStruct.Pin = GPIO_PIN_5; + break; + + case SPI_CS_2: + GPIO_InitStruct.Pin = GPIO_PIN_6; + break; + + case SPI_CS_3: + GPIO_InitStruct.Pin = GPIO_PIN_7; + break; + } + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_3; + if (hspi->Init.SPI_Mode == HAL_SPI_MODE_MASTER) + { + GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP; + } + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + } +} + +/** + * @brief Включить модуль SPI. + * + * Перед включением модуля производится сброс флагов ошибок и очистка буферов TX и RX. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + */ +void HAL_SPI_Enable(SPI_HandleTypeDef *hspi) +{ + HAL_SPI_ClearError(hspi); + __HAL_SPI_ENABLE(hspi); +} + +/** + * @brief Выключить модуль SPI. + * + * После выключения модуля производится сброс флагов ошибок и очистка буферов TX и RX. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + */ +void HAL_SPI_Disable(SPI_HandleTypeDef *hspi) +{ + __HAL_SPI_DISABLE(hspi); + HAL_SPI_ClearError(hspi); +} + +/** + * @brief Задать задержку BTWN. + * + * Задержка в периодах опорного тактового сигнала между снятием сигнала выбора одного ведомого + * устройства и установкой сигнала выбора другого ведомого устройства. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param btwn задержка BTWN в периодах опорного тактового сигнала. + * Этот параметр может быть значением в пределах от 0 до 255. + */ +void HAL_SPI_SetDelayBTWN(SPI_HandleTypeDef *hspi, uint8_t btwn) +{ + hspi->Instance->DELAY &= ~SPI_DELAY_BTWN_M; + hspi->Instance->DELAY |= SPI_DELAY_BTWN(btwn); +} + +/** + * @brief Задать задержку AFTER. + * + * Задержка в периодах опорного тактового сигнала между последним битом текущего слова + * и первым битом следующего слова. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param after Задержка AFTER в периодах опорного тактового сигнала. + * Этот параметр может быть числом в пределах от 0 до 255. + */ +void HAL_SPI_SetDelayAFTER(SPI_HandleTypeDef *hspi, uint8_t after) +{ + hspi->Instance->DELAY &= ~SPI_DELAY_AFTER_M; + hspi->Instance->DELAY |= SPI_DELAY_AFTER(after); +} + +/** + * @brief Задать задержку INIT. + * + * Дополнительная задержка в периодах опорного тактового сигнала между установкой + * сигнала n_ss_out в «0» и передачей первого бита. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param init задержка INIT в периодах опорного тактового сигнала. + * Этот параметр может быть числом в пределах от 0 до 255. + */ +void HAL_SPI_SetDelayINIT(SPI_HandleTypeDef *hspi, uint8_t init) +{ + hspi->Instance->DELAY &= ~SPI_DELAY_INIT_M; + hspi->Instance->DELAY |= SPI_DELAY_INIT(init); +} + +/** + * @brief Задать задержку перед передачей. + * + * Модуль SPI в режиме ведомого устройства начинает передачу только когда тактовый сигнал + * sclk_in (внешнего ведущего устройства) не изменяется в течение количества периодов опорного + * тактового сигнала SPI заданного в этом поле или когда модуль SPI не активен. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param slave_idle_counter задержку перед передачей в периодах опорного тактового сигнала. + * Этот параметр может быть числом в пределах от 0 до 255. + */ +void HAL_SPI_SetSlaveIdleCounter(SPI_HandleTypeDef *hspi, uint8_t slave_idle_counter) +{ + hspi->Instance->SIC = slave_idle_counter; +} + +/** + * @brief Задать уровень, при котором TX_FIFO считается незаполненным и формируется + * прерывание TX_FIFO_NOT_full (IXR_TXOW). + * + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param threshold уровень, при котором TX_FIFO считается не заполненным. + */ +void HAL_SPI_SetThresholdTX(SPI_HandleTypeDef *hspi, uint32_t threshold) +{ + hspi->Init.ThresholdTX = threshold; + hspi->Instance->TX_THR = threshold; +} + +/** + * @brief Получить идентификационный номер модуля. Ожидаемое ID 0x01090100. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @return идентификационный номер модуля. + */ +uint32_t HAL_SPI_ReadModuleID(SPI_HandleTypeDef *hspi) +{ + return hspi->Instance->ID; +} + +/** + * @brief Инициализировать SPI в соответствии с настройками в @ref SPI_HandleTypeDef. + * + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @return Статус HAL. + */ +HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi) +{ + HAL_StatusTypeDef error_code = HAL_OK; + + if (hspi == NULL) + { + return HAL_ERROR; + } + + HAL_SPI_MspInit(hspi); + + HAL_SPI_ClearError(hspi); + + /* Выключение модуля SPI */ + HAL_SPI_Disable(hspi); + + uint32_t SPI_config = 0; + + /* Настройка режима ведомого */ + switch (hspi->Init.SPI_Mode) + { + case HAL_SPI_MODE_MASTER: + SPI_config = SPI_CONFIG_MASTER_M; + break; + case HAL_SPI_MODE_SLAVE: + SPI_config = SPI_CONFIG_SLAVE_M; + hspi->Init.ManualCS = SPI_MANUALCS_OFF; + break; + } + + /* Настройки SPI */ + SPI_config |= (hspi->Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S) | /* Настройка делителя частоты */ + (hspi->Init.ManualCS << SPI_CONFIG_MANUAL_CS_S) | /* Настройка режима управления сигналом CS */ + (hspi->Init.CLKPhase << SPI_CONFIG_CLK_PH_S) | /* Настройка фазы тактового сигнала */ + (hspi->Init.CLKPolarity << SPI_CONFIG_CLK_POL_S) | /* Настройка полярности тактового сигнала */ + (hspi->Init.Decoder << SPI_CONFIG_PERI_SEL_S); /* Настройка использования внешнего декодера */ + //(hspi->Init.DataSize << SPI_CONFIG_DATA_SZ_S); /* Длина передаваемой посылки */ + + /* Выбор ведомого в соответствии с режимом ManualCS */ + if (hspi->Init.ManualCS == SPI_MANUALCS_ON) + { + /* Ведомое устройство не выбрано. Ручное управление сигналом CS */ + SPI_config |= SPI_CS_NONE << SPI_CONFIG_CS_S; + } + else + { + /* Выбор ведомого устройства в автоматическом режиме управления CS */ + SPI_config |= hspi->Init.ChipSelect << SPI_CONFIG_CS_S; + } + + /* Установка выбранных настроек */ + hspi->Instance->CONFIG = SPI_config; + + HAL_SPI_SetDelayBTWN(hspi, 1); + HAL_SPI_SetDelayAFTER(hspi, 0); + HAL_SPI_SetDelayINIT(hspi, 0); + + /* уровень при котором регистр TX считается незаполненным и формируется прерывание */ + if (hspi->Init.ThresholdTX > 8) + { + return HAL_ERROR; + } + HAL_SPI_SetThresholdTX(hspi, hspi->Init.ThresholdTX); + + hspi->TxCount = 0; + hspi->RxCount = 0; + + hspi->State = HAL_SPI_STATE_READY; + + return error_code; +} + +/** + * @brief Очистить буфер TX_FIFO. + * + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + */ +void HAL_SPI_ClearTXFIFO(SPI_HandleTypeDef *hspi) +{ + hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M; +} + +/** + * @brief Очистить буфер RX_FIFO. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + */ +void HAL_SPI_ClearRXFIFO(SPI_HandleTypeDef *hspi) +{ + hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_RX_FIFO_M; +} + +/** + * @brief Сбросить флаги ошибок, очистить буферы RX и TX. + * + * @warning Функция выключает модуль SPI. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + **/ +void HAL_SPI_ClearError(SPI_HandleTypeDef *hspi) +{ + /* Сброс ошибок */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + + __HAL_SPI_DISABLE(hspi); + HAL_SPI_ClearRXFIFO(hspi); + HAL_SPI_ClearTXFIFO(hspi); + volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */ + (void) unused; +} + +/** + * @brief Выбрать ведомое устройство. + * + * В ручном режиме управления сигналом выбора ведомого + * @ref SPI_InitTypeDef::ManualCS "SPI_HandleTypeDef.Init.ManualCS" = @ref SPI_MANUALCS_ON при вызове функции выбранный вывод + * перейдет в активное состояние (низкий уровень). + * + * В автоматическом режиме управления сигналом выбора ведомого функция задает один из сигналов + * CS0 - CS3, который будет использован во время передачи. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param CS_M ведомое устройство. + * Этот параметр должен быть одним из следующих значений: + * - @ref SPI_CS_NONE - ведомое устройство не выбрано + * - @ref SPI_CS_0 - ведомое устройство 1 + * - @ref SPI_CS_1 - ведомое устройство 2 + * - @ref SPI_CS_2 - ведомое устройство 3 + * - @ref SPI_CS_3 - ведомое устройство 4 + * Если используется внешний декодер (@ref SPI_InitTypeDef::Decoder "SPI_HandleTypeDef.Init.Decoder" = @ref SPI_DECODER_USE), + * @ref SPI_InitTypeDef::ChipSelect "SPI_HandleTypeDef.Init.ChipSelect" отображается на выводах CS0 - CS3. + */ +void HAL_SPI_CS_Enable(SPI_HandleTypeDef *hspi, uint32_t CS_M) +{ + hspi->Init.ChipSelect = CS_M; + CS_M = CS_M << SPI_CONFIG_CS_S; + hspi->Instance->CONFIG = (hspi->Instance->CONFIG & ~SPI_CONFIG_CS_M) | CS_M; +} + +/** + * @brief Перевести активный сигнал выбора ведомого в неактивное состояние (высокий уровень). + * + * Функция устанавливает значение @ref SPI_CS_NONE - ведомые устройства не выбраны. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + */ +void HAL_SPI_CS_Disable(SPI_HandleTypeDef *hspi) +{ + hspi->Init.ChipSelect = SPI_CS_NONE; + hspi->Instance->CONFIG = (hspi->Instance->CONFIG & ~SPI_CONFIG_CS_M) | SPI_CONFIG_CS_NONE_M; +} + +/** + * @brief Запустить передачу и прием данных. + * + * Байты поочередно передаются и считываются по одному байту. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param TransmitBytes указатель на буфер передаваемых данных. + * @param ReceiveBytes указатель на буфер считываемых данных. + * @param DataSize число байт для отправки и приема. + * @param Timeout продолжительность тайм-аута. + * @return Статус HAL. + * + * @warning Во время обмена пороговое значение ThresholdTX = 1. + */ +HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout) +{ + uint32_t txallowed = 1; + HAL_StatusTypeDef error_code = HAL_OK; + uint32_t timeout_counter = 0; + + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)ReceiveBytes; + hspi->RxCount = DataSize; + hspi->pTxBuffPtr = (uint8_t *)TransmitBytes; + hspi->TxCount = DataSize; + + hspi->Instance->TX_THR = 1; + + /* Включить SPI если выключено */ + if (!(hspi->Instance->ENABLE & SPI_ENABLE_M)) + { + __HAL_SPI_ENABLE(hspi); + } + + while ((hspi->TxCount > 0) || (hspi->RxCount > 0)) + { + /* Проверка флага TX_FIFO_NOT_FULL */ + if ((hspi->Instance->INT_STATUS & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M) && (hspi->TxCount > 0) && (txallowed == 1)) + { + hspi->Instance->TXDATA = *(hspi->pTxBuffPtr); + hspi->pTxBuffPtr++; + hspi->TxCount--; + /* Следующие данные - прием (Rx). Tx не разрешен */ + txallowed = 0; + } + + /* Ожидание когда установится флаг RX_FIFO_NOT_EMPTY */ + if ((hspi->Instance->INT_STATUS & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M) && (hspi->RxCount > 0)) + { + *(hspi->pRxBuffPtr) = hspi->Instance->RXDATA; + hspi->pRxBuffPtr++; + hspi->RxCount--; + /* Следующие данные - передача (Tx). Tx разрешается */ + txallowed = 1; + } + + if (((timeout_counter++) >= Timeout) || (Timeout == 0U)) + { + error_code = HAL_TIMEOUT; + goto error; + } + } + +error: + __HAL_SPI_DISABLE(hspi); + hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */ + volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */ + (void) unused; + + + return error_code; +} + + +/** + * @brief Запустить передачу и прием данных с учетом порогового значения @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX". + * + * Сначала полностью заполняется буфер TX. Затем начинается передача, состоящая из цикличного считывания + * и отправки @ref SPI_BUFFER_SIZE - @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX" + 1 байт. Если во + * время ожидания байта в буфере RX опустошился буфер TX ниже порогового значения ThresholdTX, + * то в буфер TX записывается 1 байт. За одну итерацию цикла в буфер TX записывается и считывается из буфера RX не более + * @ref SPI_BUFFER_SIZE - @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX" + 1 байт. + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param TransmitBytes указатель на буфер передаваемых данных. + * @param ReceiveBytes указатель на буфер считываемых данных. + * @param DataSize число байт для отправки и приема. + * @param Timeout продолжительность тайм-аута. + * @return Статус HAL. + */ +HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout) +{ + uint32_t tx_offset = 0; /* Номер отправляемого байта */ + uint32_t rx_offset = 0; /* Номер считываемого байта */ + uint32_t tx_counter = 0; /* Количество записанных байт в буфер TX за итерацию */ + uint32_t write_read_bytes = SPI_BUFFER_SIZE - hspi->Init.ThresholdTX + 1; /* Число байт для записи и чтения в итерации */ + uint32_t status_tx = 0; /* Регистр состояний флагов SPI во время записи в TXDATA */ + uint32_t timeout_counter = Timeout; + HAL_StatusTypeDef error_code = HAL_OK; + + /* Очистка ошибок */ + HAL_SPI_ClearError(hspi); + + /* Первая запись буфера до полного заполнения */ + while (!(hspi->Instance->INT_STATUS & SPI_INT_STATUS_TX_FIFO_FULL_M)) + { + hspi->Instance->TXDATA = TransmitBytes[tx_offset]; + tx_offset++; + + /* Количество записанных байт не должно быть больше буфера */ + if (tx_offset >= SPI_BUFFER_SIZE) + { + return HAL_ERROR; + } + } + + /* Включить SPI */ + __HAL_SPI_ENABLE(hspi); + + while ((tx_offset < DataSize) || (rx_offset < DataSize)) + { + /* Чтение (8 - Threshold + 1) байт. */ + if (rx_offset < DataSize) + { + for (uint32_t rx_counter = 0; (rx_counter < write_read_bytes) && (rx_offset < DataSize); rx_counter++) + { + timeout_counter = Timeout; + while (!((status_tx = hspi->Instance->INT_STATUS) & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M)) + { + + if (!(timeout_counter--)) + { + error_code = HAL_TIMEOUT; + goto error; + } + + if (status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M)) + { + goto error; + } + + /* Если буфер RX пуст, а буфер TX опустошился ниже порогового значения, то в буфер TX записывается байт. */ + if (((tx_counter != 0) || ((status_tx = hspi->Instance->INT_STATUS) & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M)) && (tx_offset < DataSize) && (tx_counter < write_read_bytes)) + { + if (status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M)) + { + goto error; + } + hspi->Instance->TXDATA = TransmitBytes[tx_offset++]; + tx_counter++; + } + } + ReceiveBytes[rx_offset++] = hspi->Instance->RXDATA; + } + } + + if (tx_offset < DataSize) + { + timeout_counter = Timeout; + /* Ожидание опустошение буфера ниже */ + while ((tx_counter == 0) && (!((status_tx = hspi->Instance->INT_STATUS) & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M))) + { + if (!(timeout_counter--)) + { + error_code = HAL_TIMEOUT; + goto error; + } + + if (status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M)) + { + goto error; + } + } + + for (; (tx_counter < write_read_bytes) && (tx_offset < DataSize); tx_counter++) + { + hspi->Instance->TXDATA = TransmitBytes[tx_offset++]; + } + tx_counter = 0; + } + } + +error: + __HAL_SPI_DISABLE(hspi); + hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */ + if ((status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M))) + { + if (status_tx & SPI_INT_STATUS_RX_OVERFLOW_M) + { + hspi->ErrorCode |= HAL_SPI_ERROR_OVR; + } + else + { + hspi->ErrorCode |= HAL_SPI_ERROR_MODF; + } + + error_code = HAL_ERROR; + } + status_tx = hspi->Instance->INT_STATUS; + + return error_code; +} + +/** + * @brief Запустить передачу и прием данных с прерываниями. + * + * Во время передачи используются следующие прерывания: + * - RX_OVERFLOW: прерывание при переполнении буфера RX_FIFO + * - MODE_FAIL: напряжение на выводе n_ss_in не соответствую режиму работы SPI + * - TX_FIFO_NOT_FULL: регистр TX_FIFO не заполнен (опустошился ниже значения @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX") + * - RX_FIFO_NOT_EMPTY: буфер RX_FIFO не пустой + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param TransmitBytes указатель на буфер передаваемых данных. + * @param ReceiveBytes указатель на буфер считываемых данных. + * @param Size число байт для отправки и приема. + * @return Статус HAL. + */ +HAL_StatusTypeDef HAL_SPI_Exchange_IT(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size) +{ + HAL_StatusTypeDef error_code = HAL_OK; + + if ((TransmitBytes == NULL) || (ReceiveBytes == NULL) || (Size == 0)) + { + error_code = HAL_ERROR; + return error_code; + } + if (hspi->Init.ThresholdTX == 0) + { + error_code = HAL_ERROR; + return error_code; + } + + hspi->State = HAL_SPI_STATE_BUSY; + + hspi->pTxBuffPtr = TransmitBytes; + hspi->TxCount = Size; + hspi->pRxBuffPtr = ReceiveBytes; + hspi->RxCount = Size; + + /* Очистка ошибок */ + HAL_SPI_ClearError(hspi); + + /* Первая запись буфера до полного заполнения */ + for (uint32_t i = 0; i < SPI_BUFFER_SIZE; i++) + { + hspi->Instance->TXDATA = *(hspi->pTxBuffPtr); + hspi->pTxBuffPtr++; + hspi->TxCount--; + } + + + /* Включить SPI если выключено */ + if (!(hspi->Instance->ENABLE & SPI_ENABLE_M)) + { + __HAL_SPI_ENABLE(hspi); + } + + HAL_SPI_InterruptEnable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M /* Прерывания ошибок */ + | SPI_INT_STATUS_TX_FIFO_NOT_FULL_M | SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M); /* Прерывания опустошения буфера TX и наличие байтов в буфере RX */ + + return error_code; +} diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spifi.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spifi.c new file mode 100644 index 0000000..ebe000b --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spifi.c @@ -0,0 +1,127 @@ +#include + +__attribute__((weak)) void HAL_SPIFI_MspInit() +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + __HAL_PCC_SPIFI_CLK_ENABLE(); + + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_2, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP; + HAL_GPIO_Init(GPIO_2, &GPIO_InitStruct); +} + +void HAL_SPIFI_MemoryMode_Init(SPIFI_MemoryModeConfig_HandleTypeDef *spifi) +{ + HAL_SPIFI_MspInit(); + + spifi->Instance->STAT |= SPIFI_CONFIG_STAT_RESET_M; + spifi->Instance->CLIMIT = spifi->CacheLimit; // Граница кеширования + if (spifi->CacheEnable) + { + spifi->Instance->CTRL |= SPIFI_CONFIG_CTRL_CACHE_EN_M; + } + else + { + spifi->Instance->CTRL &= ~SPIFI_CONFIG_CTRL_CACHE_EN_M; + } + + // Настройка команды чтения + spifi->Instance->MCMD = ((spifi->Command.InterimLength << SPIFI_CONFIG_MCMD_INTLEN_S) | + (spifi->Command.FieldForm << SPIFI_CONFIG_MCMD_FIELDFORM_S) | + (spifi->Command.FrameForm << SPIFI_CONFIG_MCMD_FRAMEFORM_S) | + (spifi->Command.OpCode << SPIFI_CONFIG_MCMD_OPCODE_S)); +} + +HAL_StatusTypeDef HAL_SPIFI_SendCommand( + SPIFI_HandleTypeDef *spifi, + SPIFI_CommandTypeDef *cmd, + uint32_t address, + uint16_t bufferSize, + uint8_t *readBuffer, + uint8_t *writeBuffer, + uint32_t timeout) +{ + return HAL_SPIFI_SendCommand_LL( + spifi, + cmd->Direction | + SPIFI_CONFIG_CMD_INTLEN(cmd->InterimLength) | + SPIFI_CONFIG_CMD_FIELDFORM(cmd->FieldForm) | + SPIFI_CONFIG_CMD_FRAMEFORM(cmd->FrameForm) | + SPIFI_CONFIG_CMD_OPCODE(cmd->OpCode), + address, + bufferSize, + readBuffer, + writeBuffer, + cmd->InterimData, + timeout); +} + +HAL_StatusTypeDef HAL_SPIFI_SendCommand_LL( + SPIFI_HandleTypeDef *spifi, + uint32_t cmd, + uint32_t address, + uint16_t bufferSize, + uint8_t *readBuffer, + uint8_t *writeBuffer, + uint32_t interimData, + uint32_t timeout) +{ + spifi->Instance->STAT |= SPIFI_CONFIG_STAT_INTRQ_M; + spifi->Instance->ADDR = address; + spifi->Instance->IDATA = interimData; + spifi->Instance->CMD = cmd | SPIFI_CONFIG_CMD_DATALEN(bufferSize); + + if (cmd & SPIFI_CONFIG_CMD_DOUT_M) + { + if ((bufferSize > 0) && (writeBuffer == 0)) + { + return HAL_ERROR; + } + for (int i = 0; i < bufferSize; i++) + { + spifi->Instance->DATA8 = writeBuffer[i]; + } + } + else + { + if ((bufferSize > 0) && (readBuffer == 0)) + { + return HAL_ERROR; + } + for (int i = 0; i < bufferSize; i++) + { + readBuffer[i] = (uint8_t)spifi->Instance->DATA8; + } + } + HAL_StatusTypeDef waitStatus = HAL_SPIFI_WaitCommandProcessing(spifi, timeout); + if ((waitStatus == HAL_OK) && (cmd & SPIFI_CONFIG_CMD_POLL_M)) + { + if (SPIFI_CONFIG->DATA8 == (cmd & SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE_M)) + { + return HAL_OK; + } + return HAL_ERROR; + } + return waitStatus; +} + +bool HAL_SPIFI_IsMemoryModeEnabled(SPIFI_HandleTypeDef *spifi) +{ + return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_MCINIT_M) != 0; +} + +void HAL_SPIFI_Reset(SPIFI_HandleTypeDef *spifi) +{ + spifi->Instance->STAT = SPIFI_CONFIG_STAT_RESET_M; +} + +bool HAL_SPIFI_IsReady(SPIFI_HandleTypeDef *spifi) +{ + return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_RESET_M) == 0; +} diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c new file mode 100644 index 0000000..7bcda80 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c @@ -0,0 +1,1028 @@ +#include "mik32_hal_timer16.h" + +/** + * @brief Настройка режимов выводов и тактирования Timer16. + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +__attribute__((weak)) void HAL_TIMER16_MspInit(Timer16_HandleTypeDef* htimer16) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + /* Вывод ШИМ не переводится в нужный режим */ + + if (htimer16->Instance == TIMER16_0) + { + __HAL_PCC_TIMER16_0_CLK_ENABLE(); + + if ((htimer16->Clock.Source == TIMER16_SOURCE_EXTERNAL_INPUT1) || (htimer16->CountMode == TIMER16_COUNTMODE_EXTERNAL)) + { + GPIO_InitStruct.Pin = GPIO_PIN_5; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + + if (htimer16->EncoderMode == TIMER16_ENCODER_ENABLE) + { + GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + + if (htimer16->Waveform.Enable == TIMER16_WAVEFORM_GENERATION_ENABLE) + { + GPIO_InitStruct.Pin = GPIO_PIN_7; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + + + } + + if (htimer16->Instance == TIMER16_1) + { + __HAL_PCC_TIMER16_1_CLK_ENABLE(); + + if ((htimer16->Clock.Source == TIMER16_SOURCE_EXTERNAL_INPUT1) || (htimer16->CountMode == TIMER16_COUNTMODE_EXTERNAL)) + { + GPIO_InitStruct.Pin = GPIO_PIN_8; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + + if (htimer16->EncoderMode == TIMER16_ENCODER_ENABLE) + { + GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + + if (htimer16->Waveform.Enable == TIMER16_WAVEFORM_GENERATION_ENABLE) + { + GPIO_InitStruct.Pin = GPIO_PIN_10; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + } + + if (htimer16->Instance == TIMER16_2) + { + __HAL_PCC_TIMER16_2_CLK_ENABLE(); + + if ((htimer16->Clock.Source == TIMER16_SOURCE_EXTERNAL_INPUT1) || (htimer16->CountMode == TIMER16_COUNTMODE_EXTERNAL)) + { + GPIO_InitStruct.Pin = GPIO_PIN_11; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + + if (htimer16->EncoderMode == TIMER16_ENCODER_ENABLE) + { + GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + + if (htimer16->Waveform.Enable == TIMER16_WAVEFORM_GENERATION_ENABLE) + { + GPIO_InitStruct.Pin = GPIO_PIN_13; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + } +} + +/** + * @brief Выключить таймер. + * Может использоваться для отключения таймера или при записи в регистр CFGR. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16) +{ + htimer16->Instance->CR &= ~TIMER16_CR_ENABLE_M; +} + +/** + * @brief Включить таймер + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16) +{ + htimer16->Instance->CR |= TIMER16_CR_ENABLE_M; +} + +/** + * @brief Установить активный фронт для подсчёта или задать подрежим энкодера. + * Используется при тактировании Timer16 от внешнего источника тактового сигнала на выводе Input1. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param ActiveEdge Активный фронт. Возможные значения ActiveEdge: + * - #TIMER16_ACTIVEEDGE_RISING Нарастающий фронт является активным. Подрежим энкодера 1; + * - #TIMER16_ACTIVEEDGE_FOLLING Спадающий фронт является активным. Подрежим энкодера 2; + * - #TIMER16_ACTIVEEDGE_BOTH Оба фронта являются активными фронтами. Подрежим энкодера 3. + * + * @note Если оба фронта сконфигурированы как активные, необходимо также обеспечить внутренний тактовый сигнал. + * В этом случае частота внутреннего тактового сигнала должна быть как минимум в четыре раза выше частоты внешнего тактового сигнала. + * При тактировании от Input1 ( HAL_Timer16_SetSourceClock ) счетчик Timer16 может обновляться либо по нарастающему, + * либо по спадающему фронту тактового сигнала lnput1, но не по двум (нарастающему и спадающему фронту) одновременно. + * + * @warning При использовании данной функции таймер выключается. Это необходимо для записи в регистр CFGR. + * + * + */ +void HAL_Timer16_SetActiveEdge(Timer16_HandleTypeDef *htimer16, uint8_t ActiveEdge) +{ + htimer16->ActiveEdge = ActiveEdge; + + HAL_Timer16_Disable(htimer16); + + uint32_t CFGRConfig = htimer16->Instance->CFGR; + CFGRConfig &= ~TIMER16_CFGR_CKPOL_M; + CFGRConfig |= ActiveEdge << TIMER16_CFGR_CKPOL_S; + + htimer16->Instance->CFGR = CFGRConfig; +} + +/** + * @brief Выбрать источник тактирования, который будет использовать Timer16. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param SourceClock Источник тактирования. + * @warning При использовании данной функции таймер выключается. Это необходимо для записи в регистр CFGR. + * + */ +void HAL_Timer16_SetSourceClock(Timer16_HandleTypeDef *htimer16, uint8_t SourceClock) +{ + htimer16->Clock.Source = SourceClock; + + HAL_Timer16_Disable(htimer16); + + if(SourceClock == TIMER16_SOURCE_EXTERNAL_INPUT1) /* Внешний источник Input1 */ + { + htimer16->Instance->CFGR |= TIMER16_CFGR_CKSEL_M; + + HAL_Timer16_SetActiveEdge(htimer16, htimer16->ActiveEdge); /* Настройка активного фронта при тактировании от внешнего источника */ + } + else /* Внутренний источник */ + { + /* Настройка источника тактирования таймера в PM(Power Manager) */ + uint32_t CFGConfig = PM->TIMER_CFG; + if(htimer16->Instance == TIMER16_0) + { + CFGConfig &= ~PM_TIMER_CFG_MUX_TIMER_M(PM_TIMER_CFG_MUX_TIMER16_0_S); + CFGConfig |= SourceClock << PM_TIMER_CFG_MUX_TIMER16_0_S; + } + else if (htimer16->Instance == TIMER16_1) + { + CFGConfig &= ~PM_TIMER_CFG_MUX_TIMER_M(PM_TIMER_CFG_MUX_TIMER16_1_S); + CFGConfig |= SourceClock << PM_TIMER_CFG_MUX_TIMER16_1_S; + } + else if (htimer16->Instance == TIMER16_2) + { + CFGConfig &= ~PM_TIMER_CFG_MUX_TIMER_M(PM_TIMER_CFG_MUX_TIMER16_2_S); + CFGConfig |= SourceClock << PM_TIMER_CFG_MUX_TIMER16_2_S; + } + /* Установка выбранного источника тактирования таймера в PM */ + PM->TIMER_CFG = CFGConfig; + + htimer16->Instance->CFGR &= ~TIMER16_CFGR_CKSEL_M; /* Внутренний источник */ + } + +} + +/** + * @brief Выбрать источник тактового сигнала для синхронизации счетчика Timer16. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param CountMode Источник тактового сигнала для синхронизации счетчика. + * @note При тактировании от Input1 Timer16 не нуждается во внутреннем источнике тактового сигнала + * (за исключением случаев, когда включены фильтры glitch). Сигнал, подаваемый на lnput1 Timer16, используется в качестве + * системного тактового генератора для Timer16. Эта конфигурация подходит для режимов работы, в которых не включен встроенный генератор. + * При такой конфигурации счетчик Timer16 может обновляться либо по нарастающему, либо по спадающему фронту тактового сигнала lnput1, + * но не по двум (нарастающему и спадающему фронту) одновременно. + * + * @warning При использовании данной функции таймер выключается. Это необходимо для записи в регистр CFGR. + * + */ +void HAL_Timer16_SetCountMode(Timer16_HandleTypeDef *htimer16, uint8_t CountMode) +{ + htimer16->CountMode = CountMode; + + HAL_Timer16_Disable(htimer16); + + switch (CountMode) + { + case TIMER16_COUNTMODE_INTERNAL: + htimer16->Instance->CFGR &= ~TIMER16_CFGR_COUNTMODE_M; + break; + case TIMER16_COUNTMODE_EXTERNAL: + htimer16->Instance->CFGR |= TIMER16_CFGR_COUNTMODE_M; + break; + } + +} + +/** + * @brief Инициализация тактирования в соответствии с параметрами #Timer16_HandleTypeDef *htimer16. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @warning При использовании данной функции таймер выключается. Это необходимо для записи в регистр CFGR. + */ +void HAL_Timer16_ClockInit(Timer16_HandleTypeDef *htimer16) +{ + HAL_Timer16_SetSourceClock(htimer16, htimer16->Clock.Source); + HAL_Timer16_SetCountMode(htimer16, htimer16->CountMode); +} + +/** + * @brief Задать режим обновления регистров ARR - значение автоматической перезагрузки и CMP - значение сравнения. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Preload Режим записи в ARR и CMP. + * + * @warning Для записи в ARR и CMP таймер должен быть включен. При использовании данной функции таймер выключается. Это необходимо для записи в регистр CFGR. + * + */ +void HAL_Timer16_SetPreload(Timer16_HandleTypeDef *htimer16, uint8_t Preload) +{ + htimer16->Preload = Preload; + + HAL_Timer16_Disable(htimer16); + + switch (Preload) + { + case TIMER16_PRELOAD_AFTERWRITE: + htimer16->Instance->CFGR &= ~TIMER16_CFGR_PRELOAD_M; + break; + case TIMER16_PRELOAD_ENDPERIOD: + htimer16->Instance->CFGR |= TIMER16_CFGR_PRELOAD_M; + break; + } +} + +/** + * @brief Ожидание флага ARROK, + * Установка флага ARROK означает успешную запись в регистр ARR - значение автоматической перезагрузки. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_WaitARROK(Timer16_HandleTypeDef *htimer16) +{ + while (!(htimer16->Instance->ISR & TIMER16_ISR_ARR_OK_M)); + HAL_Timer16_ClearInterruptFlag(htimer16, TIMER16_ICR_ARROKCF_S); +} + +/** + * @brief Ожидание флага CMPOK. + * Установка флага CMPOK означает успешную запись в регистр CMP - значение сравнения. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_WaitCMPOK(Timer16_HandleTypeDef *htimer16) +{ + while (!(htimer16->Instance->ISR & TIMER16_ISR_CMP_OK_M)); + HAL_Timer16_ClearInterruptFlag(htimer16, TIMER16_ICR_CMPOKCF_S); +} + +/** + * @brief Задать значение автоматической перезагрузки (ARR). + * Используется для установки верхнего предела, до которого будет считать счетчик Timer16. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Period 16 битное число в пределах от 0 до 65535. + * + * @warning Значение ARR должно быть всегда больше значения CMP. + */ +void HAL_Timer16_SetARR(Timer16_HandleTypeDef *htimer16, uint16_t Period) +{ + // htimer16->Period = Period; + + /* Выключение таймера для записи ARR */ + htimer16->Instance->ARR = Period; + if (!(htimer16->Instance->IER & TIMER16_IER_ARROKIE_M)) + { + HAL_Timer16_WaitARROK(htimer16); + } +} + +/** + * @brief Задать значение сравнения (CMP). + * Используется для сравнения текущего значения счетчика в регистре CNT со значением в регистре CMP. + * При совпадении CNT и CMP устанавливается флаг CMPM. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Compare 16 битное число в пределах от 0 до 65534. + * + * @warning В режиме генерации волновой формы при совпадении значений регистров CMP и CNT сигнал на выводе output меняет свое состояние. + * Значение ARR должно быть всегда больше значения CMP. + */ +void HAL_Timer16_SetCMP(Timer16_HandleTypeDef *htimer16, uint16_t Compare) +{ + /* Выключение таймера для записи CMP */ + htimer16->Instance->CMP = Compare; + + if (!(htimer16->Instance->IER & TIMER16_IER_CMPOKIE_M)) + { + HAL_Timer16_WaitCMPOK(htimer16); + } +} + +/** + * @brief Выбрать источник триггера. + * Счетчик Timer16 может быть запущен либо программно, либо после обнаружения активного + * фронта импульса на одном из 8 триггерных входов. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param TriggerSource Источник триггера. + * + * @warning При использовании данной функции таймер выключается. Это необходимо для записи в регистр CFGR. + */ +void HAL_Timer16_SelectTrigger(Timer16_HandleTypeDef *htimer16, uint8_t TriggerSource) +{ + htimer16->Trigger.Source = TriggerSource; + + /* Выключение таймера для записи CFGR */ + HAL_Timer16_Disable(htimer16); + + uint32_t CFGRConfig = htimer16->Instance->CFGR; + + CFGRConfig &= ~TIMER16_CFGR_TRIGSEL_M; + CFGRConfig |= TriggerSource << TIMER16_CFGR_TRIGSEL_S; + + htimer16->Instance->CFGR = CFGRConfig; +} + +/** + * @brief Выбрать разрешение работы и активный фронт триггера. + * Счетчик Timer16 может быть запущен либо программно, + * либо после обнаружения активного фронта импульса на одном из 8 триггерных входов. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param TriggerEdge Активный фронт триггера. + * @warning При использовании данной функции таймер выключается. Это необходимо для записи в регистр CFGR. + */ +void HAL_Timer16_SetTriggerEdge(Timer16_HandleTypeDef *htimer16, uint8_t TriggerEdge) +{ + htimer16->Trigger.ActiveEdge = TriggerEdge; + + /* Выключение таймера для записи CFGR */ + HAL_Timer16_Disable(htimer16); + + uint32_t CFGRConfig = htimer16->Instance->CFGR; + + CFGRConfig &= ~TIMER16_CFGR_TRIGEN_M; + CFGRConfig |= TriggerEdge << TIMER16_CFGR_TRIGEN_S; + + htimer16->Instance->CFGR = CFGRConfig; +} + +/** + * @brief Включить или выключить функцию time-out. + * С помощью включенной функции time-out активный фронт триггера + * может перезапустить отсчет таймера. Иначе повторное срабатывание + * триггера во время счета будет проигнорировано. Может быть реализована функция time-out + * с низким энергопотреблением. Значение time-out соответствует значению сравнения - CMP. + * Если в течение ожидаемого периода времени триггер не срабатывает, + * MCU пробуждается по событию совпадения сравнения. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param TimeOut Режим time-out. + * + * @warning При использовании данной функции таймер выключается. Это необходимо для записи в регистр CFGR. + */ +void HAL_Timer16_SetTimeOut(Timer16_HandleTypeDef *htimer16, uint8_t TimeOut) +{ + htimer16->Trigger.TimeOut = TimeOut; + + HAL_Timer16_Disable(htimer16); + + uint32_t CFGRConfig = htimer16->Instance->CFGR; + CFGRConfig &= ~TIMER16_CFGR_TIMOUT_M; + CFGRConfig |= TimeOut << TIMER16_CFGR_TIMOUT_S; + + htimer16->Instance->CFGR = CFGRConfig; +} + +/** + * @brief Задать чувствительность фильтра для внешнего тактового генератора. + * Прежде чем активировать цифровые фильтры, на Timer16 сначала должен быть подан + * внутренний источник синхронизации. В случае отсутствия внутреннего тактового сигнала + * цифровой фильтр должен быть деактивирован. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param FilterExternalClock Чувствительность фильтра. + * @warning При использовании данной функции таймер выключается. Это необходимо для записи в регистр CFGR. + * + */ +void HAL_Timer16_SetFilterExternalClock(Timer16_HandleTypeDef *htimer16, uint8_t FilterExternalClock) +{ + htimer16->Filter.ExternalClock = FilterExternalClock; + + /* Выключение таймера для записи в CFGR */ + HAL_Timer16_Disable(htimer16); + + htimer16->Instance->CFGR &= ~TIMER16_CFGR_CKFLT_M; + htimer16->Instance->CFGR |= FilterExternalClock << TIMER16_CFGR_CKFLT_S; +} + +/** + * @brief Задать чувствительность фильтра для триггера. + * Прежде чем активировать цифровые фильтры, на LPTIM сначала должен быть подан внутренний + * источник синхронизации. В случае отсутствия внутреннего тактового сигнала цифровой фильтр + * должен быть деактивирован. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param FilterTrigger Чувствительность фильтра. + * @warning При использовании данной функции таймер выключается. Это необходимо для записи в регистр CFGR. + */ +void HAL_Timer16_SetFilterTrigger(Timer16_HandleTypeDef *htimer16, uint8_t FilterTrigger) +{ + htimer16->Filter.Trigger = FilterTrigger; + + /* Выключение таймера для записи в CFGR */ + HAL_Timer16_Disable(htimer16); + + htimer16->Instance->CFGR &= ~TIMER16_CFGR_TRGFLT_M; + htimer16->Instance->CFGR |= FilterTrigger << TIMER16_CFGR_TRGFLT_S; +} + +/** + * @brief Включить или выключить режим энкодера. + * Режим энкодера доступен только в том случае, если Timer16 работает от внутреннего источника синхронизации. + * Частота сигналов на обоих входах lnput1 и lnput2 не должна превышать частоту внутреннего тактового генератора Timer16 , деленную на 4. + * Кроме того, коэффициент деления предделителя должен быть равен его начальному значению, которое равно 1. + * Это обязательно для обеспечения нормальной работы Timer16. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param EncoderMode Режим энкодера. + * @warning При использовании данной функции таймер выключается. Это необходимо для записи в регистр CFGR. + */ +void HAL_Timer16_SetEncoderMode(Timer16_HandleTypeDef *htimer16, uint8_t EncoderMode) +{ + htimer16->EncoderMode = EncoderMode; + + HAL_Timer16_Disable(htimer16); + + uint32_t CFGRConfig = htimer16->Instance->CFGR; + CFGRConfig &= ~TIMER16_CFGR_ENC_M; + CFGRConfig |= EncoderMode << TIMER16_CFGR_ENC_S; + + htimer16->Instance->CFGR = CFGRConfig; +} + +/** + * @brief Задать полярность формы волны на выводе Output. + * Используется при генерации волновой формы для настройки полярности выходного сигнала. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param WaveformPolarity Полярность выходного сигнала. + */ +void HAL_Timer16_WaveformPolarity(Timer16_HandleTypeDef *htimer16, HAL_Timer16_WaveformPolarityTypeDef WaveformPolarity) +{ + WaveformPolarity &= TIMER16_CFGR_WAVPOL_M; + HAL_Timer16_Disable(htimer16); + htimer16->Instance->CFGR = (htimer16->Instance->CFGR & (~TIMER16_CFGR_WAVPOL_M)) | WaveformPolarity; +} + +/** + * @brief Установить делитель частоты. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Prescaler Делитель частоты. + */ +void HAL_Timer16_SetPrescaler(Timer16_HandleTypeDef *htimer16, uint8_t Prescaler) +{ + htimer16->Clock.Prescaler = Prescaler; + + HAL_Timer16_Disable(htimer16); + + uint32_t CFGRConfig = htimer16->Instance->CFGR; + CFGRConfig &= ~TIMER16_CFGR_PRESC_M; + CFGRConfig |= Prescaler << TIMER16_CFGR_PRESC_S; + + htimer16->Instance->CFGR = CFGRConfig; +} + +/** + * @brief Инициализировать Timer16 в соответствии с настройками #Timer16_HandleTypeDef *htimer16. + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_Init(Timer16_HandleTypeDef *htimer16) +{ + HAL_TIMER16_MspInit(htimer16); + + HAL_Timer16_Disable(htimer16); + /* Настройка внутреннего/внешнего источника тактирования */ + HAL_Timer16_ClockInit(htimer16); + + HAL_Timer16_SetPrescaler(htimer16, htimer16->Clock.Prescaler); + + HAL_Timer16_SetFilterExternalClock(htimer16, htimer16->Filter.ExternalClock); + HAL_Timer16_SetFilterTrigger(htimer16, htimer16->Filter.Trigger); + + /*********************************************************/ + HAL_Timer16_SetPreload(htimer16, htimer16->Preload); + + /* Настройка триггера */ + HAL_Timer16_SelectTrigger(htimer16, htimer16->Trigger.Source); + HAL_Timer16_SetTriggerEdge(htimer16, htimer16->Trigger.ActiveEdge); + HAL_Timer16_SetTimeOut(htimer16, htimer16->Trigger.TimeOut); + /*********************************************************/ + + // HAL_Timer16_SetEncoderMode(htimer16, htimer16->EncoderMode); + + HAL_Timer16_WaveformPolarity(htimer16, htimer16->Waveform.Polarity); + + // HAL_Timer16_Enable(htimer16); + + // /* Верхний предел счета */ + // HAL_Timer16_SetARR(htimer16, htimer16->Period); + +} + +/** + * @brief Получить текущее значение счетчика из регистра CNT. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @return Текущее значение счетчика таймера16 (CNT). + */ +uint16_t HAL_Timer16_GetCounterValue(Timer16_HandleTypeDef *htimer16) +{ + return htimer16->Instance->CNT; +} + +/** + * @brief Проверить состояние флага сравнения CMPM. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @return Текущее состояние флага CMPM. + */ +uint8_t HAL_Timer16_CheckCMP(Timer16_HandleTypeDef *htimer16) +{ + if ((htimer16->Instance->ISR & TIMER16_ISR_CMP_MATCH_M) == 0) + { + return 0; + } + else + { + return 1; + } +} + +/** + * @brief Ожидать когда счетчик достигнет значения сравнения CMP. + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_WaitCMP(Timer16_HandleTypeDef *htimer16) +{ + while (!(htimer16->Instance->ISR & TIMER16_ISR_CMP_MATCH_M)); +} + +/** + * @brief Запустить таймер в продолжительном режиме. + * Счетчик будет считать от 0 до значения Period, а затем начнет сначала. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Period Значение автоматической перезагрузки. + */ +void HAL_Timer16_Counter_Start(Timer16_HandleTypeDef *htimer16, uint32_t Period) +{ + HAL_Timer16_Enable(htimer16); + + HAL_Timer16_SetARR(htimer16, Period); + + __HAL_TIMER16_START_CONTINUOUS(htimer16); +} + +/** + * @brief Запустить таймер с ШИМ сигналом. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Period Период ШИМ сигнала. Число от 0 до 65535. + * @param Compare Значение при достижении которого сигнал на выводе Output сменит свое состояние. + * Число от 0 до 65534. Данное число всегда должно быть меньше значения Period. + */ +void HAL_Timer16_StartPWM(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare) +{ + HAL_Timer16_Disable(htimer16); + htimer16->Instance->CFGR &= ~TIMER16_CFGR_WAVE_M; + HAL_Timer16_Enable(htimer16); + + if(Period > Compare) + { + HAL_Timer16_SetCMP(htimer16, Compare); + HAL_Timer16_SetARR(htimer16, Period); + } + + __HAL_TIMER16_START_CONTINUOUS(htimer16); + +} + +/** + * @brief Запустить таймер в одноимпульсном режиме. + * Счетчик будет считать от 0 до значения в регистре ARR. + * При достижении значения CMP сигнал на выводе Output сменит свое состояние. + * При достижении значения ARR сигнал на выводе Output вернется в исходное состояние. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Period Период ШИМ сигнала. Число от 0 до 65535; + * @param Compare Значение при достижении которого сигнал на выводе Output сменит свое состояние. + * Число от 0 до 65534. Данное число всегда должно быть меньше значения Period. + */ +void HAL_Timer16_StartOneShot(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare) +{ + HAL_Timer16_Disable(htimer16); + htimer16->Instance->CFGR &= ~TIMER16_CFGR_WAVE_M; + HAL_Timer16_Enable(htimer16); + + if(Period > Compare) + { + HAL_Timer16_SetCMP(htimer16, Compare); + HAL_Timer16_SetARR(htimer16, Period); + } + + __HAL_TIMER16_START_SINGLE(htimer16); + +} + +/** + * @brief Запустить таймер в однократном режиме. + * При достижении значения CMP сигнал на выводе Output сменит свое состояние. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Period Период ШИМ сигнала. Число от 0 до 65535. + * @param Compare Значение при достижении которого сигнал на выводе Output сменит свое состояние. + * Число от 0 до 65534. Данное число всегда должно быть меньше значения Period. + */ +void HAL_Timer16_StartSetOnes(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare) +{ + HAL_Timer16_Disable(htimer16); + htimer16->Instance->CFGR |= TIMER16_CFGR_WAVE_M; + HAL_Timer16_Enable(htimer16); + + if(Period > Compare) + { + HAL_Timer16_SetCMP(htimer16, Compare); + HAL_Timer16_SetARR(htimer16, Period); + } + + __HAL_TIMER16_START_SINGLE(htimer16); +} + +/** + * @brief Запустить timer16 в режиме энкодера. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Period Верхнее значение счета. + */ +void HAL_Timer16_Encoder_Start(Timer16_HandleTypeDef *htimer16, uint32_t Period) +{ + HAL_Timer16_Disable(htimer16); + HAL_Timer16_SetEncoderMode(htimer16, TIMER16_ENCODER_ENABLE); + + HAL_Timer16_Enable(htimer16); + + htimer16->Instance->ICR = TIMER16_ICR_ARROKCF_M | TIMER16_ICR_DOWNCF_M | TIMER16_ICR_UPCF_M; + HAL_Timer16_SetARR(htimer16, Period); + + __HAL_TIMER16_START_CONTINUOUS(htimer16); +} + +/** + * @brief Выключить таймер и режим энкодера. + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_Encoder_Stop(Timer16_HandleTypeDef *htimer16) +{ + HAL_Timer16_Disable(htimer16); + HAL_Timer16_SetEncoderMode(htimer16, TIMER16_ENCODER_DISABLE); +} + +/** + * @brief Выключить таймер. + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_Stop(Timer16_HandleTypeDef *htimer16) +{ + HAL_Timer16_Disable(htimer16); +} + +/** + * @brief Запустить таймер в продолжительном режиме с использованием прерываний. + * Используются прерывания успешной записи в регистр автозагрузки ARR (ARROK) + * и достижение верхнего значения (ARRM). + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Period Верхнее значение счета. + */ +void HAL_Timer16_Counter_Start_IT(Timer16_HandleTypeDef *htimer16, uint32_t Period) +{ + HAL_Timer16_Enable(htimer16); + + htimer16->Instance->ICR = TIMER16_ICR_ARROKCF_M | TIMER16_ICR_ARRMCF_M; + + HAL_Timer16_SetARR(htimer16, Period); + + htimer16->Instance->IER |= TIMER16_IER_ARROKIE_M | TIMER16_IER_ARRMIE_M; + + __HAL_TIMER16_START_CONTINUOUS(htimer16); +} + +/** + * @brief Запустить ШИМ с использованием прерываний. + * Используются следующие прерывания: + * - Обновление регистра автозагрузки успешно завершено (ARROK); + * - Обновление регистра сравнения успешно завершено (CMPOK); + * - Значение регистра счета CNT достигло значения регистра ARR (ARRM); + * - Значение регистра счета CNT достигло значения регистра CMP (CMPM); + * - На выбранном входе внешнего триггера возник достоверный фронт импульса. (EXTTRIG) + * Если триггер игнорируется, так как таймер уже запущен, то этот флаг не устанавливается. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Period Верхнее значение счета. + * @param Compare Значение при достижении которого сигнал на выводе Output сменит свое состояние. + * Число от 0 до 65534. Данное число всегда должно быть меньше значения Period. + */ +void HAL_Timer16_StartPWM_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare) +{ + + + HAL_Timer16_Disable(htimer16); + htimer16->Instance->CFGR &= ~TIMER16_CFGR_WAVE_M; + HAL_Timer16_Enable(htimer16); + + htimer16->Instance->ICR = TIMER16_ICR_ARROKCF_M | TIMER16_ICR_CMPOKCF_M | TIMER16_ICR_ARRMCF_M + | TIMER16_ICR_CMPMCF_M | TIMER16_ICR_EXTTRIGCF_M; + + + + if(Period > Compare) + { + HAL_Timer16_SetCMP(htimer16, Compare); + HAL_Timer16_SetARR(htimer16, Period); + } + + htimer16->Instance->IER |= TIMER16_IER_ARROKIE_M | TIMER16_IER_CMPOKIE_M + | TIMER16_IER_ARRMIE_M | TIMER16_IER_CMPMIE_M; + + if (htimer16->Trigger.ActiveEdge != TIMER16_TRIGGER_ACTIVEEDGE_SOFTWARE) + { + htimer16->Instance->IER |= TIMER16_IER_EXTTRIGIE_M; + } + + __HAL_TIMER16_START_CONTINUOUS(htimer16); + +} + +/** + * @brief Запустить таймер в одноимпульсном режиме с использованием прерываний. + * Используются следующие прерывания: + * - Обновление регистра автозагрузки успешно завершено (ARROK); + * - Обновление регистра сравнения успешно завершено (CMPOK); + * - Значение регистра счета CNT достигло значения регистра ARR (ARRM); + * - Значение регистра счета CNT достигло значения регистра CMP (CMPM); + * - На выбранном входе внешнего триггера возник достоверный фронт импульса. (EXTTRIG) + * Если триггер игнорируется, так как таймер уже запущен, то этот флаг не устанавливается. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Period Верхнее значение счета. + * @param Compare Значение при достижении которого сигнал на выводе Output сменит свое состояние. + * Число от 0 до 65534. Данное число всегда должно быть меньше значения Period. + */ +void HAL_Timer16_StartOneShot_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare) +{ + HAL_Timer16_Disable(htimer16); + htimer16->Instance->CFGR &= ~TIMER16_CFGR_WAVE_M; + HAL_Timer16_Enable(htimer16); + + htimer16->Instance->ICR = TIMER16_ICR_ARROKCF_M | TIMER16_ICR_CMPOKCF_M | TIMER16_ICR_ARRMCF_M + | TIMER16_ICR_CMPMCF_M | TIMER16_ICR_EXTTRIGCF_M; + + if(Period > Compare) + { + HAL_Timer16_SetCMP(htimer16, Compare); + HAL_Timer16_SetARR(htimer16, Period); + } + + htimer16->Instance->IER |= TIMER16_IER_ARROKIE_M | TIMER16_IER_CMPOKIE_M + | TIMER16_IER_ARRMIE_M | TIMER16_IER_CMPMIE_M; + + if (htimer16->Trigger.ActiveEdge != TIMER16_TRIGGER_ACTIVEEDGE_SOFTWARE) + { + htimer16->Instance->IER |= TIMER16_IER_EXTTRIGIE_M; + } + + __HAL_TIMER16_START_SINGLE(htimer16); +} + +/** + * @brief Запустить таймер в однократном режиме с использованием прерываний. + * Используются следующие прерывания: + * - Обновление регистра автозагрузки успешно завершено (ARROK); + * - Обновление регистра сравнения успешно завершено (CMPOK); + * - Значение регистра счета CNT достигло значения регистра ARR (ARRM); + * - Значение регистра счета CNT достигло значения регистра CMP (CMPM); + * - На выбранном входе внешнего триггера возник достоверный фронт импульса. (EXTTRIG) + * Если триггер игнорируется, так как таймер уже запущен, то этот флаг не устанавливается. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Period Верхнее значение счета. + * @param Compare Значение при достижении которого сигнал на выводе Output сменит свое состояние. + * Число от 0 до 65534. Данное число всегда должно быть меньше значения Period. + */ +void HAL_Timer16_StartSetOnes_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare) +{ + HAL_Timer16_Disable(htimer16); + htimer16->Instance->CFGR |= TIMER16_CFGR_WAVE_M; + HAL_Timer16_Enable(htimer16); + + htimer16->Instance->ICR = TIMER16_ICR_ARROKCF_M | TIMER16_ICR_CMPOKCF_M | TIMER16_ICR_ARRMCF_M + | TIMER16_ICR_CMPMCF_M | TIMER16_ICR_EXTTRIGCF_M; + + if(Period > Compare) + { + HAL_Timer16_SetCMP(htimer16, Compare); + HAL_Timer16_SetARR(htimer16, Period); + } + + htimer16->Instance->IER |= TIMER16_IER_ARROKIE_M | TIMER16_IER_CMPOKIE_M + | TIMER16_IER_ARRMIE_M | TIMER16_IER_CMPMIE_M; + + if (htimer16->Trigger.ActiveEdge != TIMER16_TRIGGER_ACTIVEEDGE_SOFTWARE) + { + htimer16->Instance->IER |= TIMER16_IER_EXTTRIGIE_M; + } + + __HAL_TIMER16_START_SINGLE(htimer16); +} + +/** + * @brief Запустить таймер в режиме энкодера с использованием прерываний. + * Используются следующие прерывания: + * - Изменение направления счетчика c вверх на вниз (DOWN); + * - Изменение направления счетчика с вниз на вверх (UP). + * + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param Period Верхнее значение счета. + */ +void HAL_Timer16_Encoder_Start_IT(Timer16_HandleTypeDef *htimer16, uint32_t Period) +{ + HAL_Timer16_Disable(htimer16); + HAL_Timer16_SetEncoderMode(htimer16, TIMER16_ENCODER_ENABLE); + + HAL_Timer16_Enable(htimer16); + + htimer16->Instance->ICR = TIMER16_ICR_ARROKCF_M | TIMER16_ICR_DOWNCF_M | TIMER16_ICR_UPCF_M; + + HAL_Timer16_SetARR(htimer16, Period); + + HAL_Timer16_Disable(htimer16); + htimer16->Instance->IER |= TIMER16_IER_DOWNIE_M | TIMER16_IER_UPIE_M; + + HAL_Timer16_Enable(htimer16); + __HAL_TIMER16_START_CONTINUOUS(htimer16); +} + +/** + * @brief Выключить таймер, режим энкодера и прерывания. + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_Encoder_Stop_IT(Timer16_HandleTypeDef *htimer16) +{ + HAL_Timer16_Disable(htimer16); + HAL_Timer16_SetEncoderMode(htimer16, TIMER16_ENCODER_DISABLE); + htimer16->Instance->IER &= ~(TIMER16_IER_DOWNIE_M | TIMER16_IER_UPIE_M); +} + +void HAL_Timer16_Stop_IT(Timer16_HandleTypeDef *htimer16) +{ + HAL_Timer16_Disable(htimer16); + + htimer16->Instance->IER &= ~(TIMER16_IER_ARROKIE_M | TIMER16_IER_CMPOKIE_M + | TIMER16_IER_ARRMIE_M | TIMER16_IER_CMPMIE_M); + + if (htimer16->Trigger.ActiveEdge != TIMER16_TRIGGER_ACTIVEEDGE_SOFTWARE) + { + htimer16->Instance->IER &= ~TIMER16_IER_EXTTRIGIE_M; + } + +} + +/** + * @brief Ожидать флаг триггера - EXTTRIG. + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_WaitTrigger(Timer16_HandleTypeDef *htimer16) +{ + while (!(htimer16->Instance->ISR & TIMER16_ISR_EXT_TRIG_M)); + HAL_Timer16_ClearInterruptFlag(htimer16, TIMER16_ICR_EXTTRIGCF_S); +} + +/** + * @brief Установить маску прерываний в регистр IER. + * @param htimer16 Указатель на структуру с настройками Timer16. + * @param InterruptMask Маска перываний. + */ +void HAL_Timer16_SetInterruptMask(Timer16_HandleTypeDef *htimer16, uint32_t InterruptMask) +{ + htimer16->Instance->IER = InterruptMask; +} + +/** + * @brief Разрешить прерывание DOWN. + * Используется в режиме энкодера для формирования прерывания при смене направления с вверх на вниз. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_SetInterruptDOWN(Timer16_HandleTypeDef *htimer16) +{ + uint32_t config = htimer16->Instance->IER; + config &= ~TIMER16_IER_DOWNIE_M; + config |= TIMER16_IER_DOWNIE_M; + htimer16->Instance->IER = config; +} + +/** + * @brief Разрешить прерывание UP. + * Используется в режиме энкодера для формирования прерывания при смене направления с вверх на вниз. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_SetInterruptUP(Timer16_HandleTypeDef *htimer16) +{ + uint32_t config = htimer16->Instance->IER; + config &= ~TIMER16_IER_UPIE_M; + config |= TIMER16_IER_UPIE_M; + htimer16->Instance->IER = config; +} + +/** + * @brief Разрешить прерывание ARROK. + * Используется для формирования прерывания при успешной записи в регистр ARR. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_SetInterruptARROK(Timer16_HandleTypeDef *htimer16) +{ + uint32_t config = htimer16->Instance->IER; + config &= ~TIMER16_IER_ARROKIE_M; + config |= TIMER16_IER_ARROKIE_M; + htimer16->Instance->IER = config; +} + +/** + * @brief Разрешить прерывание CMPOK. + * Используется для формирования прерывания при успешной записи в регистр CMP. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_SetInterruptCMPOK(Timer16_HandleTypeDef *htimer16) +{ + uint32_t config = htimer16->Instance->IER; + config &= ~TIMER16_IER_CMPOKIE_M; + config |= TIMER16_IER_CMPOKIE_M; + htimer16->Instance->IER = config; +} + +/** + * @brief Разрешить прерывание EXTTRIG. + * Используется для формирования прерывания при возникновении достоверного фронта импульса на выбранном входе внешнего триггера (EXTTRIG). + * Если триггер игнорируется, так как таймер уже запущен, то этот флаг не устанавливается. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_SetInterruptEXTTRIG(Timer16_HandleTypeDef *htimer16) +{ + uint32_t config = htimer16->Instance->IER; + config &= ~TIMER16_IER_EXTTRIGIE_M; + config |= TIMER16_IER_EXTTRIGIE_M; + htimer16->Instance->IER = config; +} + +/** + * @brief Разрешить прерывание ARRM. + * Используется для формирования прерывания при совпадении счетчика со значенеим ARR. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_SetInterruptARRM(Timer16_HandleTypeDef *htimer16) +{ + uint32_t config = htimer16->Instance->IER; + config &= ~TIMER16_IER_ARRMIE_M; + config |= TIMER16_IER_ARRMIE_M; + htimer16->Instance->IER = config; +} + +/** + * @brief Разрешить прерывание CMPM. + * Используется для формирования прерывания при совпадении счетчика со значенеим CMP. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +void HAL_Timer16_SetInterruptCMPM(Timer16_HandleTypeDef *htimer16) +{ + uint32_t config = htimer16->Instance->IER; + config &= ~TIMER16_IER_CMPMIE_M; + config |= TIMER16_IER_CMPMIE_M; + htimer16->Instance->IER = config; +} + + diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c new file mode 100644 index 0000000..f5b3fe0 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c @@ -0,0 +1,495 @@ +#include "mik32_hal_timer32.h" + +__attribute__((weak)) void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + + if (htimer32->Instance == TIMER32_0) + { + __HAL_PCC_TIMER32_0_CLK_ENABLE(); + } + + if (htimer32->Instance == TIMER32_1) + { + __HAL_PCC_TIMER32_1_CLK_ENABLE(); + if (htimer32->Clock.Source == TIMER32_SOURCE_TX_PAD) + { + GPIO_InitStruct.Pin = GPIO_PIN_4; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + } + + if (htimer32->Instance == TIMER32_2) + { + __HAL_PCC_TIMER32_2_CLK_ENABLE(); + if (htimer32->Clock.Source == TIMER32_SOURCE_TX_PAD) + { + GPIO_InitStruct.Pin = GPIO_PIN_4; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + } + } +} + +__attribute__((weak)) void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + if (timerChannel->TimerInstance == TIMER32_1) + { + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + + } + + if (timerChannel->TimerInstance == TIMER32_2) + { + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + } + +} + +HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer) +{ + if ((timer->Instance != TIMER32_0) && (timer->Instance != TIMER32_1) && (timer->Instance != TIMER32_2)) + { + return HAL_ERROR; + } + + HAL_TIMER32_MspInit(timer); + + HAL_Timer32_Top_Set(timer, timer->Top); + HAL_Timer32_Prescaler_Set(timer, timer->Clock.Prescaler); + HAL_Timer32_CountMode_Set(timer, timer->CountMode); + HAL_Timer32_Source_Set(timer, timer->Clock.Source); + HAL_Timer32_InterruptFlags_Clear(timer); + HAL_Timer32_State_Set(timer, timer->State); + HAL_Timer32_InterruptMask_Set(timer, 0); + + return HAL_OK; +} + +void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state) +{ + timer->State = state; + if (state == TIMER32_STATE_DISABLE) + { + timer->Instance->ENABLE &= ~TIMER32_ENABLE_TIM_EN_M; + } + else + { + timer->Instance->ENABLE |= TIMER32_ENABLE_TIM_EN_M; + } +} + +void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top) +{ + timer->Top = top; + timer->Instance->TOP = top; +} + +void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler) +{ + timer->Clock.Prescaler = prescaler; + timer->Instance->PRESCALER = prescaler; +} + +void HAL_Timer32_Source_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_SourceTypeDef source) +{ + timer->Clock.Source = source; + + uint32_t timer_cfg_mux_tim32_s = 0; + switch ((uint32_t)timer->Instance) + { + case (uint32_t)TIMER32_0: + timer_cfg_mux_tim32_s = MUX_TIM32_0; + break; + case (uint32_t)TIMER32_1: + timer_cfg_mux_tim32_s = MUX_TIM32_1; + break; + case (uint32_t)TIMER32_2: + timer_cfg_mux_tim32_s = MUX_TIM32_2; + break; + + default: + break; + } + + uint32_t timer_cfg_reg = PM->TIMER_CFG & (~PM_TIMER_CFG_MUX_TIMER_M(timer_cfg_mux_tim32_s)); + uint32_t timer_control_reg = timer->Instance->CONTROL & (~TIMER32_CONTROL_CLOCK_M); + + /* В начале настройки переключается на hclk */ + timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_PRESCALER_M; + + switch (source) + { + // case TIMER32_SOURCE_PRESCALER: + // timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_PRESCALER_M; + // break; + case TIMER32_SOURCE_TIM1_SYS_CLK: + + timer_cfg_reg |= TIMER32_TIM1_SYS_CLK << timer_cfg_mux_tim32_s; + PM->TIMER_CFG = timer_cfg_reg; + timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM1_M; + break; + case TIMER32_SOURCE_TIM1_HCLK: + timer_cfg_reg |= TIMER32_TIM1_HCLK << timer_cfg_mux_tim32_s; + PM->TIMER_CFG = timer_cfg_reg; + timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM1_M; + break; + case TIMER32_SOURCE_TIM2_OSC32K: + timer_cfg_reg |= TIMER32_TIM2_OSC32K << timer_cfg_mux_tim32_s; + PM->TIMER_CFG = timer_cfg_reg; + timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM2_M; + break; + case TIMER32_SOURCE_TIM2_LSI32K: + timer_cfg_reg |= TIMER32_TIM2_LSI32K << timer_cfg_mux_tim32_s; + PM->TIMER_CFG = timer_cfg_reg; + timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM2_M; + break; + case TIMER32_SOURCE_TX_PAD: + timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TX_PIN_M; + break; + + default: + break; + } +} + +void HAL_Timer32_InterruptMask_Set(TIMER32_HandleTypeDef *timer, uint32_t intMask) +{ + timer->InterruptMask |= intMask; + timer->Instance->INT_MASK |= intMask; +} + +void HAL_Timer32_InterruptMask_Clear(TIMER32_HandleTypeDef *timer, uint32_t intMask) +{ + timer->InterruptMask &= ~intMask; + timer->Instance->INT_MASK &= ~intMask; +} + +void HAL_Timer32_CountMode_Set(TIMER32_HandleTypeDef *timer, uint8_t countMode) +{ + timer->CountMode = countMode; + + uint32_t timer32_control_temp = timer->Instance->CONTROL; + timer32_control_temp &= ~TIMER32_CONTROL_MODE_M; + timer32_control_temp |= countMode << TIMER32_CONTROL_MODE_S; + timer->Instance->CONTROL = timer32_control_temp; +} + +void HAL_Timer32_InterruptFlags_ClearMask(TIMER32_HandleTypeDef *timer, uint32_t clearMask) +{ + timer->Instance->INT_CLEAR = clearMask; +} + +HAL_StatusTypeDef HAL_Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + if (timerChannel->TimerInstance == TIMER32_0) + { + return HAL_ERROR; + } + + HAL_TIMER32_Channel_MspInit(timerChannel); + + timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]); + + HAL_Timer32_Channel_PWM_Invert_Set(timerChannel, timerChannel->PWM_Invert); + HAL_Timer32_Channel_Mode_Set(timerChannel, timerChannel->Mode); + HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, timerChannel->CaptureEdge); + HAL_Timer32_Channel_OCR_Set(timerChannel, timerChannel->OCR); + HAL_Timer32_Channel_ICR_Clear(timerChannel); + HAL_Timer32_Channel_Noise_Set(timerChannel, timerChannel->Noise); + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_Timer32_Channel_DeInit(TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + if (timerChannel->TimerInstance == TIMER32_0) + { + return HAL_ERROR; + } + + HAL_Timer32_Channel_Disable(timerChannel); + HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, 0); + HAL_Timer32_Channel_ICR_Clear(timerChannel); + HAL_Timer32_Channel_Mode_Set(timerChannel, 0); + HAL_Timer32_Channel_Noise_Set(timerChannel, 0); + HAL_Timer32_Channel_OCR_Set(timerChannel, 0); + HAL_Timer32_Channel_PWM_Invert_Set(timerChannel, 0); + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_Timer32_Channel_Enable(TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + if (timerChannel->TimerInstance == TIMER32_0) + { + return HAL_ERROR; + } + + timerChannel->State = TIMER32_STATE_ENABLE; + timerChannel->Instance->CNTRL |= TIMER32_CH_CNTRL_ENABLE_M; + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_Timer32_Channel_Disable(TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + if (timerChannel->TimerInstance == TIMER32_0) + { + return HAL_ERROR; + } + + timerChannel->State = TIMER32_STATE_DISABLE; + timerChannel->Instance->CNTRL &= ~TIMER32_CH_CNTRL_ENABLE_M; + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_Timer32_Channel_PWM_Invert_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_PWMInvertTypeDef PWM_Invert) +{ + if (timerChannel->TimerInstance == TIMER32_0) + { + return HAL_ERROR; + } + + timerChannel->PWM_Invert = PWM_Invert; + + uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_INVERTED_PWM_M); + timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (PWM_Invert << TIMER32_CH_CNTRL_INVERTED_PWM_S); + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_Timer32_Channel_Mode_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_ModeTypeDef mode) +{ + if (timerChannel->TimerInstance == TIMER32_0) + { + return HAL_ERROR; + } + + timerChannel->Mode = mode; + + uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_MODE_M); + timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (mode << TIMER32_CH_CNTRL_MODE_S); + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_Timer32_Channel_CaptureEdge_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef captureEdge) +{ + if (timerChannel->TimerInstance == TIMER32_0) + { + return HAL_ERROR; + } + + timerChannel->CaptureEdge = captureEdge; + + uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_CAPTURE_EDGE_M); + timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (captureEdge << TIMER32_CH_CNTRL_CAPTURE_EDGE_S); + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_Timer32_Channel_OCR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t OCR) +{ + if (timerChannel->TimerInstance == TIMER32_0) + { + return HAL_ERROR; + } + + timerChannel->OCR = OCR; + timerChannel->Instance->OCR = OCR; + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t ICR) +{ + if (timerChannel->TimerInstance == TIMER32_0) + { + return HAL_ERROR; + } + + timerChannel->Instance->ICR = ICR; + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Clear(TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + if (timerChannel->TimerInstance == TIMER32_0) + { + return HAL_ERROR; + } + + timerChannel->Instance->ICR = 0; + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_Timer32_Channel_Noise_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint8_t noise) +{ + if (timerChannel->TimerInstance == TIMER32_0) + { + return HAL_ERROR; + } + + timerChannel->Noise = noise; + + uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_NOISE_M); + timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (noise << TIMER32_CH_CNTRL_NOISE_S); + + return HAL_OK; +} + +void HAL_Timer32_Start(TIMER32_HandleTypeDef *timer) +{ + timer->State = TIMER32_STATE_ENABLE; + timer->Instance->ENABLE |= TIMER32_ENABLE_TIM_EN_M; +} + +void HAL_Timer32_Stop(TIMER32_HandleTypeDef *timer) +{ + timer->State = TIMER32_STATE_DISABLE; + timer->Instance->ENABLE &= ~TIMER32_ENABLE_TIM_EN_M; +} + +void HAL_Timer32_Base_Start_IT(TIMER32_HandleTypeDef *timer) +{ + /* Включить прерывание по переполнению */ + HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_OVERFLOW_M); + + HAL_Timer32_Start(timer); +} + +void HAL_Timer32_Base_Stop_IT(TIMER32_HandleTypeDef *timer) +{ + /* Включить прерывание по переполнению */ + HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_OVERFLOW_M); + + HAL_Timer32_Stop(timer); +} + +HAL_StatusTypeDef HAL_Timer32_PWM_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + if (timer->Instance == TIMER32_0) + { + return HAL_ERROR; + } + + if (timerChannel->Mode != TIMER32_CHANNEL_MODE_PWM) + { + return HAL_ERROR; + } + + /* Включить прерывание по переполнению */ + HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_OVERFLOW_M); + /* Включить канал */ + HAL_Timer32_Channel_Enable(timerChannel); + /* Запустить счет */ + HAL_Timer32_Start(timer); + + return HAL_OK; +} + +void HAL_Timer32_PWM_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + /* Включить прерывание по переполнению */ + HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_OVERFLOW_M); + /* Включить канал */ + HAL_Timer32_Channel_Disable(timerChannel); + /* Запустить счет */ + HAL_Timer32_Stop(timer); +} + +HAL_StatusTypeDef HAL_Timer32_Compare_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + if (timer->Instance == TIMER32_0) + { + return HAL_ERROR; + } + + if (timerChannel->Mode != TIMER32_CHANNEL_MODE_COMPARE) + { + return HAL_ERROR; + } + + /* Включить прерывание по переполнению */ + HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_OC_M(timerChannel->ChannelIndex)); + /* Включить канал */ + HAL_Timer32_Channel_Enable(timerChannel); + /* Запустить счет */ + HAL_Timer32_Start(timer); + + return HAL_OK; +} + +void HAL_Timer32_Compare_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + /* Включить прерывание по переполнению */ + HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_OC_M(timerChannel->ChannelIndex)); + /* Включить канал */ + HAL_Timer32_Channel_Disable(timerChannel); + /* Запустить счет */ + HAL_Timer32_Stop(timer); +} + +HAL_StatusTypeDef HAL_Timer32_Capture_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + if (timer->Instance == TIMER32_0) + { + return HAL_ERROR; + } + + if (timerChannel->Mode != TIMER32_CHANNEL_MODE_CAPTURE) + { + return HAL_ERROR; + } + + /* Включить прерывание по переполнению */ + HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_IC_M(timerChannel->ChannelIndex)); + /* Включить канал */ + HAL_Timer32_Channel_Enable(timerChannel); + /* Запустить счет */ + HAL_Timer32_Start(timer); + + return HAL_OK; +} + +void HAL_Timer32_Capture_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel) +{ + /* Включить прерывание по переполнению */ + HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_IC_M(timerChannel->ChannelIndex)); + /* Включить канал */ + HAL_Timer32_Channel_Disable(timerChannel); + /* Запустить счет */ + HAL_Timer32_Stop(timer); +} + +void HAL_Timer32_Start_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask) +{ + /* Включить прерывание по переполнению */ + HAL_Timer32_InterruptMask_Set(timer, intMask); + /* Запустить счет */ + HAL_Timer32_Start(timer); +} + +void HAL_Timer32_Stop_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask) +{ + /* Включить прерывание по переполнению */ + HAL_Timer32_InterruptMask_Clear(timer, intMask); + /* Запустить счет */ + HAL_Timer32_Stop(timer); +} \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_tsens.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_tsens.c new file mode 100644 index 0000000..ebe4705 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_tsens.c @@ -0,0 +1,364 @@ +#ifndef MIK32V0 +#include "mik32_hal_tsens.h" + +/** + * @brief Функция включения тактирования аналогового блока (включающего термосенсор). + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + */ +__attribute__((weak)) void HAL_TSENS_MspInit(TSENS_HandleTypeDef *htsens) +{ + __HAL_PCC_ANALOG_REGS_CLK_ENABLE(); +} + + +/** + * @brief Функция начальной инициализации термосенсора. + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + * @return Статус HAL. + */ +HAL_StatusTypeDef HAL_TSENS_Init(TSENS_HandleTypeDef *htsens) +{ + HAL_StatusTypeDef errorCode = HAL_OK; + HAL_TSENS_MspInit(htsens); + /* Включение, тактирование температурного сенсора, отключение режима сброса. */ + ANALOG_REG->TSENS_CFG = (1<Clock)) != HAL_OK) + { + return errorCode; + } + + // Подбор делителя для заданной частоты термосенсора. + if ((errorCode = HAL_TSENS_Clock(htsens, htsens->Frequency)) != HAL_OK) + { + return errorCode; + } + + return errorCode; +} + + +/** + * @brief Функция установки источника тактирования термосенсора. + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + * @param clk_source источник тактирования термосенсора. + * - @ref HAL_TSENS_SYS_CLK - системная тактовая частота + * - @ref HAL_TSENS_HCLK - частота шины АНВ + * - @ref HAL_TSENS_OSC32M - внешний генератор 32МГц + * - @ref HAL_TSENS_HSI32M - внутренний генератор 32МГц + * - @ref HAL_TSENS_OSC32K - внешний генератор 32кГц + * - @ref HAL_TSENS_LSI32K - внутренний генератор 32кГц + * @return Статус HAL. + * HAL_OK, если источник тактирования установлен успешно + * HAL_ERROR, если входной параметр некорректен. + */ +HAL_StatusTypeDef HAL_TSENS_ClockSource(TSENS_HandleTypeDef *htsens, HAL_TSENS_ClockTypeDef clk_source) +{ + switch (clk_source) + { + case HAL_TSENS_SYS_CLK: + case HAL_TSENS_HCLK: + case HAL_TSENS_OSC32M: + case HAL_TSENS_HSI32M: + case HAL_TSENS_OSC32K: + case HAL_TSENS_LSI32K: + break; + default: + return HAL_ERROR; + } + + htsens->Clock = clk_source; + ANALOG_REG->TSENS_CFG = (ANALOG_REG->TSENS_CFG & (~TSENS_CFG_CLK_MUX_M)) | (clk_source << TSENS_CFG_CLK_MUX_S); + return HAL_OK; +} + +/** + * @brief Функция установки делителя частоты для термосенсора. + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + * @param clk_div делитель частоты термосенсора. + * Этот параметр может принимать значения от 0 до 1023. + * @return Статус HAL. + * HAL_OK, если делитель частоты установлен успешно; + * HAL_ERROR, если делитель частоты слишком мал или слишком велик для получения частоты термосенсора 0 - 100 кГц. + */ +HAL_StatusTypeDef HAL_TSENS_ClockDivider(TSENS_HandleTypeDef *htsens, uint16_t clk_div) +{ + if (clk_div >= 1024) return HAL_ERROR; + + clk_div &= 0x3FF; + uint32_t divider; + uint32_t systemFreq = HAL_PCC_GetSysClockFreq(); + uint32_t tsensFreq = 0; + switch (htsens->Clock) + { + case HAL_TSENS_SYS_CLK: + divider = (clk_div + 1) << 1; + tsensFreq = systemFreq / divider; + if ((tsensFreq > 100000UL)||(tsensFreq == 0)) return HAL_ERROR; + break; + case HAL_TSENS_HCLK: + divider = ((uint32_t)PM->DIV_AHB + 1) * ((clk_div + 1) << 1); + tsensFreq = systemFreq / divider; + if ((tsensFreq > 100000UL)||(tsensFreq == 0)) return HAL_ERROR; + break; + case HAL_TSENS_OSC32M: + if (clk_div < (OSC_SYSTEM_VALUE/200000 - 1)) return HAL_ERROR; + tsensFreq = OSC_SYSTEM_VALUE/((1 + clk_div) << 1); + break; + case HAL_TSENS_HSI32M: + if (clk_div < (HSI_VALUE/200000 - 1)) return HAL_ERROR; + tsensFreq = HSI_VALUE/((1 + clk_div) << 1); + break; + case HAL_TSENS_OSC32K: + case HAL_TSENS_LSI32K: + tsensFreq = OSC_CLOCK_VALUE/((1 + clk_div) << 1); + break; + default: + return HAL_ERROR; + } + ANALOG_REG->TSENS_CFG = (ANALOG_REG->TSENS_CFG & (~TSENS_CFG_DIV_M)) | (clk_div << TSENS_CFG_DIV_S); + htsens->Frequency = tsensFreq; + return HAL_OK; +} + +/** + * @brief Функция установки тактовой частоты для термосенсора. + * + * Функция подбирает делитель для получения наиболее близкой частоты термосенсора к заданной. + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + * @param f_enter тактовая частота термосенсора. + * @return Статус HAL. + * HAL_OK, если частота установлена успешно + * HAL_ERROR, если введенная частота не попадает в область допустимых значений частот 0 - 100 кГц или если невозможно подобрать делитель. + */ +HAL_StatusTypeDef HAL_TSENS_Clock(TSENS_HandleTypeDef *htsens, uint32_t f_enter) +{ + if ((f_enter > 100000UL)||(f_enter == 0)) return HAL_ERROR; + uint32_t f_real; + uint32_t systemFreq = HAL_PCC_GetSysClockFreq(); + switch (htsens->Clock) + { + case HAL_TSENS_SYS_CLK: + f_real = systemFreq; /* Примечание: надо проверить какой источник и входимость в диапазон */ + break; + case HAL_TSENS_HCLK: + f_real = systemFreq / (PM->DIV_AHB + 1); /* Примечание: надо проверить какой источник и входимость в диапазон */ + break; + case HAL_TSENS_OSC32M: + f_real = OSC_SYSTEM_VALUE; + break; + case HAL_TSENS_HSI32M: + f_real = HSI_VALUE; + break; + case HAL_TSENS_OSC32K: + f_real = OSC_CLOCK_VALUE; + break; + case HAL_TSENS_LSI32K: + f_real = LSI_VALUE; + break; + default: + return HAL_ERROR; + } + + uint32_t divider = (f_real / f_enter) >> 1; + if (divider == 0) return HAL_ERROR; + + uint32_t pre_result = f_real / (divider << 1); + while ((pre_result > 100000) && (divider <= 0x400)) + { + divider += 1; + if (divider > 0x400) + { + return HAL_ERROR; + } + pre_result = f_real / (divider << 1); + } + + divider -= 1; + + /* Запись данных */ + ANALOG_REG->TSENS_CFG = (ANALOG_REG->TSENS_CFG & (~TSENS_CFG_DIV_M)) | (divider<Frequency = f_real / ((1 + divider) << 1); + return HAL_OK; +} + +/** + * @brief Функция установки сырого значения нижнего порога температуры. + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + * @param low_tres сырое значение нижнего порога температуры. + * Этот параметр может принимать значение от 225 до 603. + * @return Статус HAL. + * HAL_OK, если нижнее пороговое значение установлено успешно; + * HAL_ERROR, если значение low_tres не попадает в диапазон [225, 603]. + */ +HAL_StatusTypeDef HAL_TSENS_SetLowThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t low_tres) +{ + if (low_tres > 603 || low_tres < 225) + { + return HAL_ERROR; + } + + low_tres &= 0x3FF; + htsens->Instance->TSENS_THRESHOLD = (htsens->Instance->TSENS_THRESHOLD & (~TSENS_TRESHOLD_LOW_M)) | ((uint32_t)low_tres << TSENS_TRESHOLD_LOW_S); + + return HAL_OK; +} + +/** + * @brief Функция установки сырого значения верхнего порога температуры. + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + * @param hi_tres сырое значение верхнего порога температуры. + * Этот параметр может принимать значение от 225 до 603. + * @return Статус HAL. + * HAL_OK, если верхнее пороговое значение установлено успешно; + * HAL_ERROR, если значение hi_tres не попадает в диапазон [225, 603]. + */ +HAL_StatusTypeDef HAL_TSENS_SetHiThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t hi_tres) +{ + if (hi_tres > 603 || hi_tres < 225) + { + return HAL_ERROR; + } + hi_tres &= 0x3FF; + htsens->Instance->TSENS_THRESHOLD = (htsens->Instance->TSENS_THRESHOLD & (~TSENS_TRESHOLD_HI_M)) | ((uint32_t)hi_tres << TSENS_TRESHOLD_HI_S); + + return HAL_OK; +} + +/** + * @brief Функция установки значения нижнего порога температуры. + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + * @param low_temp_border значение нижнего порога температуры в градусах Цельсия. + * Этот параметр может принимать значение от -40 до 125. + * @return Статус HAL. + * HAL_OK, если нижнее пороговое значение установлено успешно; + * HAL_ERROR, если рассчитанное значение нижнего порога не попадает в диапазон [225, 603]. + */ +HAL_StatusTypeDef HAL_TSENS_SetLowThreshold(TSENS_HandleTypeDef *htsens, int low_temp_border) +{ + return HAL_TSENS_SetLowThresholdRaw(htsens, TSENS_CELSIUS_TO_VALUE(low_temp_border)); +} + +/** + * @brief Функция установки значения верхнего порога температуры. + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + * @param hi_temp_border значение верхнего порога температуры в градусах Цельсия. + * Этот параметр может принимать значение от -40 до 125. + * @return Статус HAL. + * HAL_OK, если верхнее пороговое значение установлено успешно; + * HAL_ERROR, если рассчитанное значение верхнего порога не попадает в диапазон [225, 603]. + */ +HAL_StatusTypeDef HAL_TSENS_SetHiThreshold(TSENS_HandleTypeDef *htsens, int hi_temp_border) +{ + return HAL_TSENS_SetHiThresholdRaw(htsens, TSENS_CELSIUS_TO_VALUE(hi_temp_border)); +} + +/** + * @brief Функция чтения и перевода в градусы Цельсия данных термосенсора. + * + * Функция используется для получения значения температуры в непрерывном режиме измерения (Continuous). + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + * @return температура в градусах Цельсия, увеличенная в 100 раз. + */ +uint32_t HAL_TSENS_GetTemperature(TSENS_HandleTypeDef *htsens) +{ + return TSENS_VALUE_TO_CELSIUS(__HAL_TSENS_READ_MEASUREMENT(htsens)); +} + +/** + * @brief Запустить непрерывное измерение температуры. + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + */ +void HAL_TSENS_ContinuousStart(TSENS_HandleTypeDef *htsens) +{ + __HAL_TSENS_RELEASE_RESET(htsens); + __HAL_TSENS_CONTINUOUS_START(htsens); +} + +/** + * @brief Запустить одиночное измерение температуры. + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + * @param timeout значение таймаута. Если значение 0, то ожидание флага конца преобразования никогда не прервется. + * @return Структура со статусом HAL и измеренным значением температуры. + * @ref TSENS_ValueTypeDef.statusHAL статус HAL + * @ref TSENS_ValueTypeDef.value значение температуры в градусах Цельсия. Значение в 100 раз больше. + */ +TSENS_ValueTypeDef HAL_TSENS_SingleStart(TSENS_HandleTypeDef *htsens, uint32_t timeout) +{ + uint32_t timeoutCounter = timeout; + + __HAL_TSENS_RELEASE_RESET(htsens); + __HAL_TSENS_SINGLE_START(htsens); + while (!__HAL_TSENS_GET_EOC(htsens)) + { + if ((timeoutCounter-- == 0) && (timeout != 0)) + { + return (TSENS_ValueTypeDef) {.statusHAL = HAL_TIMEOUT, .value = 0}; + } + } + + uint32_t rawValue = __HAL_TSENS_READ_MEASUREMENT(htsens); + + return (TSENS_ValueTypeDef) {.statusHAL = HAL_OK, .value = TSENS_VALUE_TO_CELSIUS(rawValue)}; +} + +/** + * @brief Запустить непрерывное измерение температуры с использованием прерываний. + * + * Включаются все прерывания датчика температуры (окончание преобразование, выход измеренного значения температуры за пороговые значения). + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + */ +void HAL_TSENS_ContinuousStart_IT(TSENS_HandleTypeDef *htsens) +{ + __HAL_TSENS_IRQ_CLEAR(htsens, TSENS_CLEAR_IRQ_LOW_CLEAR_M | TSENS_CLEAR_IRQ_HI_CLEAR_M | TSENS_CLEAR_IRQ_EOC_CLEAR_M); + __HAL_TSENS_IRQ_ENABLE(htsens, TSENS_IRQ_LOW_MASK_M | TSENS_IRQ_HI_MASK_M | TSENS_IRQ_EOC_MASK_M); + __HAL_TSENS_RELEASE_RESET(htsens); + __HAL_TSENS_CONTINUOUS_START(htsens); +} + +/** + * @brief Запустить одиночное измерение температуры с использованием прерываний. + * + * Включаются все прерывания датчика температуры (окончание преобразование, выход измеренного значения температуры за пороговые значения). + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + */ +void HAL_TSENS_SingleStart_IT(TSENS_HandleTypeDef *htsens) +{ + __HAL_TSENS_IRQ_CLEAR(htsens, TSENS_CLEAR_IRQ_LOW_CLEAR_M | TSENS_CLEAR_IRQ_HI_CLEAR_M | TSENS_CLEAR_IRQ_EOC_CLEAR_M); + __HAL_TSENS_IRQ_ENABLE(htsens, TSENS_IRQ_LOW_MASK_M | TSENS_IRQ_HI_MASK_M | TSENS_IRQ_EOC_MASK_M); + __HAL_TSENS_RELEASE_RESET(htsens); + __HAL_TSENS_SINGLE_START(htsens); +} + +/** + * @brief Прервать измерение температуры и отключить прерывания. + * + * Функция останавливает измерения, выключает все прерывания термосенсора и очищает флаги прерываний. + * @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля TSENS. + */ +void HAL_TSENS_Stop_IT(TSENS_HandleTypeDef *htsens) +{ + __HAL_TSENS_FORCE_RESET(htsens); + __HAL_TSENS_IRQ_DISABLE(htsens, TSENS_IRQ_LOW_MASK_M | TSENS_IRQ_HI_MASK_M | TSENS_IRQ_EOC_MASK_M); + __HAL_TSENS_IRQ_CLEAR(htsens, TSENS_CLEAR_IRQ_LOW_CLEAR_M | TSENS_CLEAR_IRQ_HI_CLEAR_M | TSENS_CLEAR_IRQ_EOC_CLEAR_M); +} + +#endif // MIK32V0 \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_wdt.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_wdt.c new file mode 100644 index 0000000..7c39985 --- /dev/null +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_wdt.c @@ -0,0 +1,203 @@ +#include "mik32_hal_wdt.h" + +uint16_t TimeOut = 20; +uint16_t WDT_prescale[] = {1, 2, 4, 16, 64, 256, 1024, 4096}; + +/** + * @brief Инициализация WDT MSP. + * @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля WDT. + * + * информацию о конфигурации для модуля WDT. + */ +__attribute__((weak)) void HAL_RTC_MspInit(WDT_HandleTypeDef *hwdt) +{ + __HAL_PCC_WDT_CLK_ENABLE(); +} + +/** + * @brief Расчет начального значения отсчета таймера соответствующее времени до перезагрузки @ref WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.init.ReloadMs". + * @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля WDT. + * @return Структура с рассчитанным начальным значением @ref WDT_ClockTypeDef.tick и код подобранного делителя частоты @ref WDT_ClockTypeDef.divIndex. + * Значение 0 в @ref WDT_ClockTypeDef.tick означает ошибку при расчете. + */ +WDT_ClockTypeDef HAL_WDT_MillisInClock(WDT_HandleTypeDef *hwdt) +{ + uint32_t wdtClock = 0; + + if (hwdt->Init.Clock < HAL_WDT_OSC32K) + { + if (hwdt->Init.ReloadMs > WDT_MAX_VALUE_CLOCK32M) + { + return (WDT_ClockTypeDef){.tick = 0, .divIndex = 0}; + } + + wdtClock = WDT_CLOCK32M_VALUE; + } + else + { + if (hwdt->Init.ReloadMs > WDT_MAX_VALUE_CLOCK32K) + { + return (WDT_ClockTypeDef){.tick = 0, .divIndex = 0}; + } + + wdtClock = WDT_CLOCK32K_VALUE; + } + + uint32_t tick = 0; + int divIndex = 0; + int countDiv = sizeof(WDT_prescale) / sizeof(*WDT_prescale); + for (divIndex = 0; divIndex < countDiv; divIndex++) + { + tick = ((wdtClock / (WDT_prescale[divIndex])) * hwdt->Init.ReloadMs) / 1000; + + if ((tick <= 4095) && (tick != 0)) + { + tick = 4095 - tick; + break; + } + else if (divIndex == (countDiv - 1)) + { + return (WDT_ClockTypeDef){.tick = 0, .divIndex = 0}; /* Не удалось подобрать делитель для заданного времени отсчета WDT */ + } + } + + return (WDT_ClockTypeDef){.tick = tick, .divIndex = divIndex}; +} + +/** + * @brief Инициализировать WDT в соответствии с настройками в @ref WDT_HandleTypeDef. + * + * Функция включает тактирование таймера, задает источник тактирование сторожевого таймера WDT, настраивает делитель частоты + * таймера и начальное значение отсчета в соответствии с временем указанным в @ref WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.init.ReloadMs". + * @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля WDT. + * @return Статус HAL. + */ +HAL_StatusTypeDef HAL_WDT_Init(WDT_HandleTypeDef *hwdt, uint32_t timeout) +{ + if (hwdt->Instance != WDT) + { + return HAL_ERROR; + } + + HAL_RTC_MspInit(hwdt); + + + if (HAL_WDT_Stop(hwdt, timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + PM->WDT_CLK_MUX = hwdt->Init.Clock; + + WDT_ClockTypeDef wdtClock = HAL_WDT_MillisInClock(hwdt); + + if (wdtClock.tick == 0) + { + return HAL_ERROR; + } + + uint32_t conValue = (wdtClock.divIndex << WDT_CON_PRESCALE_S) | WDT_CON_PRELOAD(wdtClock.tick); + hwdt->Instance->KEY = WDT_KEY_UNLOCK; + hwdt->Instance->CON = conValue; + + return HAL_OK; +} + +/** + * @brief Перезагрузка значения сторожевого таймера. + * @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля WDT. + * @param timeout продолжительность тайм-аута. + * @return Статус HAL. + */ +HAL_StatusTypeDef HAL_WDT_Refresh(WDT_HandleTypeDef *hwdt, uint32_t timeout) +{ + hwdt->Instance->KEY = WDT_KEY_UNLOCK; + hwdt->Instance->KEY = WDT_KEY_START; + + while (timeout--) + { + if (!(hwdt->Instance->STA & WDT_STA_LOADING_M)) + { + return HAL_OK; + } + } + + return HAL_TIMEOUT; +} + + +/** + * @brief Запустить таймер WDT. + * @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля WDT. + * @param timeout продолжительность тайм-аута. + * @return Статус HAL. + */ +HAL_StatusTypeDef HAL_WDT_Start(WDT_HandleTypeDef *hwdt, uint32_t timeout) +{ + hwdt->Instance->KEY = WDT_KEY_UNLOCK; + hwdt->Instance->KEY = WDT_KEY_START; + + while (timeout--) + { + if (hwdt->Instance->STA & WDT_STA_ENABLED_M) + { + return HAL_OK; + } + } + + return HAL_TIMEOUT; +} + +/** + * @brief Остановить таймер. + * @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля WDT. + * @param timeout продолжительность тайм-аута. + * @return Статус HAL. + */ +HAL_StatusTypeDef HAL_WDT_Stop(WDT_HandleTypeDef *hwdt, uint32_t timeout) +{ + hwdt->Instance->KEY = WDT_KEY_UNLOCK; + hwdt->Instance->KEY = WDT_KEY_STOP; + + while (timeout--) + { + if (!(hwdt->Instance->STA & WDT_STA_ENABLED_M)) + { + return HAL_OK; + } + } + + return HAL_TIMEOUT; +} + +/** + * @brief Задать делитель частоты WDT. + * @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля WDT. + * @param prescale делитель частоты WDT. + */ +void HAL_WDT_SetPrescale(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale prescale) +{ + uint32_t conValue = (hwdt->Instance->CON & (~WDT_CON_PRESCALE_M)) | ((prescale << WDT_CON_PRESCALE_S) & WDT_CON_PRESCALE_M); + hwdt->Instance->KEY = WDT_KEY_UNLOCK; + hwdt->Instance->CON = conValue; +} + +/** + * @brief Задать начальное значение таймера при запуске или перезапуске. + * @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля WDT. + * @param preload начальное значение таймера при запуске или перезапуске. + */ +void HAL_WDT_SetPreload(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale preload) +{ + uint32_t conValue = (hwdt->Instance->CON & (~WDT_CON_PRELOAD_M)) | WDT_CON_PRELOAD(preload); + hwdt->Instance->KEY = WDT_KEY_UNLOCK; + hwdt->Instance->CON = conValue; +} \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Source/put here c files.txt b/cores/arduino/mik32/hal/peripherals/Source/put here c files.txt new file mode 100644 index 0000000..e69de29 diff --git a/cores/arduino/mik32/hal/utilities/Include/mik32_hal_spifi_w25.h b/cores/arduino/mik32/hal/utilities/Include/mik32_hal_spifi_w25.h new file mode 100644 index 0000000..3c3c923 --- /dev/null +++ b/cores/arduino/mik32/hal/utilities/Include/mik32_hal_spifi_w25.h @@ -0,0 +1,103 @@ +#ifndef MIK32_HAL_SPIFI_W25 +#define MIK32_HAL_SPIFI_W25 + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_def.h" +#include "mik32_hal_spifi.h" + +typedef enum __HAL_SPIFI_W25_SREGTypeDef +{ + W25_SREG1 = 1, + W25_SREG2 = 2, +} HAL_SPIFI_W25_SREGTypeDef; + +typedef struct __SPIFI_W25_ManufacturerDeviceIDTypeDef +{ + uint8_t Manufacturer; + + uint8_t Device; + +} W25_ManufacturerDeviceIDTypeDef; + +#define SPIFI_W25_SREG1_BUSY_S 0 +#define SPIFI_W25_SREG1_BUSY_M (1 << SPIFI_W25_SREG1_BUSY_S) +#define SPIFI_W25_SREG1_WRITE_ENABLE_S 1 +#define SPIFI_W25_SREG1_WRITE_ENABLE_M (1 << SPIFI_W25_SREG1_WRITE_ENABLE_S) +#define SPIFI_W25_SREG1_BLOCK_PROTECT_0_S 2 +#define SPIFI_W25_SREG1_BLOCK_PROTECT_0_M (1 << SPIFI_W25_SREG1_BLOCK_PROTECT_0_S) +#define SPIFI_W25_SREG1_BLOCK_PROTECT_1_S 3 +#define SPIFI_W25_SREG1_BLOCK_PROTECT_1_M (1 << SPIFI_W25_SREG1_BLOCK_PROTECT_1_S) +#define SPIFI_W25_SREG1_BLOCK_PROTECT_2_S 4 +#define SPIFI_W25_SREG1_BLOCK_PROTECT_2_M (1 << SPIFI_W25_SREG1_BLOCK_PROTECT_2_S) +#define SPIFI_W25_SREG1_TOP_BOTTOM_PROTECT_S 5 +#define SPIFI_W25_SREG1_TOP_BOTTOM_PROTECT_M (1 << SPIFI_W25_SREG1_TOP_BOTTOM_PROTECT_S) +#define SPIFI_W25_SREG1_SECTOR_PROTECT_S 6 +#define SPIFI_W25_SREG1_SECTOR_PROTECT_M (1 << SPIFI_W25_SREG1_SECTOR_PROTECT_S) +#define SPIFI_W25_SREG1_STATUS_REGISTER_PROTECT_0_S 7 +#define SPIFI_W25_SREG1_STATUS_REGISTER_PROTECT_0_M (1 << SPIFI_W25_SREG1_STATUS_REGISTER_PROTECT_0_S) + +#define SPIFI_W25_SREG2_STATUS_REGISTER_PROTECT_1_S 0 +#define SPIFI_W25_SREG2_STATUS_REGISTER_PROTECT_1_M (1 << SPIFI_W25_SREG2_STATUS_REGISTER_PROTECT_1_S) +#define SPIFI_W25_SREG2_QUAD_ENABLE_S 1 +#define SPIFI_W25_SREG2_QUAD_ENABLE_M (1 << SPIFI_W25_SREG2_QUAD_ENABLE_S) +#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_1_S 3 +#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_1_M (1 << SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_1_S) +#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_2_S 4 +#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_2_M (1 << SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_2_S) +#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_3_S 5 +#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_3_M (1 << SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_3_S) +#define SPIFI_W25_SREG2_COMPLEMENT_PROTECT_S 6 +#define SPIFI_W25_SREG2_COMPLEMENT_PROTECT_M (1 << SPIFI_W25_SREG2_COMPLEMENT_PROTECT_S) +#define SPIFI_W25_SREG2_SUSPEND_STATUS_S 7 +#define SPIFI_W25_SREG2_SUSPEND_STATUS_M (1 << SPIFI_W25_SREG2_SUSPEND_STATUS_S) + +void HAL_SPIFI_W25_WriteEnable(SPIFI_HandleTypeDef *spifi); + +uint8_t HAL_SPIFI_W25_ReadSREG(SPIFI_HandleTypeDef *spifi, HAL_SPIFI_W25_SREGTypeDef SREG); + +HAL_StatusTypeDef HAL_SPIFI_W25_WriteSREG(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2); + +void HAL_SPIFI_W25_WriteSREG_Volatile(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2); + +#include "xprintf.h" + +static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_W25_WaitBusy(SPIFI_HandleTypeDef *spifi, uint32_t timeout) +{ + while (timeout-- != 0) + { + if ((HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG1) & 1) == 0) + { + return HAL_OK; + } + } + return HAL_TIMEOUT; +} + +HAL_StatusTypeDef HAL_SPIFI_W25_WaitBusy_Polling(SPIFI_HandleTypeDef *spifi, uint32_t timeout); + +void HAL_SPIFI_W25_PageProgram(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes); + +void HAL_SPIFI_W25_SectorErase4K(SPIFI_HandleTypeDef *spifi, uint32_t address); + +void HAL_SPIFI_W25_ReadData(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes); + +W25_ManufacturerDeviceIDTypeDef HAL_SPIFI_W25_ReadManufacturerDeviceID(SPIFI_HandleTypeDef *spifi); + +void HAL_SPIFI_W25_PageProgram_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes); + +void HAL_SPIFI_W25_ReadData_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes); + +void HAL_SPIFI_W25_ReadData_Quad_IO(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes); + +HAL_StatusTypeDef HAL_SPIFI_W25_QuadEnable(SPIFI_HandleTypeDef *spifi); + +HAL_StatusTypeDef HAL_SPIFI_W25_QuadDisable(SPIFI_HandleTypeDef *spifi); + +#ifdef __cplusplus +} +#endif + +#endif // MIK32_HAL_W25 diff --git a/cores/arduino/mik32/hal/utilities/Include/mik32_hal_ssd1306.h b/cores/arduino/mik32/hal/utilities/Include/mik32_hal_ssd1306.h new file mode 100644 index 0000000..3523ff0 --- /dev/null +++ b/cores/arduino/mik32/hal/utilities/Include/mik32_hal_ssd1306.h @@ -0,0 +1,59 @@ +#ifndef MIK32_HAL_SSD130 +#define MIK32_HAL_SSD130 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SSD1306_128x64 +#define SSD1306_128x32 +#endif + +#define BRIGHTNESS_FULL 0xFF +#define BRIGHTNESS_HAL 0x7F + +#define START_PAGE 0 +#define END_PAGE 7 +#define START_COLUMN 0 +#define END_COLUMN 127 + +/* Десятые часов */ +#define START_COLUMN_TH 0 +#define END_COLUMN_TH 24 +/* Единицы часов */ +#define START_COLUMN_H 25 +#define END_COLUMN_H 49 + +/* Разделитель - двоеточие */ +#define START_COLUMN_COLON 50 +#define END_COLUMN_COLON 74 + +/* Десятые минут */ +#define START_COLUMN_TM 75 +#define END_COLUMN_TM 99 +/* Единицы минут */ +#define START_COLUMN_M 100 +#define END_COLUMN_M 124 + +#define SYMBOL_COLON 58 +#define SYMBOL_SMILE 13 + +#include +#include "mik32_hal_i2c.h" + +/* COM (СЛЕДУЮЩИЙ БАЙТ будет командой), DAT (СЛЕДУЮЩИЙ БАЙТ будет данными) и DATS (ВСЕ СЛЕДУЮЩИЕ БАЙТЫ будут данными) */ +#define DATS 0b01000000 +#define DAT 0b11000000 +#define COM 0b10000000 + + +HAL_StatusTypeDef HAL_SSD1306_Init(I2C_HandleTypeDef *hi2c, uint8_t brightness); +HAL_StatusTypeDef HAL_SSD1306_SetBorder(I2C_HandleTypeDef *hi2c, uint8_t start_col, uint8_t end_col, uint8_t start_page, uint8_t end_page); +HAL_StatusTypeDef HAL_SSD1306_CLR_SCR(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_SSD1306_Write(I2C_HandleTypeDef *hi2c, uint8_t symbol); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cores/arduino/mik32/hal/utilities/Include/put here h files.txt b/cores/arduino/mik32/hal/utilities/Include/put here h files.txt new file mode 100644 index 0000000..e69de29 diff --git a/cores/arduino/mik32/hal/utilities/Source/mik32_hal_spifi_w25.c b/cores/arduino/mik32/hal/utilities/Source/mik32_hal_spifi_w25.c new file mode 100644 index 0000000..5e4fa1b --- /dev/null +++ b/cores/arduino/mik32/hal/utilities/Source/mik32_hal_spifi_w25.c @@ -0,0 +1,257 @@ +#include "mik32_hal_spifi_w25.h" + +#define SPIFI_W25_WRITE_SREG_BUSY 10000 +#define SPIFI_W25_PROGRAM_BUSY 100000 + +typedef enum __HAL_SPIFI_W25_OPCodesTypeDef +{ + // Standard SPI Instructions + WRITE_ENABLE = 0x06, + VOLATILE_SR_WRITE_ENABLE = 0x50, + WRITE_DISABLE = 0x04, + READ_SREG1 = 0x05, + READ_SREG2 = 0x35, + WRITE_SREG = 0x01, + PAGE_PROGRAM = 0x02, + SECTOR_ERASE_4K = 0x20, + BLOCK_ERASE_32K = 0x52, + BLOCK_ERASE_64K = 0xD8, + CHIP_ERASE = 0x60, + ERASE_PROGRAM_SUSPEND = 0x75, + ERASE_PROGRAM_RESUME = 0x7A, + POWER_DOWN = 0xB9, + READ_DATA = 0x03, + FAST_READ = 0x0B, + RELEASE_POWERDOWN_ID = 0xAB, + MANUFACTURER_DEVICE_ID = 0x90, + JEDEC_ID = 0x9F, + READ_UNIQUE_ID = 0x4B, + READ_SFDP_REGISTERS = 0x5A, + ERASE_SECURITY_REGISTERS = 0x44, + PROGRAM_SECURITY_REGISTERS = 0x42, + READ_SECURITY_REGISTERS = 0x48, + ENABLE_QPI = 0x38, + ENABLE_RESET = 0x66, + RESET = 0x99, + + // Quad SPI Instructions + QUAD_PAGE_PROGRAM = 0x32, + FAST_READ_QUAD_OUTPUT = 0x6B, + FAST_READ_QUAD_IO = 0xEB, + WORD_READ_QUAD_IO = 0xE7, + OCTAL_WORD_READ_QUAD_IO = 0xE3, + SET_BURST_WITH_WRAP = 0x77, + MANUFACTURER_DEVICE_ID_BY_QUAD_IO = 0x94, +} HAL_SPIFI_W25_OPCodesTypeDef; + +#define HAL_SPIFI_W25_SREG2_BUSY 2 + +const uint32_t cmd_write_enable = + SPIFI_DIRECTION_INPUT | + SPIFI_CONFIG_CMD_INTLEN(0) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) | + SPIFI_CONFIG_CMD_OPCODE(WRITE_ENABLE); + +const uint32_t cmd_volatile_sr_write_enable = + SPIFI_DIRECTION_INPUT | + SPIFI_CONFIG_CMD_INTLEN(0) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) | + SPIFI_CONFIG_CMD_OPCODE(VOLATILE_SR_WRITE_ENABLE); + +const uint32_t cmd_read_sreg1 = + SPIFI_DIRECTION_INPUT | + SPIFI_CONFIG_CMD_INTLEN(0) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) | + SPIFI_CONFIG_CMD_OPCODE(READ_SREG1); + +const uint32_t cmd_read_sreg2 = + SPIFI_DIRECTION_INPUT | + SPIFI_CONFIG_CMD_INTLEN(0) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) | + SPIFI_CONFIG_CMD_OPCODE(READ_SREG2); + +const uint32_t cmd_write_sreg = + SPIFI_DIRECTION_OUTPUT | + SPIFI_CONFIG_CMD_INTLEN(0) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) | + SPIFI_CONFIG_CMD_OPCODE(WRITE_SREG); + +const uint32_t cmd_page_program = + SPIFI_DIRECTION_OUTPUT | + SPIFI_CONFIG_CMD_INTLEN(0) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) | + SPIFI_CONFIG_CMD_OPCODE(PAGE_PROGRAM); + +const uint32_t cmd_sector_erase_4k = + SPIFI_DIRECTION_INPUT | + SPIFI_CONFIG_CMD_INTLEN(0) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) | + SPIFI_CONFIG_CMD_OPCODE(SECTOR_ERASE_4K); + +const uint32_t cmd_read_data = + SPIFI_DIRECTION_INPUT | + SPIFI_CONFIG_CMD_INTLEN(0) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) | + SPIFI_CONFIG_CMD_OPCODE(READ_DATA); + +const uint32_t cmd_manufacturer_device_id = + SPIFI_DIRECTION_INPUT | + SPIFI_CONFIG_CMD_INTLEN(0) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) | + SPIFI_CONFIG_CMD_OPCODE(MANUFACTURER_DEVICE_ID); + +const uint32_t cmd_quad_page_program = + SPIFI_DIRECTION_OUTPUT | + SPIFI_CONFIG_CMD_INTLEN(0) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_DATA_PARALLEL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) | + SPIFI_CONFIG_CMD_OPCODE(QUAD_PAGE_PROGRAM); + +const uint32_t cmd_fast_read_quad_output = + SPIFI_DIRECTION_INPUT | + SPIFI_CONFIG_CMD_INTLEN(1) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_DATA_PARALLEL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) | + SPIFI_CONFIG_CMD_OPCODE(FAST_READ_QUAD_OUTPUT); + +const uint32_t cmd_fast_read_quad_io = + SPIFI_DIRECTION_INPUT | + SPIFI_CONFIG_CMD_INTLEN(3) | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_OPCODE_SERIAL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) | + SPIFI_CONFIG_CMD_OPCODE(FAST_READ_QUAD_IO); + +const uint32_t cmd_read_sreg1_polling = + SPIFI_DIRECTION_INPUT | + SPIFI_CONFIG_CMD_POLL_INDEX(0) | + SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE(0) | + SPIFI_CONFIG_CMD_POLL_M | + SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) | + SPIFI_CONFIG_CMD_OPCODE(READ_SREG1); + +void HAL_SPIFI_W25_WriteEnable(SPIFI_HandleTypeDef *spifi) +{ + HAL_SPIFI_SendCommand_LL(spifi, cmd_write_enable, 0, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT); +} + +void HAL_SPIFI_W25_VolatileSRWriteEnable(SPIFI_HandleTypeDef *spifi) +{ + HAL_SPIFI_SendCommand_LL(spifi, cmd_volatile_sr_write_enable, 0, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT); +} + +uint8_t HAL_SPIFI_W25_ReadSREG(SPIFI_HandleTypeDef *spifi, HAL_SPIFI_W25_SREGTypeDef sreg) +{ + uint8_t byte = 0; + + uint32_t cmd = cmd_read_sreg1; + if (sreg == W25_SREG1) + { + cmd = cmd_read_sreg1; + } + else if (sreg == W25_SREG2) + { + cmd = cmd_read_sreg2; + } + + HAL_SPIFI_SendCommand_LL(spifi, cmd, 0, 1, &byte, 0, 0, HAL_SPIFI_TIMEOUT); + + return byte; +} + +HAL_StatusTypeDef HAL_SPIFI_W25_WriteSREG(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2) +{ + uint8_t data[2] = {sreg1, sreg2}; + + HAL_SPIFI_W25_WriteEnable(spifi); + + HAL_SPIFI_SendCommand_LL(spifi, cmd_write_sreg, 0, 2, 0, data, 0, HAL_SPIFI_TIMEOUT); + return HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_WRITE_SREG_BUSY); +} + +void HAL_SPIFI_W25_WriteSREG_Volatile(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2) +{ + uint8_t data[2] = {sreg1, sreg2}; + + HAL_SPIFI_W25_VolatileSRWriteEnable(spifi); + + HAL_SPIFI_SendCommand_LL(spifi, cmd_write_sreg, 0, 2, 0, data, 0, HAL_SPIFI_TIMEOUT); +} + +HAL_StatusTypeDef HAL_SPIFI_W25_WaitBusy_Polling(SPIFI_HandleTypeDef *spifi, uint32_t timeout) +{ + return HAL_SPIFI_SendCommand_LL(spifi, cmd_read_sreg1_polling, 0, 0, 0, 0, 0, timeout); +} + +void HAL_SPIFI_W25_PageProgram(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes) +{ + HAL_SPIFI_W25_WriteEnable(spifi); + HAL_SPIFI_SendCommand_LL(spifi, cmd_page_program, address, dataLength, 0, dataBytes, 0, HAL_SPIFI_TIMEOUT); + HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_PROGRAM_BUSY); +} + +void HAL_SPIFI_W25_SectorErase4K(SPIFI_HandleTypeDef *spifi, uint32_t address) +{ + HAL_SPIFI_W25_WriteEnable(spifi); + HAL_SPIFI_SendCommand_LL(spifi, cmd_sector_erase_4k, address, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT); + HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_PROGRAM_BUSY); +} + +void HAL_SPIFI_W25_ReadData(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes) +{ + HAL_SPIFI_SendCommand_LL(spifi, cmd_read_data, address, dataLength, dataBytes, 0, 0, HAL_SPIFI_TIMEOUT); +} + +W25_ManufacturerDeviceIDTypeDef HAL_SPIFI_W25_ReadManufacturerDeviceID(SPIFI_HandleTypeDef *spifi) +{ + uint8_t data[2] = {0}; + + HAL_SPIFI_SendCommand_LL(spifi, cmd_manufacturer_device_id, 0, 2, data, 0, 0, HAL_SPIFI_TIMEOUT); + + return (W25_ManufacturerDeviceIDTypeDef){ + .Manufacturer = data[0], + .Device = data[1], + }; +} + +void HAL_SPIFI_W25_PageProgram_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes) +{ + HAL_SPIFI_W25_WriteEnable(spifi); + HAL_SPIFI_SendCommand_LL(spifi, cmd_quad_page_program, address, dataLength, 0, dataBytes, 0, HAL_SPIFI_TIMEOUT); + HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_PROGRAM_BUSY); +} + +void HAL_SPIFI_W25_ReadData_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes) +{ + HAL_SPIFI_SendCommand_LL(spifi, cmd_fast_read_quad_output, address, dataLength, dataBytes, 0, 0, HAL_SPIFI_TIMEOUT); +} + +void HAL_SPIFI_W25_ReadData_Quad_IO(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes) +{ + HAL_SPIFI_SendCommand_LL(spifi, cmd_fast_read_quad_io, address, dataLength, dataBytes, 0, 0, HAL_SPIFI_TIMEOUT); +} + +HAL_StatusTypeDef HAL_SPIFI_W25_QuadEnable(SPIFI_HandleTypeDef *spifi) +{ + uint8_t sreg1 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG1); + uint8_t sreg2 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG2); + + return HAL_SPIFI_W25_WriteSREG(spifi, sreg1, sreg2 | HAL_SPIFI_W25_SREG2_BUSY); +} + +HAL_StatusTypeDef HAL_SPIFI_W25_QuadDisable(SPIFI_HandleTypeDef *spifi) +{ + uint8_t sreg1 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG1); + uint8_t sreg2 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG2); + + return HAL_SPIFI_W25_WriteSREG(spifi, sreg1, sreg2 & (~HAL_SPIFI_W25_SREG2_BUSY)); +} diff --git a/cores/arduino/mik32/hal/utilities/Source/mik32_hal_ssd1306.c b/cores/arduino/mik32/hal/utilities/Source/mik32_hal_ssd1306.c new file mode 100644 index 0000000..905b17a --- /dev/null +++ b/cores/arduino/mik32/hal/utilities/Source/mik32_hal_ssd1306.c @@ -0,0 +1,241 @@ +#include "mik32_hal_ssd1306.h" + +// Адрес ведомого +uint16_t slave_address = 0b00111100; + + +uint8_t data_test[] = { + DATS, + 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/*Символы для SSD1306 128x32*/ + +/* Символ ":)" */ +uint8_t data_symbol_smile[] = { + DATS, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, + 0x00, 0x01, 0x02, 0x07, 0x0F, 0x1E, 0x3C, 0x38, 0x38, 0x78, 0x70, 0x70, 0x70, 0x70, 0x70, 0x78, 0x38, 0x38, 0x3C, 0x1E, 0x0F, 0x07, 0x02, 0x01, 0x00 +}; + +/* Символ ":" */ +uint8_t data_symbol_colon[] = { + DATS, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* Символ "0" */ +uint8_t data_symbol_null[] = { + DATS, + 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00 +}; + +/* Символ "1" */ +uint8_t data_symbol_one[] = { + DATS, + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFF, 0xFF, 0xFF, 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, 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, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00 +}; + +/* Символ "2" */ +uint8_t data_symbol_two[] = { + DATS, + 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xFC, 0xFC, 0xFC, 0xFC, 0x1F, 0x1F, 0x1F, 0x1F, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xF1, 0xF1, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00 +}; + +/* Символ "3" */ +uint8_t data_symbol_three[] = { + DATS, + 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00 +}; + +/* Символ "4" */ +uint8_t data_symbol_four[] = { + DATS, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xE3, 0xE3, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 +}; + +/* Символ "5" */ +uint8_t data_symbol_five[] = { + DATS, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFE, 0xFE, 0xFE, 0xFE, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x01, 0x00, 0x00 +}; + +/* Символ "6" */ +uint8_t data_symbol_six[] = { + DATS, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x7F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x3F, 0x38, 0x38, 0x38, 0xF8, 0xF8, 0xF8, 0xF8, 0xC0, 0xC0, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00 +}; + +/* Символ "7" */ +uint8_t data_symbol_seven[] = { + DATS, + 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x8F, 0x8F, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x7F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* Символ "8" */ +uint8_t data_symbol_eight[] = { + DATS, + 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0xF8, 0xF8, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x00, 0x00, + 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0x1F, 0x1F, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00 +}; + +/* Символ "9" */ +uint8_t data_symbol_nine[] = { + DATS, + 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x03, 0x03, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0x1F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + +HAL_StatusTypeDef HAL_SSD1306_Init(I2C_HandleTypeDef *hi2c, uint8_t brightness) +{ + // for (volatile int i = 0; i < 1000; i++); + uint8_t Set_MUX_Ratio, Set_COM_Pins; + #ifdef SSD1306_128x64 + Set_MUX_Ratio = 0x3F; + Set_COM_Pins = 0x12; + #endif + + #ifdef SSD1306_128x32 + Set_MUX_Ratio = 0x1F; + Set_COM_Pins = 0x02; + #endif + + /* Массив для стандартной инициализации */ + uint8_t data_init[] = { + COM, 0xA8, COM, Set_MUX_Ratio, // Set MUX Ratio // 0x3F - 128x64; 0x1F - 128x32 + COM, 0xD3, COM, 0x00, // Set Display Offset + COM, 0x40, // Set Display Start Line + COM, 0xA1, // Set Segment re-map + COM, 0xC8, // Set COM Output Scan Direction + COM, 0xDA, COM, Set_COM_Pins,// Set COM Pins hardware configuration. 0x12 - 128x64; 0x02 - 128x32 + COM, 0x81, COM, brightness, // Set Contrast Control + COM, 0xA4, // Disable Entire Display On + COM, 0xA6, // Set Normal Display + COM, 0xD5, COM, 0x80, // Set Osc Frequency + COM, 0x8D,COM, 0x14, // Enable charge pump regulator + COM, 0xAF // Display On + }; + + /* Oled_init - инициализация экрана в стандартном режиме */ + return HAL_I2C_Master_Transmit(hi2c, slave_address, data_init, sizeof(data_init), I2C_TIMEOUT_DEFAULT); +} + +HAL_StatusTypeDef HAL_SSD1306_SetBorder(I2C_HandleTypeDef *hi2c, uint8_t start_col, uint8_t end_col, uint8_t start_page, uint8_t end_page) +{ + uint8_t data_SetBorder[] = { + COM, 0x21, // установка адреса колонок + COM, start_col, // номер стартовой колонки + COM, end_col, // номер конечной колонки + + COM, 0x22, // установка адреса страницы + COM, start_page, // номер стартовой страницы + COM, end_page, // номер конечной страницы + }; + + /* set_border - установка границ вывода на дисплей */ + return HAL_I2C_Master_Transmit(hi2c, slave_address, data_SetBorder, sizeof(data_SetBorder), I2C_TIMEOUT_DEFAULT); +} + +HAL_StatusTypeDef HAL_SSD1306_CLR_SCR(I2C_HandleTypeDef *hi2c) +{ + uint8_t data_CLR_SCR[517] = {COM, 0x20, COM, 0x00, // Horizontal Addressing Mode + DATS}; + int counter = 5; + for (int page = 0; page < 4; page++) + { + for(int col = 0; col < 128; col++) + { + data_CLR_SCR[counter] = (uint8_t)0; + counter++; + } + } + + /* CLR_SCR - очищение всего экрана в горизонтальном режиме*/ + return HAL_I2C_Master_Transmit(hi2c, slave_address, data_CLR_SCR, sizeof(data_CLR_SCR), I2C_TIMEOUT_DEFAULT); + +} + +HAL_StatusTypeDef HAL_SSD1306_Write(I2C_HandleTypeDef *hi2c, uint8_t symbol) +{ + // for (volatile int i = 0; i < 1000; i++); + HAL_StatusTypeDef error_code = HAL_OK; + switch (symbol) + { + case 0: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_null, sizeof(data_symbol_null), I2C_TIMEOUT_DEFAULT); + break; + case 1: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_one, sizeof(data_symbol_one), I2C_TIMEOUT_DEFAULT); + break; + case 2: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_two, sizeof(data_symbol_two), I2C_TIMEOUT_DEFAULT); + break; + case 3: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_three, sizeof(data_symbol_three), I2C_TIMEOUT_DEFAULT); + break; + case 4: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_four, sizeof(data_symbol_four), I2C_TIMEOUT_DEFAULT); + break; + case 5: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_five, sizeof(data_symbol_five), I2C_TIMEOUT_DEFAULT); + break; + case 6: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_six, sizeof(data_symbol_six), I2C_TIMEOUT_DEFAULT); + break; + case 7: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_seven, sizeof(data_symbol_seven), I2C_TIMEOUT_DEFAULT); + break; + case 8: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_eight, sizeof(data_symbol_eight), I2C_TIMEOUT_DEFAULT); + break; + case 9: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_nine, sizeof(data_symbol_nine), I2C_TIMEOUT_DEFAULT); + break; + case SYMBOL_SMILE: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_smile, sizeof(data_symbol_smile), I2C_TIMEOUT_DEFAULT); + break; + default: + error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_colon, sizeof(data_symbol_colon), I2C_TIMEOUT_DEFAULT); + break; + } + + return error_code; + +} \ No newline at end of file diff --git a/cores/arduino/mik32/hal/utilities/Source/put here c files.txt b/cores/arduino/mik32/hal/utilities/Source/put here c files.txt new file mode 100644 index 0000000..e69de29 diff --git a/cores/arduino/mik32/shared/.gitignore b/cores/arduino/mik32/shared/.gitignore new file mode 100644 index 0000000..c6127b3 --- /dev/null +++ b/cores/arduino/mik32/shared/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/cores/arduino/mik32/shared/README.md b/cores/arduino/mik32/shared/README.md new file mode 100644 index 0000000..7cc2c55 --- /dev/null +++ b/cores/arduino/mik32/shared/README.md @@ -0,0 +1,13 @@ +# mik32v2-shared + +The repository contains header files, startup files, linking scripts and some basic libraries related to MIK32 V2 + + * include/ - header files of the controller core + * mcu32_memory_map.h - memory map, bus clocking masks, interrupt lines and DMA + * ldscripts/ - linker scripts + * eeprom.ld - loading from ROM + * ram.ld - loading from RAM + * spifi.ld - loading from SPIFI + * libs/ - periphery libraries + * periphery/ - periphery register header files + * runtime/crt0.S - start file diff --git a/cores/arduino/mik32/shared/include/csr.h b/cores/arduino/mik32/shared/include/csr.h new file mode 100644 index 0000000..8433517 --- /dev/null +++ b/cores/arduino/mik32/shared/include/csr.h @@ -0,0 +1,119 @@ +/// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details +/// @file +/// Architecture specific CSR's defs and inlines + +#ifndef SCR_CSR_H +#define SCR_CSR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#define __xstringify(s) __stringify(s) +#define __stringify(s) #s + +#ifdef read_csr +#undef read_csr +#endif + +#ifdef write_csr +#undef write_csr +#endif + +#ifdef swap_csr +#undef swap_csr +#endif + +#ifdef set_csr +#undef set_csr +#endif + +#ifdef clear_csr +#undef clear_csr +#endif + +#ifdef rdtime +#undef rdtime +#endif + +#ifdef rdcycle +#undef rdcycle +#endif + +#ifdef rdinstret +#undef rdinstret +#endif + +#define read_csr(reg) \ + ({ \ + unsigned long __tmp; \ + asm volatile ("csrr %0, " __xstringify(reg) : "=r"(__tmp)); \ + __tmp; \ + }) + +#define write_csr(reg, val) \ + do { \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrw " __xstringify(reg) ", %0" :: "i"(val)); \ + else \ + asm volatile ("csrw " __xstringify(reg) ", %0" :: "r"(val)); \ + } while (0) + +#define swap_csr(reg, val) \ + ({ \ + unsigned long __tmp; \ + if (__builtin_constant_p(val) && (val) == 0) \ + asm volatile ("csrrw %0, " __xstringify(reg) ", zero" : "=r"(__tmp) :); \ + else if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrrw %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(val)); \ + else \ + asm volatile ("csrrw %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(val)); \ + __tmp; \ + }) + +#define set_csr(reg, bit) \ + ({ \ + unsigned long __tmp; \ + if (__builtin_constant_p(bit) && (bit) < 32) \ + asm volatile ("csrrs %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(bit)); \ + else \ + asm volatile ("csrrs %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(bit)); \ + __tmp; \ + }) + +#define clear_csr(reg, bit) \ + ({ \ + unsigned long __tmp; \ + if (__builtin_constant_p(bit) && (bit) < 32) \ + asm volatile ("csrrc %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(bit)); \ + else \ + asm volatile ("csrrc %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(bit)); \ + __tmp; \ + }) + +#define rdtime() read_csr(time) +#define rdcycle() read_csr(cycle) +#define rdinstret() read_csr(instret) + +static inline unsigned long __attribute__((const)) cpuid() +{ + unsigned long res; + asm ("csrr %0, mcpuid" : "=r"(res)); + return res; +} + +static inline unsigned long __attribute__((const)) impid() +{ + unsigned long res; + asm ("csrr %0, mimpid" : "=r"(res)); + return res; +} + +#ifdef __cplusplus +} +#endif + +#endif // SCR_CSR_H diff --git a/cores/arduino/mik32/shared/include/mcu32_memory_map.h b/cores/arduino/mik32/shared/include/mcu32_memory_map.h new file mode 100644 index 0000000..7cacfa6 --- /dev/null +++ b/cores/arduino/mik32/shared/include/mcu32_memory_map.h @@ -0,0 +1,250 @@ +#ifndef MCU32_MEMORY_MAP_H_INCLUDED +#define MCU32_MEMORY_MAP_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define EEPROM_BASE_ADDRESS 0x01000000 +#define EEPROM_SIZE (16*1024) + +#define RAM_BASE_ADDRESS 0x02000000 +#define RAM_SIZE (16*1024) + +#define SPIFI_BASE_ADDRESS 0x80000000 +#define SPIFI_SIZE (2*1024*1024) + +#define BOOT_BASE_ADDRESS 0x00000000 +#define BOOT_SIZE (16*1024) + +#define APB_PERIPH_STEP 0x00000400 + +#define DMA_CONFIG_BASE_ADDRESS 0x000040000 + +#define APB_DOM_0_BASE_ADDRESS 0x000050000 +#define PM_BASE_ADDRESS 0x000050000 +#define EPIC_BASE_ADDRESS 0x000050400 +#define TIMER32_0_BASE_ADDRESS 0x000050800 +#define PAD_CONFIG_BASE_ADDRESS 0x000050c00 +#define WDT_BUS_BASE_ADDRESS 0x000051000 +#define OTP_BASE_ADDRESS 0x000051400 +#define PVD_CONTROL_BASE_ADDRESS 0x000051800 + +#define WU_BASE_ADDRESS 0x00060000 +#define RTC_BASE_ADDRESS 0x00060400 +#define BOOT_MANAGER_BASE_ADDRESS 0x00060800 + +#define SPIFI_CONFIG_BASE_ADDRESS 0x00070000 +#define EEPROM_REGS_BASE_ADDRESS 0x00070400 +#define CRYPTO_BASE_ADDRESS 0x00080000 +#define CRC_BASE_ADDRESS 0x00080400 + +#define APB_DOM_3_BASE_ADDRESS 0x00081000 + +#define WDT_BASE_ADDRESS 0x00081000 +#define UART_0_BASE_ADDRESS 0x00081400 +#define UART_1_BASE_ADDRESS 0x00081800 +#define TIMER16_0_BASE_ADDRESS 0x00081C00 +#define TIMER16_1_BASE_ADDRESS 0x00082000 +#define TIMER16_2_BASE_ADDRESS 0x00082400 +#define TIMER32_1_BASE_ADDRESS 0x00082800 +#define TIMER32_2_BASE_ADDRESS 0x00082C00 +#define SPI_0_BASE_ADDRESS 0x00083000 +#define SPI_1_BASE_ADDRESS 0x00083400 +#define I2C_0_BASE_ADDRESS 0x00083800 +#define I2C_1_BASE_ADDRESS 0x00083C00 +#define GPIO_0_BASE_ADDRESS 0x00084000 +#define GPIO_1_BASE_ADDRESS 0x00084400 +#define GPIO_2_BASE_ADDRESS 0x00084800 +#define GPIO_IRQ_BASE_ADDRESS 0x00084C00 +#define ANALOG_REG_BASE_ADDRESS 0x00085000 + + +#define SCR1_TIMER_BASE_ADDRESS 0x00490000 + + +#define DMA_CONFIG (( DMA_CONFIG_TypeDef *) DMA_CONFIG_BASE_ADDRESS ) + +#define PM (( PM_TypeDef *) PM_BASE_ADDRESS ) +#define EPIC (( EPIC_TypeDef *) EPIC_BASE_ADDRESS ) +#define TIMER32_0 (( TIMER32_TypeDef *) TIMER32_0_BASE_ADDRESS ) +#define PVD_CONTROL (( PVD_CONTROL_TypeDef *) PVD_CONTROL_BASE_ADDRESS ) +#define PAD_CONFIG (( PAD_CONFIG_TypeDef *) PAD_CONFIG_BASE_ADDRESS ) +#define WDT_BUS (( WDT_BUS_TypeDef *) WDT_BUS_BASE_ADDRESS ) +#define OTP (( OTP_TypeDef *) OTP_BASE_ADDRESS ) + +#define WU (( WU_TypeDef *) WU_BASE_ADDRESS ) +#define RTC (( RTC_TypeDef *) RTC_BASE_ADDRESS ) +#define BOOT_MANAGER (( BOOT_MANAGER_TypeDef *) BOOT_MANAGER_BASE_ADDRESS ) + +#define SPIFI_CONFIG (( SPIFI_CONFIG_TypeDef *) SPIFI_CONFIG_BASE_ADDRESS ) +#define EEPROM_REGS (( EEPROM_REGS_TypeDef *) EEPROM_REGS_BASE_ADDRESS ) +#define CRYPTO (( CRYPTO_TypeDef *) CRYPTO_BASE_ADDRESS ) +#define CRC (( CRC_TypeDef *) CRC_BASE_ADDRESS ) + +#define WDT (( WDT_TypeDef *) WDT_BASE_ADDRESS ) +#define UART_0 (( UART_TypeDef *) UART_0_BASE_ADDRESS ) +#define UART_1 (( UART_TypeDef *) UART_1_BASE_ADDRESS ) +#define TIMER16_0 (( TIMER16_TypeDef *) TIMER16_0_BASE_ADDRESS ) +#define TIMER16_1 (( TIMER16_TypeDef *) TIMER16_1_BASE_ADDRESS ) +#define TIMER16_2 (( TIMER16_TypeDef *) TIMER16_2_BASE_ADDRESS ) +#define TIMER32_1 (( TIMER32_TypeDef *) TIMER32_1_BASE_ADDRESS ) +#define TIMER32_2 (( TIMER32_TypeDef *) TIMER32_2_BASE_ADDRESS ) +#define SPI_0 (( SPI_TypeDef *) SPI_0_BASE_ADDRESS ) +#define SPI_1 (( SPI_TypeDef *) SPI_1_BASE_ADDRESS ) +#define I2C_0 (( I2C_TypeDef *) I2C_0_BASE_ADDRESS ) +#define I2C_1 (( I2C_TypeDef *) I2C_1_BASE_ADDRESS ) +#define GPIO_0 (( GPIO_TypeDef *) GPIO_0_BASE_ADDRESS ) +#define GPIO_1 (( GPIO_TypeDef *) GPIO_1_BASE_ADDRESS ) +#define GPIO_2 (( GPIO_TypeDef *) GPIO_2_BASE_ADDRESS ) +#define GPIO_IRQ (( GPIO_IRQ_TypeDef *) GPIO_IRQ_BASE_ADDRESS ) +#define ANALOG_REG (( ANALOG_REG_TypeDef *) ANALOG_REG_BASE_ADDRESS ) + +#define SCR1_TIMER (( SCR1_TIMER_TypeDef *) SCR1_TIMER_BASE_ADDRESS ) + + + +// Clock gating masks to be used with PM module +//AHB BUS +#define PM_CLOCK_AHB_CPU_S 0 +#define PM_CLOCK_AHB_CPU_M (1 << PM_CLOCK_AHB_CPU_S) +#define PM_CLOCK_AHB_EEPROM_S 1 +#define PM_CLOCK_AHB_EEPROM_M (1 << PM_CLOCK_AHB_EEPROM_S) +#define PM_CLOCK_AHB_RAM_S 2 +#define PM_CLOCK_AHB_RAM_M (1 << PM_CLOCK_AHB_RAM_S) +#define PM_CLOCK_AHB_SPIFI_S 3 +#define PM_CLOCK_AHB_SPIFI_M (1 << PM_CLOCK_AHB_SPIFI_S) +#define PM_CLOCK_AHB_TCB_S 4 +#define PM_CLOCK_AHB_TCB_M (1 << PM_CLOCK_AHB_TCB_S) +#define PM_CLOCK_AHB_DMA_S 5 +#define PM_CLOCK_AHB_DMA_M (1 << PM_CLOCK_AHB_DMA_S) +#define PM_CLOCK_AHB_CRYPTO_S 6 +#define PM_CLOCK_AHB_CRYPTO_M (1 << PM_CLOCK_AHB_CRYPTO_S) +#define PM_CLOCK_AHB_CRC32_S 7 +#define PM_CLOCK_AHB_CRC32_M (1 << PM_CLOCK_AHB_CRC32_S) + + +//APB M BUS +#define PM_CLOCK_APB_M_PM_S 0 +#define PM_CLOCK_APB_M_PM_M (1 << PM_CLOCK_APB_M_PM_S) +#define PM_CLOCK_APB_M_EPIC_S 1 +#define PM_CLOCK_APB_M_EPIC_M (1 << PM_CLOCK_APB_M_EPIC_S) +#define PM_CLOCK_APB_M_TIMER32_0_S 2 +#define PM_CLOCK_APB_M_TIMER32_0_M (1 << PM_CLOCK_APB_M_TIMER32_0_S) +#define PM_CLOCK_APB_M_PAD_CONFIG_S 3 +#define PM_CLOCK_APB_M_PAD_CONFIG_M (1 << PM_CLOCK_APB_M_PAD_CONFIG_S) +#define PM_CLOCK_APB_M_WDT_BUS_S 4 +#define PM_CLOCK_APB_M_WDT_BUS_M (1 << PM_CLOCK_APB_M_WDT_BUS_S) +#define PM_CLOCK_APB_M_OTP_CONTROLLER_S 5 +#define PM_CLOCK_APB_M_OTP_CONTROLLER_M (1 << PM_CLOCK_APB_M_OTP_CONTROLLER_S) +#define PM_CLOCK_APB_M_PVD_CONTROL_S 6 +#define PM_CLOCK_APB_M_PVD_CONTROL_M (1 << PM_CLOCK_APB_M_PVD_CONTROL_S) +#define PM_CLOCK_APB_M_WU_S 7 +#define PM_CLOCK_APB_M_WU_M (1 << PM_CLOCK_APB_M_WU_S) +#define PM_CLOCK_APB_M_RTC_S 8 +#define PM_CLOCK_APB_M_RTC_M (1 << PM_CLOCK_APB_M_RTC_S) + +//APB P BUS +#define PM_CLOCK_APB_P_WDT_S 0 +#define PM_CLOCK_APB_P_WDT_M (1 << PM_CLOCK_APB_P_WDT_S) +#define PM_CLOCK_APB_P_UART_0_S 1 +#define PM_CLOCK_APB_P_UART_0_M (1 << PM_CLOCK_APB_P_UART_0_S) +#define PM_CLOCK_APB_P_UART_1_S 2 +#define PM_CLOCK_APB_P_UART_1_M (1 << PM_CLOCK_APB_P_UART_1_S) +#define PM_CLOCK_APB_P_TIMER16_0_S 3 +#define PM_CLOCK_APB_P_TIMER16_0_M (1 << PM_CLOCK_APB_P_TIMER16_0_S) +#define PM_CLOCK_APB_P_TIMER16_1_S 4 +#define PM_CLOCK_APB_P_TIMER16_1_M (1 << PM_CLOCK_APB_P_TIMER16_1_S) +#define PM_CLOCK_APB_P_TIMER16_2_S 5 +#define PM_CLOCK_APB_P_TIMER16_2_M (1 << PM_CLOCK_APB_P_TIMER16_2_S) +#define PM_CLOCK_APB_P_TIMER32_1_S 6 +#define PM_CLOCK_APB_P_TIMER32_1_M (1 << PM_CLOCK_APB_P_TIMER32_1_S) +#define PM_CLOCK_APB_P_TIMER32_2_S 7 +#define PM_CLOCK_APB_P_TIMER32_2_M (1 << PM_CLOCK_APB_P_TIMER32_2_S) +#define PM_CLOCK_APB_P_SPI_0_S 8 +#define PM_CLOCK_APB_P_SPI_0_M (1 << PM_CLOCK_APB_P_SPI_0_S) +#define PM_CLOCK_APB_P_SPI_1_S 9 +#define PM_CLOCK_APB_P_SPI_1_M (1 << PM_CLOCK_APB_P_SPI_1_S) +#define PM_CLOCK_APB_P_I2C_0_S 10 +#define PM_CLOCK_APB_P_I2C_0_M (1 << PM_CLOCK_APB_P_I2C_0_S) +#define PM_CLOCK_APB_P_I2C_1_S 11 +#define PM_CLOCK_APB_P_I2C_1_M (1 << PM_CLOCK_APB_P_I2C_1_S) +#define PM_CLOCK_APB_P_GPIO_0_S 12 +#define PM_CLOCK_APB_P_GPIO_0_M (1 << PM_CLOCK_APB_P_GPIO_0_S) +#define PM_CLOCK_APB_P_GPIO_1_S 13 +#define PM_CLOCK_APB_P_GPIO_1_M (1 << PM_CLOCK_APB_P_GPIO_1_S) +#define PM_CLOCK_APB_P_GPIO_2_S 14 +#define PM_CLOCK_APB_P_GPIO_2_M (1 << PM_CLOCK_APB_P_GPIO_2_S) +#define PM_CLOCK_APB_P_ANALOG_REGS_S 15 +#define PM_CLOCK_APB_P_ANALOG_REGS_M (1 << PM_CLOCK_APB_P_ANALOG_REGS_S) +#define PM_CLOCK_APB_P_GPIO_IRQ_S 16 +#define PM_CLOCK_APB_P_GPIO_IRQ_M (1 << PM_CLOCK_APB_P_GPIO_IRQ_S) + +// Timer connection to PM multiplexor controling timer inputs +// +#define PM_TIMER32_0_INDEX 0 +#define PM_TIMER32_1_INDEX 1 +#define PM_TIMER32_2_INDEX 2 +#define PM_TIMER16_0_INDEX 3 +#define PM_TIMER16_1_INDEX 4 +#define PM_TIMER16_2_INDEX 5 + + +// Interrupt lines to be used with EPIC module +// +#define EPIC_TIMER32_0_INDEX 0 +#define EPIC_UART_0_INDEX 1 +#define EPIC_UART_1_INDEX 2 +#define EPIC_SPI_0_INDEX 3 +#define EPIC_SPI_1_INDEX 4 +#define EPIC_GPIO_IRQ_INDEX 5 +#define EPIC_I2C_0_INDEX 6 +#define EPIC_I2C_1_INDEX 7 +#define EPIC_WDT_INDEX 8 +#define EPIC_TIMER16_0_INDEX 9 +#define EPIC_TIMER16_1_INDEX 10 +#define EPIC_TIMER16_2_INDEX 11 +#define EPIC_TIMER32_1_INDEX 12 +#define EPIC_TIMER32_2_INDEX 13 +#define EPIC_SPIFI_INDEX 14 +#define EPIC_RTC_INDEX 15 +#define EPIC_EEPROM_INDEX 16 +#define EPIC_WDT_DOM3_INDEX 17 +#define EPIC_WDT_SPIFI_INDEX 18 +#define EPIC_WDT_EEPROM_INDEX 19 +#define EPIC_DMA_INDEX 20 +#define EPIC_FREQ_MON_INDEX 21 +#define EPIC_PVD_AVCC_UNDER 22 +#define EPIC_PVD_AVCC_OVER 23 +#define EPIC_PVD_VCC_UNDER 24 +#define EPIC_PVD_VCC_OVER 25 +#define EPIC_BATTERY_NON_GOOD 26 +#define EPIC_BOR_INDEX 27 +#define EPIC_TSENS_INDEX 28 +#define EPIC_ADC_INDEX 29 +#define EPIC_DAC0_INDEX 30 +#define EPIC_DAC1_INDEX 31 + + +// DMA request lines +// +#define DMA_UART_0_INDEX 0 +#define DMA_UART_1_INDEX 1 +#define DMA_CRYPTO_INDEX 2 +#define DMA_SPI_0_INDEX 3 +#define DMA_SPI_1_INDEX 4 +#define DMA_I2C_0_INDEX 5 +#define DMA_I2C_1_INDEX 6 +#define DMA_SPIFI_INDEX 7 +#define DMA_TIMER32_1_INDEX 8 +#define DMA_TIMER32_2_INDEX 9 +#define DMA_DAC0_INDEX 10 +#define DMA_DAC1_INDEX 11 +#define DMA_TIMER32_0_INDEX 12 + + +#ifdef __cplusplus +} +#endif + +#endif // MCU32_MEMORY_MAP_H_INCLUDED diff --git a/cores/arduino/mik32/shared/include/riscv_csr_encoding.h b/cores/arduino/mik32/shared/include/riscv_csr_encoding.h new file mode 100644 index 0000000..efd7ed9 --- /dev/null +++ b/cores/arduino/mik32/shared/include/riscv_csr_encoding.h @@ -0,0 +1,1481 @@ +// See LICENSE for license details. + +#ifndef RISCV_CSR_ENCODING_H +#define RISCV_CSR_ENCODING_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MSTATUS_UIE 0x00000001 +#define MSTATUS_SIE 0x00000002 +#define MSTATUS_HIE 0x00000004 +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_UPIE 0x00000010 +#define MSTATUS_SPIE 0x00000020 +#define MSTATUS_HPIE 0x00000040 +#define MSTATUS_MPIE 0x00000080 +#define MSTATUS_SPP 0x00000100 +#define MSTATUS_HPP 0x00000600 +#define MSTATUS_MPP 0x00001800 +#define MSTATUS_FS 0x00006000 +#define MSTATUS_XS 0x00018000 +#define MSTATUS_MPRV 0x00020000 +#define MSTATUS_SUM 0x00040000 +#define MSTATUS_MXR 0x00080000 +#define MSTATUS_TVM 0x00100000 +#define MSTATUS_TW 0x00200000 +#define MSTATUS_TSR 0x00400000 +#define MSTATUS32_SD 0x80000000 +#define MSTATUS_UXL 0x0000000300000000 +#define MSTATUS_SXL 0x0000000C00000000 +#define MSTATUS64_SD 0x8000000000000000 + +#define SSTATUS_UIE 0x00000001 +#define SSTATUS_SIE 0x00000002 +#define SSTATUS_UPIE 0x00000010 +#define SSTATUS_SPIE 0x00000020 +#define SSTATUS_SPP 0x00000100 +#define SSTATUS_FS 0x00006000 +#define SSTATUS_XS 0x00018000 +#define SSTATUS_SUM 0x00040000 +#define SSTATUS_MXR 0x00080000 +#define SSTATUS32_SD 0x80000000 +#define SSTATUS_UXL 0x0000000300000000 +#define SSTATUS64_SD 0x8000000000000000 + +#define DCSR_XDEBUGVER (3U<<30) +#define DCSR_NDRESET (1<<29) +#define DCSR_FULLRESET (1<<28) +#define DCSR_EBREAKM (1<<15) +#define DCSR_EBREAKH (1<<14) +#define DCSR_EBREAKS (1<<13) +#define DCSR_EBREAKU (1<<12) +#define DCSR_STOPCYCLE (1<<10) +#define DCSR_STOPTIME (1<<9) +#define DCSR_CAUSE (7<<6) +#define DCSR_DEBUGINT (1<<5) +#define DCSR_HALT (1<<3) +#define DCSR_STEP (1<<2) +#define DCSR_PRV (3<<0) + +#define DCSR_CAUSE_NONE 0 +#define DCSR_CAUSE_SWBP 1 +#define DCSR_CAUSE_HWBP 2 +#define DCSR_CAUSE_DEBUGINT 3 +#define DCSR_CAUSE_STEP 4 +#define DCSR_CAUSE_HALT 5 + +#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4)) +#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5)) +#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11)) + +#define MCONTROL_SELECT (1<<19) +#define MCONTROL_TIMING (1<<18) +#define MCONTROL_ACTION (0x3f<<12) +#define MCONTROL_CHAIN (1<<11) +#define MCONTROL_MATCH (0xf<<7) +#define MCONTROL_M (1<<6) +#define MCONTROL_H (1<<5) +#define MCONTROL_S (1<<4) +#define MCONTROL_U (1<<3) +#define MCONTROL_EXECUTE (1<<2) +#define MCONTROL_STORE (1<<1) +#define MCONTROL_LOAD (1<<0) + +#define MCONTROL_TYPE_NONE 0 +#define MCONTROL_TYPE_MATCH 2 + +#define MCONTROL_ACTION_DEBUG_EXCEPTION 0 +#define MCONTROL_ACTION_DEBUG_MODE 1 +#define MCONTROL_ACTION_TRACE_START 2 +#define MCONTROL_ACTION_TRACE_STOP 3 +#define MCONTROL_ACTION_TRACE_EMIT 4 + +#define MCONTROL_MATCH_EQUAL 0 +#define MCONTROL_MATCH_NAPOT 1 +#define MCONTROL_MATCH_GE 2 +#define MCONTROL_MATCH_LT 3 +#define MCONTROL_MATCH_MASK_LOW 4 +#define MCONTROL_MATCH_MASK_HIGH 5 + +#define MIP_SSIP (1 << IRQ_S_SOFT) +#define MIP_HSIP (1 << IRQ_H_SOFT) +#define MIP_MSIP (1 << IRQ_M_SOFT) +#define MIP_STIP (1 << IRQ_S_TIMER) +#define MIP_HTIP (1 << IRQ_H_TIMER) +#define MIP_MTIP (1 << IRQ_M_TIMER) +#define MIP_SEIP (1 << IRQ_S_EXT) +#define MIP_HEIP (1 << IRQ_H_EXT) +#define MIP_MEIP (1 << IRQ_M_EXT) + +#define SIP_SSIP MIP_SSIP +#define SIP_STIP MIP_STIP + +#define PRV_U 0 +#define PRV_S 1 +#define PRV_H 2 +#define PRV_M 3 + +#define SPTBR32_MODE 0x80000000 +#define SPTBR32_ASID 0x7FC00000 +#define SPTBR32_PPN 0x003FFFFF +#define SPTBR64_MODE 0xF000000000000000 +#define SPTBR64_ASID 0x0FFFF00000000000 +#define SPTBR64_PPN 0x00000FFFFFFFFFFF + +#define SPTBR_MODE_OFF 0 +#define SPTBR_MODE_SV32 1 +#define SPTBR_MODE_SV39 8 +#define SPTBR_MODE_SV48 9 +#define SPTBR_MODE_SV57 10 +#define SPTBR_MODE_SV64 11 + +#define PMP_R 0x01 +#define PMP_W 0x02 +#define PMP_X 0x04 +#define PMP_A 0x18 +#define PMP_L 0x80 +#define PMP_SHIFT 2 + +#define PMP_TOR 0x08 +#define PMP_NA4 0x10 +#define PMP_NAPOT 0x18 + +#define IRQ_S_SOFT 1 +#define IRQ_H_SOFT 2 +#define IRQ_M_SOFT 3 +#define IRQ_S_TIMER 5 +#define IRQ_H_TIMER 6 +#define IRQ_M_TIMER 7 +#define IRQ_S_EXT 9 +#define IRQ_H_EXT 10 +#define IRQ_M_EXT 11 +#define IRQ_COP 12 +#define IRQ_HOST 13 + +#define DEFAULT_RSTVEC 0x00001000 +#define CLINT_BASE 0x02000000 +#define CLINT_SIZE 0x000c0000 +#define EXT_IO_BASE 0x40000000 +#define DRAM_BASE 0x80000000 + +// page table entry (PTE) fields +#define PTE_V 0x001 // Valid +#define PTE_R 0x002 // Read +#define PTE_W 0x004 // Write +#define PTE_X 0x008 // Execute +#define PTE_U 0x010 // User +#define PTE_G 0x020 // Global +#define PTE_A 0x040 // Accessed +#define PTE_D 0x080 // Dirty +#define PTE_SOFT 0x300 // Reserved for Software + +#define PTE_PPN_SHIFT 10 + +#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V) + +#ifdef __riscv + +#if __riscv_xlen == 64 +# define MSTATUS_SD MSTATUS64_SD +# define SSTATUS_SD SSTATUS64_SD +# define RISCV_PGLEVEL_BITS 9 +# define SPTBR_MODE SPTBR64_MODE +#else +# define MSTATUS_SD MSTATUS32_SD +# define SSTATUS_SD SSTATUS32_SD +# define RISCV_PGLEVEL_BITS 10 +# define SPTBR_MODE SPTBR32_MODE +#endif +#define RISCV_PGSHIFT 12 +#define RISCV_PGSIZE (1 << RISCV_PGSHIFT) + +#ifndef __ASSEMBLER__ + +#ifdef __GNUC__ + +#define read_csr(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +#define write_csr(reg, val) ({ \ + asm volatile ("csrw " #reg ", %0" :: "rK"(val)); }) + +#define swap_csr(reg, val) ({ unsigned long __tmp; \ + asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "rK"(val)); \ + __tmp; }) + +#define set_csr(reg, bit) ({ unsigned long __tmp; \ + asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \ + __tmp; }) + +#define clear_csr(reg, bit) ({ unsigned long __tmp; \ + asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \ + __tmp; }) + +#define rdtime() read_csr(time) +#define rdcycle() read_csr(cycle) +#define rdinstret() read_csr(instret) + +#endif + +#endif + +#endif + +#endif +/* Automatically generated by parse-opcodes. */ +#ifndef RISCV_ENCODING_H +#define RISCV_ENCODING_H +#define MATCH_BEQ 0x63 +#define MASK_BEQ 0x707f +#define MATCH_BNE 0x1063 +#define MASK_BNE 0x707f +#define MATCH_BLT 0x4063 +#define MASK_BLT 0x707f +#define MATCH_BGE 0x5063 +#define MASK_BGE 0x707f +#define MATCH_BLTU 0x6063 +#define MASK_BLTU 0x707f +#define MATCH_BGEU 0x7063 +#define MASK_BGEU 0x707f +#define MATCH_JALR 0x67 +#define MASK_JALR 0x707f +#define MATCH_JAL 0x6f +#define MASK_JAL 0x7f +#define MATCH_LUI 0x37 +#define MASK_LUI 0x7f +#define MATCH_AUIPC 0x17 +#define MASK_AUIPC 0x7f +#define MATCH_ADDI 0x13 +#define MASK_ADDI 0x707f +#define MATCH_SLLI 0x1013 +#define MASK_SLLI 0xfc00707f +#define MATCH_SLTI 0x2013 +#define MASK_SLTI 0x707f +#define MATCH_SLTIU 0x3013 +#define MASK_SLTIU 0x707f +#define MATCH_XORI 0x4013 +#define MASK_XORI 0x707f +#define MATCH_SRLI 0x5013 +#define MASK_SRLI 0xfc00707f +#define MATCH_SRAI 0x40005013 +#define MASK_SRAI 0xfc00707f +#define MATCH_ORI 0x6013 +#define MASK_ORI 0x707f +#define MATCH_ANDI 0x7013 +#define MASK_ANDI 0x707f +#define MATCH_ADD 0x33 +#define MASK_ADD 0xfe00707f +#define MATCH_SUB 0x40000033 +#define MASK_SUB 0xfe00707f +#define MATCH_SLL 0x1033 +#define MASK_SLL 0xfe00707f +#define MATCH_SLT 0x2033 +#define MASK_SLT 0xfe00707f +#define MATCH_SLTU 0x3033 +#define MASK_SLTU 0xfe00707f +#define MATCH_XOR 0x4033 +#define MASK_XOR 0xfe00707f +#define MATCH_SRL 0x5033 +#define MASK_SRL 0xfe00707f +#define MATCH_SRA 0x40005033 +#define MASK_SRA 0xfe00707f +#define MATCH_OR 0x6033 +#define MASK_OR 0xfe00707f +#define MATCH_AND 0x7033 +#define MASK_AND 0xfe00707f +#define MATCH_ADDIW 0x1b +#define MASK_ADDIW 0x707f +#define MATCH_SLLIW 0x101b +#define MASK_SLLIW 0xfe00707f +#define MATCH_SRLIW 0x501b +#define MASK_SRLIW 0xfe00707f +#define MATCH_SRAIW 0x4000501b +#define MASK_SRAIW 0xfe00707f +#define MATCH_ADDW 0x3b +#define MASK_ADDW 0xfe00707f +#define MATCH_SUBW 0x4000003b +#define MASK_SUBW 0xfe00707f +#define MATCH_SLLW 0x103b +#define MASK_SLLW 0xfe00707f +#define MATCH_SRLW 0x503b +#define MASK_SRLW 0xfe00707f +#define MATCH_SRAW 0x4000503b +#define MASK_SRAW 0xfe00707f +#define MATCH_LB 0x3 +#define MASK_LB 0x707f +#define MATCH_LH 0x1003 +#define MASK_LH 0x707f +#define MATCH_LW 0x2003 +#define MASK_LW 0x707f +#define MATCH_LD 0x3003 +#define MASK_LD 0x707f +#define MATCH_LBU 0x4003 +#define MASK_LBU 0x707f +#define MATCH_LHU 0x5003 +#define MASK_LHU 0x707f +#define MATCH_LWU 0x6003 +#define MASK_LWU 0x707f +#define MATCH_SB 0x23 +#define MASK_SB 0x707f +#define MATCH_SH 0x1023 +#define MASK_SH 0x707f +#define MATCH_SW 0x2023 +#define MASK_SW 0x707f +#define MATCH_SD 0x3023 +#define MASK_SD 0x707f +#define MATCH_FENCE 0xf +#define MASK_FENCE 0x707f +#define MATCH_FENCE_I 0x100f +#define MASK_FENCE_I 0x707f +#define MATCH_MUL 0x2000033 +#define MASK_MUL 0xfe00707f +#define MATCH_MULH 0x2001033 +#define MASK_MULH 0xfe00707f +#define MATCH_MULHSU 0x2002033 +#define MASK_MULHSU 0xfe00707f +#define MATCH_MULHU 0x2003033 +#define MASK_MULHU 0xfe00707f +#define MATCH_DIV 0x2004033 +#define MASK_DIV 0xfe00707f +#define MATCH_DIVU 0x2005033 +#define MASK_DIVU 0xfe00707f +#define MATCH_REM 0x2006033 +#define MASK_REM 0xfe00707f +#define MATCH_REMU 0x2007033 +#define MASK_REMU 0xfe00707f +#define MATCH_MULW 0x200003b +#define MASK_MULW 0xfe00707f +#define MATCH_DIVW 0x200403b +#define MASK_DIVW 0xfe00707f +#define MATCH_DIVUW 0x200503b +#define MASK_DIVUW 0xfe00707f +#define MATCH_REMW 0x200603b +#define MASK_REMW 0xfe00707f +#define MATCH_REMUW 0x200703b +#define MASK_REMUW 0xfe00707f +#define MATCH_AMOADD_W 0x202f +#define MASK_AMOADD_W 0xf800707f +#define MATCH_AMOXOR_W 0x2000202f +#define MASK_AMOXOR_W 0xf800707f +#define MATCH_AMOOR_W 0x4000202f +#define MASK_AMOOR_W 0xf800707f +#define MATCH_AMOAND_W 0x6000202f +#define MASK_AMOAND_W 0xf800707f +#define MATCH_AMOMIN_W 0x8000202f +#define MASK_AMOMIN_W 0xf800707f +#define MATCH_AMOMAX_W 0xa000202f +#define MASK_AMOMAX_W 0xf800707f +#define MATCH_AMOMINU_W 0xc000202f +#define MASK_AMOMINU_W 0xf800707f +#define MATCH_AMOMAXU_W 0xe000202f +#define MASK_AMOMAXU_W 0xf800707f +#define MATCH_AMOSWAP_W 0x800202f +#define MASK_AMOSWAP_W 0xf800707f +#define MATCH_LR_W 0x1000202f +#define MASK_LR_W 0xf9f0707f +#define MATCH_SC_W 0x1800202f +#define MASK_SC_W 0xf800707f +#define MATCH_AMOADD_D 0x302f +#define MASK_AMOADD_D 0xf800707f +#define MATCH_AMOXOR_D 0x2000302f +#define MASK_AMOXOR_D 0xf800707f +#define MATCH_AMOOR_D 0x4000302f +#define MASK_AMOOR_D 0xf800707f +#define MATCH_AMOAND_D 0x6000302f +#define MASK_AMOAND_D 0xf800707f +#define MATCH_AMOMIN_D 0x8000302f +#define MASK_AMOMIN_D 0xf800707f +#define MATCH_AMOMAX_D 0xa000302f +#define MASK_AMOMAX_D 0xf800707f +#define MATCH_AMOMINU_D 0xc000302f +#define MASK_AMOMINU_D 0xf800707f +#define MATCH_AMOMAXU_D 0xe000302f +#define MASK_AMOMAXU_D 0xf800707f +#define MATCH_AMOSWAP_D 0x800302f +#define MASK_AMOSWAP_D 0xf800707f +#define MATCH_LR_D 0x1000302f +#define MASK_LR_D 0xf9f0707f +#define MATCH_SC_D 0x1800302f +#define MASK_SC_D 0xf800707f +#define MATCH_ECALL 0x73 +#define MASK_ECALL 0xffffffff +#define MATCH_EBREAK 0x100073 +#define MASK_EBREAK 0xffffffff +#define MATCH_URET 0x200073 +#define MASK_URET 0xffffffff +#define MATCH_SRET 0x10200073 +#define MASK_SRET 0xffffffff +#define MATCH_MRET 0x30200073 +#define MASK_MRET 0xffffffff +#define MATCH_DRET 0x7b200073 +#define MASK_DRET 0xffffffff +#define MATCH_SFENCE_VMA 0x12000073 +#define MASK_SFENCE_VMA 0xfe007fff +#define MATCH_WFI 0x10500073 +#define MASK_WFI 0xffffffff +#define MATCH_CSRRW 0x1073 +#define MASK_CSRRW 0x707f +#define MATCH_CSRRS 0x2073 +#define MASK_CSRRS 0x707f +#define MATCH_CSRRC 0x3073 +#define MASK_CSRRC 0x707f +#define MATCH_CSRRWI 0x5073 +#define MASK_CSRRWI 0x707f +#define MATCH_CSRRSI 0x6073 +#define MASK_CSRRSI 0x707f +#define MATCH_CSRRCI 0x7073 +#define MASK_CSRRCI 0x707f +#define MATCH_FADD_S 0x53 +#define MASK_FADD_S 0xfe00007f +#define MATCH_FSUB_S 0x8000053 +#define MASK_FSUB_S 0xfe00007f +#define MATCH_FMUL_S 0x10000053 +#define MASK_FMUL_S 0xfe00007f +#define MATCH_FDIV_S 0x18000053 +#define MASK_FDIV_S 0xfe00007f +#define MATCH_FSGNJ_S 0x20000053 +#define MASK_FSGNJ_S 0xfe00707f +#define MATCH_FSGNJN_S 0x20001053 +#define MASK_FSGNJN_S 0xfe00707f +#define MATCH_FSGNJX_S 0x20002053 +#define MASK_FSGNJX_S 0xfe00707f +#define MATCH_FMIN_S 0x28000053 +#define MASK_FMIN_S 0xfe00707f +#define MATCH_FMAX_S 0x28001053 +#define MASK_FMAX_S 0xfe00707f +#define MATCH_FSQRT_S 0x58000053 +#define MASK_FSQRT_S 0xfff0007f +#define MATCH_FADD_D 0x2000053 +#define MASK_FADD_D 0xfe00007f +#define MATCH_FSUB_D 0xa000053 +#define MASK_FSUB_D 0xfe00007f +#define MATCH_FMUL_D 0x12000053 +#define MASK_FMUL_D 0xfe00007f +#define MATCH_FDIV_D 0x1a000053 +#define MASK_FDIV_D 0xfe00007f +#define MATCH_FSGNJ_D 0x22000053 +#define MASK_FSGNJ_D 0xfe00707f +#define MATCH_FSGNJN_D 0x22001053 +#define MASK_FSGNJN_D 0xfe00707f +#define MATCH_FSGNJX_D 0x22002053 +#define MASK_FSGNJX_D 0xfe00707f +#define MATCH_FMIN_D 0x2a000053 +#define MASK_FMIN_D 0xfe00707f +#define MATCH_FMAX_D 0x2a001053 +#define MASK_FMAX_D 0xfe00707f +#define MATCH_FCVT_S_D 0x40100053 +#define MASK_FCVT_S_D 0xfff0007f +#define MATCH_FCVT_D_S 0x42000053 +#define MASK_FCVT_D_S 0xfff0007f +#define MATCH_FSQRT_D 0x5a000053 +#define MASK_FSQRT_D 0xfff0007f +#define MATCH_FADD_Q 0x6000053 +#define MASK_FADD_Q 0xfe00007f +#define MATCH_FSUB_Q 0xe000053 +#define MASK_FSUB_Q 0xfe00007f +#define MATCH_FMUL_Q 0x16000053 +#define MASK_FMUL_Q 0xfe00007f +#define MATCH_FDIV_Q 0x1e000053 +#define MASK_FDIV_Q 0xfe00007f +#define MATCH_FSGNJ_Q 0x26000053 +#define MASK_FSGNJ_Q 0xfe00707f +#define MATCH_FSGNJN_Q 0x26001053 +#define MASK_FSGNJN_Q 0xfe00707f +#define MATCH_FSGNJX_Q 0x26002053 +#define MASK_FSGNJX_Q 0xfe00707f +#define MATCH_FMIN_Q 0x2e000053 +#define MASK_FMIN_Q 0xfe00707f +#define MATCH_FMAX_Q 0x2e001053 +#define MASK_FMAX_Q 0xfe00707f +#define MATCH_FCVT_S_Q 0x40300053 +#define MASK_FCVT_S_Q 0xfff0007f +#define MATCH_FCVT_Q_S 0x46000053 +#define MASK_FCVT_Q_S 0xfff0007f +#define MATCH_FCVT_D_Q 0x42300053 +#define MASK_FCVT_D_Q 0xfff0007f +#define MATCH_FCVT_Q_D 0x46100053 +#define MASK_FCVT_Q_D 0xfff0007f +#define MATCH_FSQRT_Q 0x5e000053 +#define MASK_FSQRT_Q 0xfff0007f +#define MATCH_FLE_S 0xa0000053 +#define MASK_FLE_S 0xfe00707f +#define MATCH_FLT_S 0xa0001053 +#define MASK_FLT_S 0xfe00707f +#define MATCH_FEQ_S 0xa0002053 +#define MASK_FEQ_S 0xfe00707f +#define MATCH_FLE_D 0xa2000053 +#define MASK_FLE_D 0xfe00707f +#define MATCH_FLT_D 0xa2001053 +#define MASK_FLT_D 0xfe00707f +#define MATCH_FEQ_D 0xa2002053 +#define MASK_FEQ_D 0xfe00707f +#define MATCH_FLE_Q 0xa6000053 +#define MASK_FLE_Q 0xfe00707f +#define MATCH_FLT_Q 0xa6001053 +#define MASK_FLT_Q 0xfe00707f +#define MATCH_FEQ_Q 0xa6002053 +#define MASK_FEQ_Q 0xfe00707f +#define MATCH_FCVT_W_S 0xc0000053 +#define MASK_FCVT_W_S 0xfff0007f +#define MATCH_FCVT_WU_S 0xc0100053 +#define MASK_FCVT_WU_S 0xfff0007f +#define MATCH_FCVT_L_S 0xc0200053 +#define MASK_FCVT_L_S 0xfff0007f +#define MATCH_FCVT_LU_S 0xc0300053 +#define MASK_FCVT_LU_S 0xfff0007f +#define MATCH_FMV_X_W 0xe0000053 +#define MASK_FMV_X_W 0xfff0707f +#define MATCH_FCLASS_S 0xe0001053 +#define MASK_FCLASS_S 0xfff0707f +#define MATCH_FCVT_W_D 0xc2000053 +#define MASK_FCVT_W_D 0xfff0007f +#define MATCH_FCVT_WU_D 0xc2100053 +#define MASK_FCVT_WU_D 0xfff0007f +#define MATCH_FCVT_L_D 0xc2200053 +#define MASK_FCVT_L_D 0xfff0007f +#define MATCH_FCVT_LU_D 0xc2300053 +#define MASK_FCVT_LU_D 0xfff0007f +#define MATCH_FMV_X_D 0xe2000053 +#define MASK_FMV_X_D 0xfff0707f +#define MATCH_FCLASS_D 0xe2001053 +#define MASK_FCLASS_D 0xfff0707f +#define MATCH_FCVT_W_Q 0xc6000053 +#define MASK_FCVT_W_Q 0xfff0007f +#define MATCH_FCVT_WU_Q 0xc6100053 +#define MASK_FCVT_WU_Q 0xfff0007f +#define MATCH_FCVT_L_Q 0xc6200053 +#define MASK_FCVT_L_Q 0xfff0007f +#define MATCH_FCVT_LU_Q 0xc6300053 +#define MASK_FCVT_LU_Q 0xfff0007f +#define MATCH_FMV_X_Q 0xe6000053 +#define MASK_FMV_X_Q 0xfff0707f +#define MATCH_FCLASS_Q 0xe6001053 +#define MASK_FCLASS_Q 0xfff0707f +#define MATCH_FCVT_S_W 0xd0000053 +#define MASK_FCVT_S_W 0xfff0007f +#define MATCH_FCVT_S_WU 0xd0100053 +#define MASK_FCVT_S_WU 0xfff0007f +#define MATCH_FCVT_S_L 0xd0200053 +#define MASK_FCVT_S_L 0xfff0007f +#define MATCH_FCVT_S_LU 0xd0300053 +#define MASK_FCVT_S_LU 0xfff0007f +#define MATCH_FMV_W_X 0xf0000053 +#define MASK_FMV_W_X 0xfff0707f +#define MATCH_FCVT_D_W 0xd2000053 +#define MASK_FCVT_D_W 0xfff0007f +#define MATCH_FCVT_D_WU 0xd2100053 +#define MASK_FCVT_D_WU 0xfff0007f +#define MATCH_FCVT_D_L 0xd2200053 +#define MASK_FCVT_D_L 0xfff0007f +#define MATCH_FCVT_D_LU 0xd2300053 +#define MASK_FCVT_D_LU 0xfff0007f +#define MATCH_FMV_D_X 0xf2000053 +#define MASK_FMV_D_X 0xfff0707f +#define MATCH_FCVT_Q_W 0xd6000053 +#define MASK_FCVT_Q_W 0xfff0007f +#define MATCH_FCVT_Q_WU 0xd6100053 +#define MASK_FCVT_Q_WU 0xfff0007f +#define MATCH_FCVT_Q_L 0xd6200053 +#define MASK_FCVT_Q_L 0xfff0007f +#define MATCH_FCVT_Q_LU 0xd6300053 +#define MASK_FCVT_Q_LU 0xfff0007f +#define MATCH_FMV_Q_X 0xf6000053 +#define MASK_FMV_Q_X 0xfff0707f +#define MATCH_FLW 0x2007 +#define MASK_FLW 0x707f +#define MATCH_FLD 0x3007 +#define MASK_FLD 0x707f +#define MATCH_FLQ 0x4007 +#define MASK_FLQ 0x707f +#define MATCH_FSW 0x2027 +#define MASK_FSW 0x707f +#define MATCH_FSD 0x3027 +#define MASK_FSD 0x707f +#define MATCH_FSQ 0x4027 +#define MASK_FSQ 0x707f +#define MATCH_FMADD_S 0x43 +#define MASK_FMADD_S 0x600007f +#define MATCH_FMSUB_S 0x47 +#define MASK_FMSUB_S 0x600007f +#define MATCH_FNMSUB_S 0x4b +#define MASK_FNMSUB_S 0x600007f +#define MATCH_FNMADD_S 0x4f +#define MASK_FNMADD_S 0x600007f +#define MATCH_FMADD_D 0x2000043 +#define MASK_FMADD_D 0x600007f +#define MATCH_FMSUB_D 0x2000047 +#define MASK_FMSUB_D 0x600007f +#define MATCH_FNMSUB_D 0x200004b +#define MASK_FNMSUB_D 0x600007f +#define MATCH_FNMADD_D 0x200004f +#define MASK_FNMADD_D 0x600007f +#define MATCH_FMADD_Q 0x6000043 +#define MASK_FMADD_Q 0x600007f +#define MATCH_FMSUB_Q 0x6000047 +#define MASK_FMSUB_Q 0x600007f +#define MATCH_FNMSUB_Q 0x600004b +#define MASK_FNMSUB_Q 0x600007f +#define MATCH_FNMADD_Q 0x600004f +#define MASK_FNMADD_Q 0x600007f +#define MATCH_C_NOP 0x1 +#define MASK_C_NOP 0xffff +#define MATCH_C_ADDI16SP 0x6101 +#define MASK_C_ADDI16SP 0xef83 +#define MATCH_C_JR 0x8002 +#define MASK_C_JR 0xf07f +#define MATCH_C_JALR 0x9002 +#define MASK_C_JALR 0xf07f +#define MATCH_C_EBREAK 0x9002 +#define MASK_C_EBREAK 0xffff +#define MATCH_C_LD 0x6000 +#define MASK_C_LD 0xe003 +#define MATCH_C_SD 0xe000 +#define MASK_C_SD 0xe003 +#define MATCH_C_ADDIW 0x2001 +#define MASK_C_ADDIW 0xe003 +#define MATCH_C_LDSP 0x6002 +#define MASK_C_LDSP 0xe003 +#define MATCH_C_SDSP 0xe002 +#define MASK_C_SDSP 0xe003 +#define MATCH_C_ADDI4SPN 0x0 +#define MASK_C_ADDI4SPN 0xe003 +#define MATCH_C_FLD 0x2000 +#define MASK_C_FLD 0xe003 +#define MATCH_C_LW 0x4000 +#define MASK_C_LW 0xe003 +#define MATCH_C_FLW 0x6000 +#define MASK_C_FLW 0xe003 +#define MATCH_C_FSD 0xa000 +#define MASK_C_FSD 0xe003 +#define MATCH_C_SW 0xc000 +#define MASK_C_SW 0xe003 +#define MATCH_C_FSW 0xe000 +#define MASK_C_FSW 0xe003 +#define MATCH_C_ADDI 0x1 +#define MASK_C_ADDI 0xe003 +#define MATCH_C_JAL 0x2001 +#define MASK_C_JAL 0xe003 +#define MATCH_C_LI 0x4001 +#define MASK_C_LI 0xe003 +#define MATCH_C_LUI 0x6001 +#define MASK_C_LUI 0xe003 +#define MATCH_C_SRLI 0x8001 +#define MASK_C_SRLI 0xec03 +#define MATCH_C_SRAI 0x8401 +#define MASK_C_SRAI 0xec03 +#define MATCH_C_ANDI 0x8801 +#define MASK_C_ANDI 0xec03 +#define MATCH_C_SUB 0x8c01 +#define MASK_C_SUB 0xfc63 +#define MATCH_C_XOR 0x8c21 +#define MASK_C_XOR 0xfc63 +#define MATCH_C_OR 0x8c41 +#define MASK_C_OR 0xfc63 +#define MATCH_C_AND 0x8c61 +#define MASK_C_AND 0xfc63 +#define MATCH_C_SUBW 0x9c01 +#define MASK_C_SUBW 0xfc63 +#define MATCH_C_ADDW 0x9c21 +#define MASK_C_ADDW 0xfc63 +#define MATCH_C_J 0xa001 +#define MASK_C_J 0xe003 +#define MATCH_C_BEQZ 0xc001 +#define MASK_C_BEQZ 0xe003 +#define MATCH_C_BNEZ 0xe001 +#define MASK_C_BNEZ 0xe003 +#define MATCH_C_SLLI 0x2 +#define MASK_C_SLLI 0xe003 +#define MATCH_C_FLDSP 0x2002 +#define MASK_C_FLDSP 0xe003 +#define MATCH_C_LWSP 0x4002 +#define MASK_C_LWSP 0xe003 +#define MATCH_C_FLWSP 0x6002 +#define MASK_C_FLWSP 0xe003 +#define MATCH_C_MV 0x8002 +#define MASK_C_MV 0xf003 +#define MATCH_C_ADD 0x9002 +#define MASK_C_ADD 0xf003 +#define MATCH_C_FSDSP 0xa002 +#define MASK_C_FSDSP 0xe003 +#define MATCH_C_SWSP 0xc002 +#define MASK_C_SWSP 0xe003 +#define MATCH_C_FSWSP 0xe002 +#define MASK_C_FSWSP 0xe003 +#define MATCH_CUSTOM0 0xb +#define MASK_CUSTOM0 0x707f +#define MATCH_CUSTOM0_RS1 0x200b +#define MASK_CUSTOM0_RS1 0x707f +#define MATCH_CUSTOM0_RS1_RS2 0x300b +#define MASK_CUSTOM0_RS1_RS2 0x707f +#define MATCH_CUSTOM0_RD 0x400b +#define MASK_CUSTOM0_RD 0x707f +#define MATCH_CUSTOM0_RD_RS1 0x600b +#define MASK_CUSTOM0_RD_RS1 0x707f +#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b +#define MASK_CUSTOM0_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM1 0x2b +#define MASK_CUSTOM1 0x707f +#define MATCH_CUSTOM1_RS1 0x202b +#define MASK_CUSTOM1_RS1 0x707f +#define MATCH_CUSTOM1_RS1_RS2 0x302b +#define MASK_CUSTOM1_RS1_RS2 0x707f +#define MATCH_CUSTOM1_RD 0x402b +#define MASK_CUSTOM1_RD 0x707f +#define MATCH_CUSTOM1_RD_RS1 0x602b +#define MASK_CUSTOM1_RD_RS1 0x707f +#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b +#define MASK_CUSTOM1_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM2 0x5b +#define MASK_CUSTOM2 0x707f +#define MATCH_CUSTOM2_RS1 0x205b +#define MASK_CUSTOM2_RS1 0x707f +#define MATCH_CUSTOM2_RS1_RS2 0x305b +#define MASK_CUSTOM2_RS1_RS2 0x707f +#define MATCH_CUSTOM2_RD 0x405b +#define MASK_CUSTOM2_RD 0x707f +#define MATCH_CUSTOM2_RD_RS1 0x605b +#define MASK_CUSTOM2_RD_RS1 0x707f +#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b +#define MASK_CUSTOM2_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM3 0x7b +#define MASK_CUSTOM3 0x707f +#define MATCH_CUSTOM3_RS1 0x207b +#define MASK_CUSTOM3_RS1 0x707f +#define MATCH_CUSTOM3_RS1_RS2 0x307b +#define MASK_CUSTOM3_RS1_RS2 0x707f +#define MATCH_CUSTOM3_RD 0x407b +#define MASK_CUSTOM3_RD 0x707f +#define MATCH_CUSTOM3_RD_RS1 0x607b +#define MASK_CUSTOM3_RD_RS1 0x707f +#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b +#define MASK_CUSTOM3_RD_RS1_RS2 0x707f +#define CSR_FFLAGS 0x1 +#define CSR_FRM 0x2 +#define CSR_FCSR 0x3 +#define CSR_CYCLE 0xc00 +#define CSR_TIME 0xc01 +#define CSR_INSTRET 0xc02 +#define CSR_HPMCOUNTER3 0xc03 +#define CSR_HPMCOUNTER4 0xc04 +#define CSR_HPMCOUNTER5 0xc05 +#define CSR_HPMCOUNTER6 0xc06 +#define CSR_HPMCOUNTER7 0xc07 +#define CSR_HPMCOUNTER8 0xc08 +#define CSR_HPMCOUNTER9 0xc09 +#define CSR_HPMCOUNTER10 0xc0a +#define CSR_HPMCOUNTER11 0xc0b +#define CSR_HPMCOUNTER12 0xc0c +#define CSR_HPMCOUNTER13 0xc0d +#define CSR_HPMCOUNTER14 0xc0e +#define CSR_HPMCOUNTER15 0xc0f +#define CSR_HPMCOUNTER16 0xc10 +#define CSR_HPMCOUNTER17 0xc11 +#define CSR_HPMCOUNTER18 0xc12 +#define CSR_HPMCOUNTER19 0xc13 +#define CSR_HPMCOUNTER20 0xc14 +#define CSR_HPMCOUNTER21 0xc15 +#define CSR_HPMCOUNTER22 0xc16 +#define CSR_HPMCOUNTER23 0xc17 +#define CSR_HPMCOUNTER24 0xc18 +#define CSR_HPMCOUNTER25 0xc19 +#define CSR_HPMCOUNTER26 0xc1a +#define CSR_HPMCOUNTER27 0xc1b +#define CSR_HPMCOUNTER28 0xc1c +#define CSR_HPMCOUNTER29 0xc1d +#define CSR_HPMCOUNTER30 0xc1e +#define CSR_HPMCOUNTER31 0xc1f +#define CSR_SSTATUS 0x100 +#define CSR_SIE 0x104 +#define CSR_STVEC 0x105 +#define CSR_SCOUNTEREN 0x106 +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SCAUSE 0x142 +#define CSR_SBADADDR 0x143 +#define CSR_SIP 0x144 +#define CSR_SPTBR 0x180 +#define CSR_MSTATUS 0x300 +#define CSR_MISA 0x301 +#define CSR_MEDELEG 0x302 +#define CSR_MIDELEG 0x303 +#define CSR_MIE 0x304 +#define CSR_MTVEC 0x305 +#define CSR_MCOUNTEREN 0x306 +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MBADADDR 0x343 +#define CSR_MIP 0x344 +#define CSR_PMPCFG0 0x3a0 +#define CSR_PMPCFG1 0x3a1 +#define CSR_PMPCFG2 0x3a2 +#define CSR_PMPCFG3 0x3a3 +#define CSR_PMPADDR0 0x3b0 +#define CSR_PMPADDR1 0x3b1 +#define CSR_PMPADDR2 0x3b2 +#define CSR_PMPADDR3 0x3b3 +#define CSR_PMPADDR4 0x3b4 +#define CSR_PMPADDR5 0x3b5 +#define CSR_PMPADDR6 0x3b6 +#define CSR_PMPADDR7 0x3b7 +#define CSR_PMPADDR8 0x3b8 +#define CSR_PMPADDR9 0x3b9 +#define CSR_PMPADDR10 0x3ba +#define CSR_PMPADDR11 0x3bb +#define CSR_PMPADDR12 0x3bc +#define CSR_PMPADDR13 0x3bd +#define CSR_PMPADDR14 0x3be +#define CSR_PMPADDR15 0x3bf +#define CSR_TSELECT 0x7a0 +#define CSR_TDATA1 0x7a1 +#define CSR_TDATA2 0x7a2 +#define CSR_TDATA3 0x7a3 +#define CSR_DCSR 0x7b0 +#define CSR_DPC 0x7b1 +#define CSR_DSCRATCH 0x7b2 +#define CSR_MCYCLE 0xb00 +#define CSR_MINSTRET 0xb02 +#define CSR_MHPMCOUNTER3 0xb03 +#define CSR_MHPMCOUNTER4 0xb04 +#define CSR_MHPMCOUNTER5 0xb05 +#define CSR_MHPMCOUNTER6 0xb06 +#define CSR_MHPMCOUNTER7 0xb07 +#define CSR_MHPMCOUNTER8 0xb08 +#define CSR_MHPMCOUNTER9 0xb09 +#define CSR_MHPMCOUNTER10 0xb0a +#define CSR_MHPMCOUNTER11 0xb0b +#define CSR_MHPMCOUNTER12 0xb0c +#define CSR_MHPMCOUNTER13 0xb0d +#define CSR_MHPMCOUNTER14 0xb0e +#define CSR_MHPMCOUNTER15 0xb0f +#define CSR_MHPMCOUNTER16 0xb10 +#define CSR_MHPMCOUNTER17 0xb11 +#define CSR_MHPMCOUNTER18 0xb12 +#define CSR_MHPMCOUNTER19 0xb13 +#define CSR_MHPMCOUNTER20 0xb14 +#define CSR_MHPMCOUNTER21 0xb15 +#define CSR_MHPMCOUNTER22 0xb16 +#define CSR_MHPMCOUNTER23 0xb17 +#define CSR_MHPMCOUNTER24 0xb18 +#define CSR_MHPMCOUNTER25 0xb19 +#define CSR_MHPMCOUNTER26 0xb1a +#define CSR_MHPMCOUNTER27 0xb1b +#define CSR_MHPMCOUNTER28 0xb1c +#define CSR_MHPMCOUNTER29 0xb1d +#define CSR_MHPMCOUNTER30 0xb1e +#define CSR_MHPMCOUNTER31 0xb1f +#define CSR_MHPMEVENT3 0x323 +#define CSR_MHPMEVENT4 0x324 +#define CSR_MHPMEVENT5 0x325 +#define CSR_MHPMEVENT6 0x326 +#define CSR_MHPMEVENT7 0x327 +#define CSR_MHPMEVENT8 0x328 +#define CSR_MHPMEVENT9 0x329 +#define CSR_MHPMEVENT10 0x32a +#define CSR_MHPMEVENT11 0x32b +#define CSR_MHPMEVENT12 0x32c +#define CSR_MHPMEVENT13 0x32d +#define CSR_MHPMEVENT14 0x32e +#define CSR_MHPMEVENT15 0x32f +#define CSR_MHPMEVENT16 0x330 +#define CSR_MHPMEVENT17 0x331 +#define CSR_MHPMEVENT18 0x332 +#define CSR_MHPMEVENT19 0x333 +#define CSR_MHPMEVENT20 0x334 +#define CSR_MHPMEVENT21 0x335 +#define CSR_MHPMEVENT22 0x336 +#define CSR_MHPMEVENT23 0x337 +#define CSR_MHPMEVENT24 0x338 +#define CSR_MHPMEVENT25 0x339 +#define CSR_MHPMEVENT26 0x33a +#define CSR_MHPMEVENT27 0x33b +#define CSR_MHPMEVENT28 0x33c +#define CSR_MHPMEVENT29 0x33d +#define CSR_MHPMEVENT30 0x33e +#define CSR_MHPMEVENT31 0x33f +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MHARTID 0xf14 +#define CSR_CYCLEH 0xc80 +#define CSR_TIMEH 0xc81 +#define CSR_INSTRETH 0xc82 +#define CSR_HPMCOUNTER3H 0xc83 +#define CSR_HPMCOUNTER4H 0xc84 +#define CSR_HPMCOUNTER5H 0xc85 +#define CSR_HPMCOUNTER6H 0xc86 +#define CSR_HPMCOUNTER7H 0xc87 +#define CSR_HPMCOUNTER8H 0xc88 +#define CSR_HPMCOUNTER9H 0xc89 +#define CSR_HPMCOUNTER10H 0xc8a +#define CSR_HPMCOUNTER11H 0xc8b +#define CSR_HPMCOUNTER12H 0xc8c +#define CSR_HPMCOUNTER13H 0xc8d +#define CSR_HPMCOUNTER14H 0xc8e +#define CSR_HPMCOUNTER15H 0xc8f +#define CSR_HPMCOUNTER16H 0xc90 +#define CSR_HPMCOUNTER17H 0xc91 +#define CSR_HPMCOUNTER18H 0xc92 +#define CSR_HPMCOUNTER19H 0xc93 +#define CSR_HPMCOUNTER20H 0xc94 +#define CSR_HPMCOUNTER21H 0xc95 +#define CSR_HPMCOUNTER22H 0xc96 +#define CSR_HPMCOUNTER23H 0xc97 +#define CSR_HPMCOUNTER24H 0xc98 +#define CSR_HPMCOUNTER25H 0xc99 +#define CSR_HPMCOUNTER26H 0xc9a +#define CSR_HPMCOUNTER27H 0xc9b +#define CSR_HPMCOUNTER28H 0xc9c +#define CSR_HPMCOUNTER29H 0xc9d +#define CSR_HPMCOUNTER30H 0xc9e +#define CSR_HPMCOUNTER31H 0xc9f +#define CSR_MCYCLEH 0xb80 +#define CSR_MINSTRETH 0xb82 +#define CSR_MHPMCOUNTER3H 0xb83 +#define CSR_MHPMCOUNTER4H 0xb84 +#define CSR_MHPMCOUNTER5H 0xb85 +#define CSR_MHPMCOUNTER6H 0xb86 +#define CSR_MHPMCOUNTER7H 0xb87 +#define CSR_MHPMCOUNTER8H 0xb88 +#define CSR_MHPMCOUNTER9H 0xb89 +#define CSR_MHPMCOUNTER10H 0xb8a +#define CSR_MHPMCOUNTER11H 0xb8b +#define CSR_MHPMCOUNTER12H 0xb8c +#define CSR_MHPMCOUNTER13H 0xb8d +#define CSR_MHPMCOUNTER14H 0xb8e +#define CSR_MHPMCOUNTER15H 0xb8f +#define CSR_MHPMCOUNTER16H 0xb90 +#define CSR_MHPMCOUNTER17H 0xb91 +#define CSR_MHPMCOUNTER18H 0xb92 +#define CSR_MHPMCOUNTER19H 0xb93 +#define CSR_MHPMCOUNTER20H 0xb94 +#define CSR_MHPMCOUNTER21H 0xb95 +#define CSR_MHPMCOUNTER22H 0xb96 +#define CSR_MHPMCOUNTER23H 0xb97 +#define CSR_MHPMCOUNTER24H 0xb98 +#define CSR_MHPMCOUNTER25H 0xb99 +#define CSR_MHPMCOUNTER26H 0xb9a +#define CSR_MHPMCOUNTER27H 0xb9b +#define CSR_MHPMCOUNTER28H 0xb9c +#define CSR_MHPMCOUNTER29H 0xb9d +#define CSR_MHPMCOUNTER30H 0xb9e +#define CSR_MHPMCOUNTER31H 0xb9f +#define CAUSE_MISALIGNED_FETCH 0x0 +#define CAUSE_FETCH_ACCESS 0x1 +#define CAUSE_ILLEGAL_INSTRUCTION 0x2 +#define CAUSE_BREAKPOINT 0x3 +#define CAUSE_MISALIGNED_LOAD 0x4 +#define CAUSE_LOAD_ACCESS 0x5 +#define CAUSE_MISALIGNED_STORE 0x6 +#define CAUSE_STORE_ACCESS 0x7 +#define CAUSE_USER_ECALL 0x8 +#define CAUSE_SUPERVISOR_ECALL 0x9 +#define CAUSE_HYPERVISOR_ECALL 0xa +#define CAUSE_MACHINE_ECALL 0xb +#define CAUSE_FETCH_PAGE_FAULT 0xc +#define CAUSE_LOAD_PAGE_FAULT 0xd +#define CAUSE_STORE_PAGE_FAULT 0xf +#endif +#ifdef DECLARE_INSN +DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) +DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) +DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) +DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) +DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) +DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) +DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) +DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) +DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) +DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) +DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) +DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) +DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) +DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) +DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) +DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) +DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) +DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) +DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) +DECLARE_INSN(add, MATCH_ADD, MASK_ADD) +DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) +DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) +DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) +DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) +DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) +DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) +DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) +DECLARE_INSN(or, MATCH_OR, MASK_OR) +DECLARE_INSN(and, MATCH_AND, MASK_AND) +DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW) +DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) +DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) +DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) +DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW) +DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) +DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) +DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) +DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) +DECLARE_INSN(lb, MATCH_LB, MASK_LB) +DECLARE_INSN(lh, MATCH_LH, MASK_LH) +DECLARE_INSN(lw, MATCH_LW, MASK_LW) +DECLARE_INSN(ld, MATCH_LD, MASK_LD) +DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) +DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) +DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) +DECLARE_INSN(sb, MATCH_SB, MASK_SB) +DECLARE_INSN(sh, MATCH_SH, MASK_SH) +DECLARE_INSN(sw, MATCH_SW, MASK_SW) +DECLARE_INSN(sd, MATCH_SD, MASK_SD) +DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) +DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) +DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) +DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) +DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) +DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) +DECLARE_INSN(div, MATCH_DIV, MASK_DIV) +DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) +DECLARE_INSN(rem, MATCH_REM, MASK_REM) +DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) +DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) +DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) +DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) +DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) +DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) +DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) +DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) +DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) +DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) +DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) +DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) +DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) +DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) +DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) +DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) +DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) +DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D) +DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) +DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) +DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) +DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) +DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D) +DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) +DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) +DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D) +DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) +DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) +DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) +DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) +DECLARE_INSN(uret, MATCH_URET, MASK_URET) +DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) +DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) +DECLARE_INSN(dret, MATCH_DRET, MASK_DRET) +DECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA) +DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI) +DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) +DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) +DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) +DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) +DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) +DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) +DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) +DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) +DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) +DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) +DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) +DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) +DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) +DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) +DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) +DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) +DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) +DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) +DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) +DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) +DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) +DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) +DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) +DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) +DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) +DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) +DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) +DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) +DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q) +DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q) +DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q) +DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q) +DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q) +DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q) +DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q) +DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q) +DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q) +DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q) +DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S) +DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q) +DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D) +DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q) +DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) +DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) +DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) +DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) +DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) +DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) +DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q) +DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q) +DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q) +DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) +DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) +DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) +DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) +DECLARE_INSN(fmv_x_w, MATCH_FMV_X_W, MASK_FMV_X_W) +DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) +DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) +DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) +DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) +DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) +DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) +DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D) +DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q) +DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q) +DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q) +DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q) +DECLARE_INSN(fmv_x_q, MATCH_FMV_X_Q, MASK_FMV_X_Q) +DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q) +DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) +DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) +DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) +DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) +DECLARE_INSN(fmv_w_x, MATCH_FMV_W_X, MASK_FMV_W_X) +DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) +DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) +DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) +DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) +DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) +DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W) +DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU) +DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L) +DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU) +DECLARE_INSN(fmv_q_x, MATCH_FMV_Q_X, MASK_FMV_Q_X) +DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) +DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) +DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ) +DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) +DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) +DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ) +DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) +DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) +DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) +DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) +DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) +DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) +DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) +DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) +DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q) +DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q) +DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q) +DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q) +DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP) +DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP) +DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR) +DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) +DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK) +DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) +DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) +DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) +DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) +DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) +DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) +DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD) +DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) +DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW) +DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD) +DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) +DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW) +DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) +DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) +DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) +DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) +DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) +DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) +DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI) +DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) +DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR) +DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR) +DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND) +DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW) +DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) +DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) +DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) +DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) +DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) +DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP) +DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) +DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP) +DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) +DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) +DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP) +DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) +DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP) +DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0) +DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1) +DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2) +DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD) +DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1) +DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2) +DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1) +DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1) +DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2) +DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD) +DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1) +DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2) +DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2) +DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1) +DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2) +DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD) +DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1) +DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2) +DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3) +DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1) +DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2) +DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD) +DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1) +DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2) +#endif +#ifdef DECLARE_CSR +DECLARE_CSR(fflags, CSR_FFLAGS) +DECLARE_CSR(frm, CSR_FRM) +DECLARE_CSR(fcsr, CSR_FCSR) +DECLARE_CSR(cycle, CSR_CYCLE) +DECLARE_CSR(time, CSR_TIME) +DECLARE_CSR(instret, CSR_INSTRET) +DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3) +DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4) +DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5) +DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6) +DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7) +DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8) +DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9) +DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10) +DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11) +DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12) +DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13) +DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14) +DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15) +DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16) +DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17) +DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18) +DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19) +DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20) +DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21) +DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22) +DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23) +DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24) +DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25) +DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26) +DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27) +DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28) +DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29) +DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30) +DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31) +DECLARE_CSR(sstatus, CSR_SSTATUS) +DECLARE_CSR(sie, CSR_SIE) +DECLARE_CSR(stvec, CSR_STVEC) +DECLARE_CSR(scounteren, CSR_SCOUNTEREN) +DECLARE_CSR(sscratch, CSR_SSCRATCH) +DECLARE_CSR(sepc, CSR_SEPC) +DECLARE_CSR(scause, CSR_SCAUSE) +DECLARE_CSR(sbadaddr, CSR_SBADADDR) +DECLARE_CSR(sip, CSR_SIP) +DECLARE_CSR(sptbr, CSR_SPTBR) +DECLARE_CSR(mstatus, CSR_MSTATUS) +DECLARE_CSR(misa, CSR_MISA) +DECLARE_CSR(medeleg, CSR_MEDELEG) +DECLARE_CSR(mideleg, CSR_MIDELEG) +DECLARE_CSR(mie, CSR_MIE) +DECLARE_CSR(mtvec, CSR_MTVEC) +DECLARE_CSR(mcounteren, CSR_MCOUNTEREN) +DECLARE_CSR(mscratch, CSR_MSCRATCH) +DECLARE_CSR(mepc, CSR_MEPC) +DECLARE_CSR(mcause, CSR_MCAUSE) +DECLARE_CSR(mbadaddr, CSR_MBADADDR) +DECLARE_CSR(mip, CSR_MIP) +DECLARE_CSR(pmpcfg0, CSR_PMPCFG0) +DECLARE_CSR(pmpcfg1, CSR_PMPCFG1) +DECLARE_CSR(pmpcfg2, CSR_PMPCFG2) +DECLARE_CSR(pmpcfg3, CSR_PMPCFG3) +DECLARE_CSR(pmpaddr0, CSR_PMPADDR0) +DECLARE_CSR(pmpaddr1, CSR_PMPADDR1) +DECLARE_CSR(pmpaddr2, CSR_PMPADDR2) +DECLARE_CSR(pmpaddr3, CSR_PMPADDR3) +DECLARE_CSR(pmpaddr4, CSR_PMPADDR4) +DECLARE_CSR(pmpaddr5, CSR_PMPADDR5) +DECLARE_CSR(pmpaddr6, CSR_PMPADDR6) +DECLARE_CSR(pmpaddr7, CSR_PMPADDR7) +DECLARE_CSR(pmpaddr8, CSR_PMPADDR8) +DECLARE_CSR(pmpaddr9, CSR_PMPADDR9) +DECLARE_CSR(pmpaddr10, CSR_PMPADDR10) +DECLARE_CSR(pmpaddr11, CSR_PMPADDR11) +DECLARE_CSR(pmpaddr12, CSR_PMPADDR12) +DECLARE_CSR(pmpaddr13, CSR_PMPADDR13) +DECLARE_CSR(pmpaddr14, CSR_PMPADDR14) +DECLARE_CSR(pmpaddr15, CSR_PMPADDR15) +DECLARE_CSR(tselect, CSR_TSELECT) +DECLARE_CSR(tdata1, CSR_TDATA1) +DECLARE_CSR(tdata2, CSR_TDATA2) +DECLARE_CSR(tdata3, CSR_TDATA3) +DECLARE_CSR(dcsr, CSR_DCSR) +DECLARE_CSR(dpc, CSR_DPC) +DECLARE_CSR(dscratch, CSR_DSCRATCH) +DECLARE_CSR(mcycle, CSR_MCYCLE) +DECLARE_CSR(minstret, CSR_MINSTRET) +DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3) +DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4) +DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5) +DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6) +DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7) +DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8) +DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9) +DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10) +DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11) +DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12) +DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13) +DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14) +DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15) +DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16) +DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17) +DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18) +DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19) +DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20) +DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21) +DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22) +DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23) +DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24) +DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25) +DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26) +DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27) +DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28) +DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29) +DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30) +DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31) +DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3) +DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4) +DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5) +DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6) +DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7) +DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8) +DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9) +DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10) +DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11) +DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12) +DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13) +DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14) +DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15) +DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16) +DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17) +DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18) +DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19) +DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20) +DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21) +DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22) +DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23) +DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24) +DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25) +DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26) +DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27) +DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28) +DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29) +DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30) +DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31) +DECLARE_CSR(mvendorid, CSR_MVENDORID) +DECLARE_CSR(marchid, CSR_MARCHID) +DECLARE_CSR(mimpid, CSR_MIMPID) +DECLARE_CSR(mhartid, CSR_MHARTID) +DECLARE_CSR(cycleh, CSR_CYCLEH) +DECLARE_CSR(timeh, CSR_TIMEH) +DECLARE_CSR(instreth, CSR_INSTRETH) +DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H) +DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H) +DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H) +DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H) +DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H) +DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H) +DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H) +DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H) +DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H) +DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H) +DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H) +DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H) +DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H) +DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H) +DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H) +DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H) +DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H) +DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H) +DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H) +DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H) +DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H) +DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H) +DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H) +DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H) +DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H) +DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H) +DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H) +DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H) +DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H) +DECLARE_CSR(mcycleh, CSR_MCYCLEH) +DECLARE_CSR(minstreth, CSR_MINSTRETH) +DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H) +DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H) +DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H) +DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H) +DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H) +DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H) +DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H) +DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H) +DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H) +DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H) +DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H) +DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H) +DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H) +DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H) +DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H) +DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H) +DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H) +DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H) +DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H) +DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H) +DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H) +DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H) +DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H) +DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H) +DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H) +DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H) +DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H) +DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H) +DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H) +#endif +#ifdef DECLARE_CAUSE +DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH) +DECLARE_CAUSE("fetch access", CAUSE_FETCH_ACCESS) +DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION) +DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT) +DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD) +DECLARE_CAUSE("load access", CAUSE_LOAD_ACCESS) +DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE) +DECLARE_CAUSE("store access", CAUSE_STORE_ACCESS) +DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL) +DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL) +DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL) +DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL) +DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT) +DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT) +DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT) +#endif + +#ifdef __cplusplus +} +#endif + +#include "scr1_specific.h" diff --git a/cores/arduino/mik32/shared/include/scr1_csr_encoding.h b/cores/arduino/mik32/shared/include/scr1_csr_encoding.h new file mode 100644 index 0000000..fa260bd --- /dev/null +++ b/cores/arduino/mik32/shared/include/scr1_csr_encoding.h @@ -0,0 +1,88 @@ + +#ifndef SCR1_CSR_ENCODING_H +#define SCR1_CSR_ENCODING_H + +#ifdef __cplusplus +extern "C" { +#endif + +// Bit mask and register value list is based on +// SCR1 External Architecture Specification +// (3.2.4. Machine Mode Standard CSRs) + +#define MVENDORID_VALUE 0x0 +#define MARCHID_VALUE 0x8 +#define MIMPID_VALUE 0x19083000 + +// MSTATUS masks +// +#define MSTATUS_MIE (0x1 << 3) +#define MSTATUS_MPIE (0x1 << 7) +#define MSTATUS_MPP (0x3 << 11) + +// MISA +// +#define MISA_RVC (0x1 << 2) +#define MISA_RVE (0x1 << 4) +#define MISA_RVI (0x1 << 8) +#define MISA_RVM (0x1 << 12) +#define MISA_RVX (0x1 << 23) +#define MISA_MXL (0x3 << 30) + +// MIE +// +#define MIE_MSIE (0x1 << 3) +#define MIE_MTIE (0x1 << 7) +#define MIE_MEIE (0x1 << 11) + +// MTVEC +// +#define MTVEC_MODE (0x3 << 0) +#define MTVEC_MODE_DIRECT (0x0 << 0) +#define MTVEC_MODE_VECTORED (0x1 << 0) +#define MTVEC_BASE (0xFFFFFFFF & 0xFFFFFFC0) + +// MSCRATCH +// MEPC + +// MCAUSE +// +#define MCAUSE_EC (0xF << 0) +#define MCAUSE_INT (0x1 << 31) +#define MCAUSE_INSTRUCTION_ADDRESS_MISALIGNED 0 +#define MCAUSE_INSTRUCTION_ACCESS_FAULT 1 +#define MCAUSE_ILLEGAL_INSTRUCTION 2 +#define MCAUSE_BREAKPOINT 3 +#define MCAUSE_LOAD_ADDRESS_MISSALIGNED 4 +#define MCAUSE_LOAD_ACCESS_FAULT 5 +#define MCAUSE_STORE_ADDRESS_MISALIGNED 6 +#define MCAUSE_STORE_ACCESS_FAULT 7 +// +#define MCAUSE_ECALL_FROM_M_MODE 11 +// +#define MCAUSE_MACHINE_SOFTWARE_INTERRUPT 0x80000003 +#define MCAUSE_MACHINE_TIMER_INTERRUPT 0x80000007 +#define MCAUSE_MACHINE_EXTERNAL_INTERRUPT 0x8000000B + +// MTVAL + +// MIP +// +#define MIP_MSIP (0x1 << 3) +#define MIP_MTIP (0x1 << 7) +#define MIP_MEIP (0x1 << 11) + +// MCYCLE +// MCYCLEH +// MINSTRET +// MINSTRETH + +// MCOUNTEN +#define MCOUNTEN_CY (1 << 0) +#define MCOUNTEN_IR (1 << 2) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cores/arduino/mik32/shared/include/scr1_specific.h b/cores/arduino/mik32/shared/include/scr1_specific.h new file mode 100644 index 0000000..5701e2f --- /dev/null +++ b/cores/arduino/mik32/shared/include/scr1_specific.h @@ -0,0 +1,35 @@ +#ifndef __SCR1__SPECIFIC +#define __SCR1__SPECIFIC + +#ifdef __cplusplus +extern "C" { +#endif + +#define mcounten 0x7E0 + +// Memory-mapped registers +#define mtime_base 0x00490000 +#define mtime_ctrl_offs 0x00 +#define mtime_div_offs 0x04 +#define mtime_offs 0x08 +#define mtimeh_offs 0x0C +#define mtimecmp_offs 0x10 +#define mtimecmph_offs 0x14 +#define mtime_ctrl mtime_base+mtime_ctrl_offs +#define mtime_div mtime_base+mtime_div_offs +#define mtime mtime_base+mtime_offs +#define mtimeh mtime_base+mtimeh_offs +#define mtimecmp mtime_base+mtimecmp_offs +#define mtimecmph mtime_base+mtimecmph_offs + +#define SCR1_MTIME_CTRL_EN 0 +#define SCR1_MTIME_CTRL_CLKSRC 1 + +#define SCR1_MTIME_CTRL_WR_MASK 0x3 +#define SCR1_MTIME_DIV_WR_MASK 0x3FF + +#ifdef __cplusplus +} +#endif + +#endif // _SCR1__SPECIFIC diff --git a/cores/arduino/mik32/shared/ldscripts/eeprom.ld b/cores/arduino/mik32/shared/ldscripts/eeprom.ld new file mode 100644 index 0000000..e4280d1 --- /dev/null +++ b/cores/arduino/mik32/shared/ldscripts/eeprom.ld @@ -0,0 +1,92 @@ + +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") +OUTPUT_ARCH(riscv) + +ENTRY(_start) + + +MEMORY { + rom (RX): ORIGIN = 0x01000000, LENGTH = 8K + ram (RWX): ORIGIN = 0x02000000, LENGTH = 16K +} + +STACK_SIZE = 1024; + +CL_SIZE = 16; + +SECTIONS { + .text ORIGIN(rom) : { + PROVIDE(__TEXT_START__ = .); + *crt0.o(.text .text.*) + *(.text.smallsysteminit) + *(.text.SmallSystemInit) + . = ORIGIN(rom) + 0xC0; + KEEP(*crt0.o(.trap_text)) + + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + . = ALIGN(CL_SIZE); + PROVIDE(__TEXT_END__ = .); + } >rom + + .data : + AT( __TEXT_END__ ) { + PROVIDE(__DATA_START__ = .); + _gp = .; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(.data .data.*) + . = ALIGN(CL_SIZE); + } >ram + + __DATA_IMAGE_START__ = LOADADDR(.data); + __DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data); + ASSERT(__DATA_IMAGE_END__ < ORIGIN(rom) + LENGTH(rom), "Data image overflows rom section") + + /* thread-local data segment */ + .tdata : { + PROVIDE(_tls_data = .); + PROVIDE(_tdata_begin = .); + *(.tdata .tdata.*) + PROVIDE(_tdata_end = .); + . = ALIGN(CL_SIZE); + } >ram + + .tbss : { + PROVIDE(__BSS_START__ = .); + *(.tbss .tbss.*) + . = ALIGN(CL_SIZE); + PROVIDE(_tbss_end = .); + } >ram + + /* bss segment */ + .sbss : { + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } >ram + + .bss : { + *(.bss .bss.*) + . = ALIGN(CL_SIZE); + PROVIDE(__BSS_END__ = .); + } >ram + + _end = .; + PROVIDE(__end = .); + + /* End of uninitalized data segement */ + + .stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : { + FILL(0); + PROVIDE(__STACK_START__ = .); + . += STACK_SIZE; + PROVIDE(__C_STACK_TOP__ = .); + PROVIDE(__STACK_END__ = .); + } >ram + + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +} diff --git a/cores/arduino/mik32/shared/ldscripts/link_boot_spifi.ld b/cores/arduino/mik32/shared/ldscripts/link_boot_spifi.ld new file mode 100644 index 0000000..d3c0a40 --- /dev/null +++ b/cores/arduino/mik32/shared/ldscripts/link_boot_spifi.ld @@ -0,0 +1,98 @@ + +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") +OUTPUT_ARCH(riscv) + +ENTRY(_start) + + +MEMORY { + boot : ORIGIN = 0x00000000, LENGTH = 16K + ram : ORIGIN = 0x02000000, LENGTH = 16K + spifi : ORIGIN = 0x80000000, LENGTH = DEFINED(SPIFI_LENGTH) ? SPIFI_LENGTH : 256M +} + +STACK_SIZE = 1024; + +CL_SIZE = 16; + +SECTIONS { + .boot : + AT(ORIGIN(spifi)) { + PROVIDE(__BOOT_START__ = .); + *crt0.o(.text .text.*) + *(.boot) + . = ALIGN(CL_SIZE); + PROVIDE(__BOOT_END__ = .); + } > boot + + + /* Placeholder for boot section */ + .text ORIGIN(spifi) + SIZEOF(.boot) : { + + PROVIDE(__TEXT_START__ = .); + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + . = ALIGN(CL_SIZE); + PROVIDE(__TEXT_END__ = .); + } > spifi + + .data : + AT( ALIGN(__TEXT_END__, CL_SIZE) ) { + PROVIDE(__DATA_START__ = .); + _gp = .; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(.data .data.*) + . = ALIGN(CL_SIZE); + } > ram + + __DATA_IMAGE_START__ = LOADADDR(.data); + __DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data); + ASSERT(__DATA_IMAGE_END__ < ORIGIN(spifi) + LENGTH(spifi), "Data image overflows spifi section") + + /* bss segment */ + .sbss : { + PROVIDE(__BSS_START__ = .); + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } > ram + + .bss : { + *(.bss .bss.*) + . = ALIGN(CL_SIZE); + PROVIDE(__BSS_END__ = .); + } > ram + + + /* Code intended to be copied to RAM before execution */ + .ram_text : + AT( ALIGN(__DATA_IMAGE_END__, CL_SIZE) ) { + PROVIDE(__RAM_TEXT_START__ = .); + *(.ram_text) + . = ALIGN(CL_SIZE); + PROVIDE(__RAM_TEXT_END__ = .); + } > ram + + __RAM_TEXT_IMAGE_START__ = LOADADDR(.ram_text); + __RAM_TEXT_IMAGE_END__ = LOADADDR(.ram_text) + SIZEOF(.ram_text); + ASSERT(__RAM_TEXT_IMAGE_END__ < ORIGIN(spifi) + LENGTH(spifi), "RAM text image overflows spifi section") + + _end = .; + PROVIDE(__end = .); + + /* End of uninitalized data segement */ + + .stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : { + FILL(0); + PROVIDE(__STACK_START__ = .); + . += STACK_SIZE; + PROVIDE(__C_STACK_TOP__ = .); + PROVIDE(__STACK_END__ = .); + } > ram + + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +} diff --git a/cores/arduino/mik32/shared/ldscripts/ram.ld b/cores/arduino/mik32/shared/ldscripts/ram.ld new file mode 100644 index 0000000..29049ce --- /dev/null +++ b/cores/arduino/mik32/shared/ldscripts/ram.ld @@ -0,0 +1,91 @@ + +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") +OUTPUT_ARCH(riscv) + +ENTRY(_start) + + +MEMORY { + ram (RWX): ORIGIN = 0x02000000, LENGTH = 16K +} + +STACK_SIZE = 1024; + +CL_SIZE = 16; + +SECTIONS { + .text ORIGIN(ram) : { + PROVIDE(__TEXT_START__ = .); + *crt0.o(.text .text.*) + *(.text.smallsysteminit) + *(.text.SmallSystemInit) + . = ORIGIN(ram) + 0xC0; + KEEP(*crt0.o(.trap_text)) + + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + . = ALIGN(CL_SIZE); + PROVIDE(__TEXT_END__ = .); + } >ram + + .data : + AT( __TEXT_END__ ) { + PROVIDE(__DATA_START__ = .); + _gp = .; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(.data .data.*) + . = ALIGN(CL_SIZE); + } >ram + + __DATA_IMAGE_START__ = LOADADDR(.data); + __DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data); + ASSERT(__DATA_IMAGE_END__ < ORIGIN(ram) + LENGTH(ram) - STACK_SIZE, "Data image overflows ram section") + + /* thread-local data segment */ + .tdata : { + PROVIDE(_tls_data = .); + PROVIDE(_tdata_begin = .); + *(.tdata .tdata.*) + PROVIDE(_tdata_end = .); + . = ALIGN(CL_SIZE); + } >ram + + .tbss : { + PROVIDE(__BSS_START__ = .); + *(.tbss .tbss.*) + . = ALIGN(CL_SIZE); + PROVIDE(_tbss_end = .); + } >ram + + /* bss segment */ + .sbss : { + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } >ram + + .bss : { + *(.bss .bss.*) + . = ALIGN(CL_SIZE); + PROVIDE(__BSS_END__ = .); + } >ram + + _end = .; + PROVIDE(__end = .); + + /* End of uninitalized data segement */ + + .stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : { + FILL(0); + PROVIDE(__STACK_START__ = .); + . += STACK_SIZE; + PROVIDE(__C_STACK_TOP__ = .); + PROVIDE(__STACK_END__ = .); + } >ram + + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +} diff --git a/cores/arduino/mik32/shared/ldscripts/ram2.ld b/cores/arduino/mik32/shared/ldscripts/ram2.ld new file mode 100644 index 0000000..b4e9486 --- /dev/null +++ b/cores/arduino/mik32/shared/ldscripts/ram2.ld @@ -0,0 +1,92 @@ + +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") +OUTPUT_ARCH(riscv) + +ENTRY(_start) + + +MEMORY { + rom (RX): ORIGIN = 0x02000000, LENGTH = 8K + ram (RWX): ORIGIN = 0x02002000, LENGTH = 8K +} + +STACK_SIZE = 1024; + +CL_SIZE = 16; + +SECTIONS { + .text ORIGIN(rom) : { + PROVIDE(__TEXT_START__ = .); + *crt0.o(.text .text.*) + *(.text.smallsysteminit) + *(.text.SmallSystemInit) + . = ORIGIN(rom) + 0xC0; + KEEP(*crt0.o(.trap_text)) + + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + . = ALIGN(CL_SIZE); + PROVIDE(__TEXT_END__ = .); + } >rom + + .data : + AT( __TEXT_END__ ) { + PROVIDE(__DATA_START__ = .); + _gp = .; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(.data .data.*) + . = ALIGN(CL_SIZE); + } >ram + + __DATA_IMAGE_START__ = LOADADDR(.data); + __DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data); + ASSERT(__DATA_IMAGE_END__ < ORIGIN(rom) + LENGTH(rom), "Data image overflows rom section") + + /* thread-local data segment */ + .tdata : { + PROVIDE(_tls_data = .); + PROVIDE(_tdata_begin = .); + *(.tdata .tdata.*) + PROVIDE(_tdata_end = .); + . = ALIGN(CL_SIZE); + } >ram + + .tbss : { + PROVIDE(__BSS_START__ = .); + *(.tbss .tbss.*) + . = ALIGN(CL_SIZE); + PROVIDE(_tbss_end = .); + } >ram + + /* bss segment */ + .sbss : { + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } >ram + + .bss : { + *(.bss .bss.*) + . = ALIGN(CL_SIZE); + PROVIDE(__BSS_END__ = .); + } >ram + + _end = .; + PROVIDE(__end = .); + + /* End of uninitalized data segement */ + + .stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : { + FILL(0); + PROVIDE(__STACK_START__ = .); + . += STACK_SIZE; + PROVIDE(__C_STACK_TOP__ = .); + PROVIDE(__STACK_END__ = .); + } >ram + + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +} diff --git a/cores/arduino/mik32/shared/ldscripts/spifi.ld b/cores/arduino/mik32/shared/ldscripts/spifi.ld new file mode 100644 index 0000000..6a75d08 --- /dev/null +++ b/cores/arduino/mik32/shared/ldscripts/spifi.ld @@ -0,0 +1,92 @@ + +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") +OUTPUT_ARCH(riscv) + +ENTRY(_start) + + +MEMORY { + rom (RX): ORIGIN = 0x80000000, LENGTH = 256M + ram (RWX): ORIGIN = 0x02000000, LENGTH = 16K +} + +STACK_SIZE = 1024; + +CL_SIZE = 16; + +SECTIONS { + .text ORIGIN(rom) : { + PROVIDE(__TEXT_START__ = .); + *crt0.S.o(.text .text.*) + *(.text.smallsysteminit) + *(.text.SmallSystemInit) + . = 0xC0; + KEEP(*crt0.S.o(.trap_text)) + + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + . = ALIGN(CL_SIZE); + PROVIDE(__TEXT_END__ = .); + } >rom + + .data : + AT( __TEXT_END__ ) { + PROVIDE(__DATA_START__ = .); + _gp = .; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(.data .data.*) + . = ALIGN(CL_SIZE); + } >ram + + __DATA_IMAGE_START__ = LOADADDR(.data); + __DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data); + ASSERT(__DATA_IMAGE_END__ < ORIGIN(rom) + LENGTH(rom), "Data image overflows rom section") + + /* thread-local data segment */ + .tdata : { + PROVIDE(_tls_data = .); + PROVIDE(_tdata_begin = .); + *(.tdata .tdata.*) + PROVIDE(_tdata_end = .); + . = ALIGN(CL_SIZE); + } >ram + + .tbss : { + PROVIDE(__BSS_START__ = .); + *(.tbss .tbss.*) + . = ALIGN(CL_SIZE); + PROVIDE(_tbss_end = .); + } >ram + + /* bss segment */ + .sbss : { + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } >ram + + .bss : { + *(.bss .bss.*) + . = ALIGN(CL_SIZE); + PROVIDE(__BSS_END__ = .); + } >ram + + _end = .; + PROVIDE(__end = .); + + /* End of uninitalized data segement */ + + .stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : { + FILL(0); + PROVIDE(__STACK_START__ = .); + . += STACK_SIZE; + PROVIDE(__C_STACK_TOP__ = .); + PROVIDE(__STACK_END__ = .); + } >ram + + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +} diff --git a/cores/arduino/mik32/shared/ldscripts/spifi_cpp.ld b/cores/arduino/mik32/shared/ldscripts/spifi_cpp.ld new file mode 100644 index 0000000..a018295 --- /dev/null +++ b/cores/arduino/mik32/shared/ldscripts/spifi_cpp.ld @@ -0,0 +1,114 @@ + +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") +OUTPUT_ARCH(riscv) + +ENTRY(_start) + + +MEMORY { + rom (RX): ORIGIN = 0x80000000, LENGTH = 256M + ram (RWX): ORIGIN = 0x02000000, LENGTH = 16K +} + +STACK_SIZE = 1024; +HEAP_SIZE = 1024; + +CL_SIZE = 16; + +SECTIONS { + .text ORIGIN(rom) : { + PROVIDE(__TEXT_START__ = .); + *crt0.S.o(.text .text.*) + *(.text.smallsysteminit) + *(.text.SmallSystemInit) + . = ORIGIN(rom) + 0xC0; + KEEP(*crt0.S.o(.trap_text)) + + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + . = ALIGN(CL_SIZE); + } >rom + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + PROVIDE(__TEXT_END__ = .); + } >rom AT>rom + + .data : + AT( __TEXT_END__ ) { + PROVIDE(__DATA_START__ = .); + _gp = .; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) + *(.sdata .sdata.* .sdata* .sdata*.* .gnu.linkonce.s.*) + *(.data .data.*) + . = ALIGN(CL_SIZE); + } >ram + + __DATA_IMAGE_START__ = LOADADDR(.data); + __DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data); + ASSERT(__DATA_IMAGE_END__ < ORIGIN(rom) + LENGTH(rom), "Data image overflows rom section") + + /* thread-local data segment */ + .tdata : { + PROVIDE(_tls_data = .); + PROVIDE(_tdata_begin = .); + *(.tdata .tdata.*) + PROVIDE(_tdata_end = .); + . = ALIGN(CL_SIZE); + } >ram + + .tbss : { + PROVIDE(__BSS_START__ = .); + *(.tbss .tbss.*) + . = ALIGN(CL_SIZE); + PROVIDE(_tbss_end = .); + } >ram + + /* bss segment */ + .sbss : { + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } >ram + + .bss : { + *(.bss .bss.*) + . = ALIGN(CL_SIZE); + PROVIDE(__BSS_END__ = .); + } >ram + + .heap : { + PROVIDE(__heap_start = .); + . += HEAP_SIZE; + . = ALIGN(CL_SIZE); + PROVIDE(__heap_end = .); + } >ram + + _end = .; + PROVIDE(__end = .); + + /* End of uninitalized data segement */ + + .stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : { + FILL(0); + PROVIDE(__STACK_START__ = .); + . += STACK_SIZE; + PROVIDE(__C_STACK_TOP__ = .); + PROVIDE(__STACK_END__ = .); + } >ram + + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +} diff --git a/cores/arduino/mik32/shared/libs/dma_lib.c b/cores/arduino/mik32/shared/libs/dma_lib.c new file mode 100644 index 0000000..b4f0097 --- /dev/null +++ b/cores/arduino/mik32/shared/libs/dma_lib.c @@ -0,0 +1,133 @@ + + +#include "dma_lib.h" + + + + +void DMA_StartNewTask(DMA_CONFIG_TypeDef* dma, uint32_t channel_index, + uint32_t control_value, + uint32_t source_address, uint32_t destination_address, uint32_t length) +{ + + + dma->CHANNELS[channel_index].SRC = source_address; + dma->CHANNELS[channel_index].DST = destination_address; + dma->CHANNELS[channel_index].LEN = length; + dma->CHANNELS[channel_index].CFG = control_value | DMA_CH_CFG_ENABLE_M; +} + +void DMA_Wait (DMA_CONFIG_TypeDef* dma, uint32_t channel_index) +{ + + // uint32_t channel_bits = 0; + + while ((dma->CONFIG_STATUS & ((1 << channel_index) << DMA_STATUS_READY_S)) == 0) ; +} + + + + + +/* +void DMA_StartNewLlTask(DMA_CONFIG_TypeDef* dma, uint32_t channel_index, + uint32_t task_address) +{ + dma->ENABLE_CH &= ~(1 << channel_index); + dma->CHANNELS[channel_index].DMA_Cntrl = DMA_CONTROL_linkListEnable_M; + dma->CHANNELS[channel_index].SRC_DESCRIPTOR = task_address; + dma->ENABLE_CH |= (1 << channel_index); +} + + +//�������� ��������� �������� � ��������� +unsigned int DMA_Wait_Timeout (DMA_CONFIG_TypeDef* dma, uint32_t channel_index) { + unsigned int TIMEOUT = 30000; + unsigned int wait = 0; + if ((dma->ENABLE_CH & (1 << channel_index)) == 0) { + return 0; + } + + uint32_t channel_bits = 0; + channel_bits |= (1 << channel_index) << DMA_DONE_S; + channel_bits |= (1 << channel_index) << DMA_PERROR_SRC_S; + channel_bits |= (1 << channel_index) << DMA_PERROR_DST_S; + + //�������� ��������� �������� � ��������� + for(wait=0;waitDMA_STATUS & channel_bits) != 0) { + break; + } + } + if(wait==TIMEOUT) { + return 0; + } + return 1; +} + + + +//�������� ���������� ������� � ������ +unsigned int DMA_ChnDone (DMA_CONFIG_TypeDef* dma, uint32_t channel_index) { + if ((dma->ENABLE_CH & (1 << channel_index)) == 0) { + return DMA_CHN_DONE_ERROR_ENABLE; + } + + uint32_t channel_bits = 0; + + //�������� ���������� + channel_bits = (1 << channel_index) << DMA_DONE_S; + if((dma->DMA_STATUS & channel_bits) != 0) { + return DMA_CHN_DONE_ERROR_NO; + } + + //������ ��������� + channel_bits = (1 << channel_index) << DMA_PERROR_SRC_S; + if((dma->DMA_STATUS & channel_bits) != 0) { + return DMA_CHN_DONE_ERROR_SRC; + } + + //������ ��������� + channel_bits = (1 << channel_index) << DMA_PERROR_DST_S; + if((dma->DMA_STATUS & channel_bits) != 0) { + return DMA_CHN_DONE_ERROR_DST; + } + + return DMA_CHN_DONE_NOT_DONE; +} + + + +//�������� ���������� ������� �� ���� ������� +unsigned int DMA_AllChnDone (DMA_CONFIG_TypeDef* dma) { + if (dma->ENABLE_CH != DMA_ENABLE_M) { + return DMA_CHN_DONE_ERROR_ENABLE; + } + + //�������� ���������� + if((dma->DMA_STATUS & DMA_DONE_M) == DMA_DONE_M) { + return DMA_CHN_DONE_ERROR_NO; + } + + //������ ��������� + if((dma->DMA_STATUS & DMA_PERROR_SRC_M) != 0) { + return DMA_CHN_DONE_ERROR_SRC; + } + + //������ ��������� + if((dma->DMA_STATUS & DMA_PERROR_DST_M) != 0) { + return DMA_CHN_DONE_ERROR_DST; + } + + return DMA_CHN_DONE_NOT_DONE; +} + + + + +*/ + + + + + diff --git a/cores/arduino/mik32/shared/libs/dma_lib.h b/cores/arduino/mik32/shared/libs/dma_lib.h new file mode 100644 index 0000000..7cf7517 --- /dev/null +++ b/cores/arduino/mik32/shared/libs/dma_lib.h @@ -0,0 +1,54 @@ +#ifndef DMA_LIB_H_INCLUDED +#define DMA_LIB_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/* +#define DMA_CHN_DONE_ERROR_NO 0 +#define DMA_CHN_DONE_ERROR_SRC 1 +#define DMA_CHN_DONE_ERROR_DST 2 +#define DMA_CHN_DONE_ERROR_ENABLE 3 +#define DMA_CHN_DONE_NOT_DONE 4 +*/ +#include "dma_config.h" + +/* + Следует пользоваться структурами задач для DMA так, чтобы они не выходили + из области видимости и память под ними не использовалась для других целей, + пока DMA точно не закончил работать с ними. + Например, это относится к созданию переменных этого типа в стеке. +*/ +typedef struct +{ + uint32_t SrcAddress; + uint32_t DestAddress; + uint32_t LengthBytes; + uint32_t Control; +} DMA_Task_t; + + +void DMA_StartNewTask(DMA_CONFIG_TypeDef* dma, uint32_t channel_index, + uint32_t control_value, + uint32_t source_address, uint32_t destination_address, uint32_t length); + + + + +void DMA_Wait(DMA_CONFIG_TypeDef* dma, uint32_t channel_index); + +/* +void DMA_StartNewLlTask(DMA_CONFIG_TypeDef* dma, uint32_t channel_index, uint32_t task_address); + +unsigned int DMA_Wait_Timeout (DMA_CONFIG_TypeDef* dma, uint32_t channel_index); +unsigned int DMA_ChnDone (DMA_CONFIG_TypeDef* dma, uint32_t channel_index); +unsigned int DMA_AllChnDone (DMA_CONFIG_TypeDef* dma); +*/ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/cores/arduino/mik32/shared/libs/rtc_lib.c b/cores/arduino/mik32/shared/libs/rtc_lib.c new file mode 100644 index 0000000..ade58b5 --- /dev/null +++ b/cores/arduino/mik32/shared/libs/rtc_lib.c @@ -0,0 +1,132 @@ + +#include "rtc_lib.h" + +void RTC_Enable(RTC_TypeDef* rtc) +{ + rtc->CTRL |= RTC_CTRL_EN_M; +} + +void RTC_Disable(RTC_TypeDef* rtc) +{ + rtc->CTRL &= ~RTC_CTRL_EN_M; +} + +void RTC_ClearAlarmFlag(RTC_TypeDef* rtc) +{ + rtc->CTRL &= ~RTC_CTRL_ALRM_M; +} + + +void RTC_WaitDataLoading(RTC_TypeDef* rtc) +{ + while(rtc->CTRL & RTC_CTRL_FLAG_M) ; +} + +void RTC_WaitAlarm(RTC_TypeDef* rtc) +{ + while((rtc->CTRL & RTC_CTRL_ALRM_M) == 0) ; +} + + +void RTC_WriteTimeToReg(RTC_TypeDef* rtc, volatile uint32_t* reg, + uint8_t hours, uint8_t minutes, uint8_t seconds, + uint16_t miliseconds, uint8_t day_of_week +) +{ + *reg = + ((day_of_week << RTC_TIME_DOW_S) & RTC_TIME_DOW_M) | + (((hours / 10) << RTC_TIME_TH_S) & RTC_TIME_TH_M) | + (((hours % 10) << RTC_TIME_H_S) & RTC_TIME_H_M) | + (((minutes / 10) << RTC_TIME_TM_S) & RTC_TIME_TM_M) | + (((minutes % 10) << RTC_TIME_M_S) & RTC_TIME_M_M) | + (((seconds / 10) << RTC_TIME_TS_S) & RTC_TIME_TS_M) | + (((seconds % 10) << RTC_TIME_S_S) & RTC_TIME_S_M) | + (((miliseconds / 100) << RTC_TIME_TOS_S) & RTC_TIME_TOS_M); +} + + +void RTC_LoadTime(RTC_TypeDef* rtc, + uint8_t hours, uint8_t minutes, uint8_t seconds, + uint16_t miliseconds, uint8_t day_of_week +) +{ + RTC_WriteTimeToReg(rtc, &(rtc->TIME), + hours, minutes, seconds, miliseconds, day_of_week); + RTC_WaitDataLoading(rtc); +} + + +void RTC_LoadTimeAlarm(RTC_TypeDef* rtc, + uint8_t hours, uint8_t minutes, uint8_t seconds, + uint16_t miliseconds, uint8_t day_of_week +) +{ + RTC_WriteTimeToReg(rtc, &(rtc->TALRM), + hours, minutes, seconds, miliseconds, day_of_week); + RTC_WaitDataLoading(rtc); +} + + + +void RTC_WriteDateToReg(RTC_TypeDef* rtc, volatile uint32_t* reg, + uint8_t date, uint8_t month, uint16_t year +) +{ + *reg = + (((date / 10) << RTC_DATE_TD_S) & RTC_DATE_TD_M) | + (((date % 10) << RTC_DATE_D_S) & RTC_DATE_D_M) | + (((month / 10) << RTC_DATE_TM_S) & RTC_DATE_TM_M) | + (((month % 10) << RTC_DATE_M_S) & RTC_DATE_M_M) | + (((year % 10) << RTC_DATE_Y_S) & RTC_DATE_Y_M) | + (((year / 10 % 10) << RTC_DATE_TY_S) & RTC_DATE_TY_M) | + (((year /100 % 10) << RTC_DATE_C_S) & RTC_DATE_C_M) | + (((year / 1000) << RTC_DATE_TC_S) & RTC_DATE_TC_M); +} + +void RTC_LoadDate(RTC_TypeDef* rtc, + uint8_t date, uint8_t month, uint16_t year +) +{ + RTC_WriteDateToReg(rtc, &(rtc->DATE), + date, month, year); + RTC_WaitDataLoading(rtc); +} + + +void RTC_LoadDateAlarm(RTC_TypeDef* rtc, + uint8_t date, uint8_t month, uint16_t year +) +{ + RTC_WriteDateToReg(rtc, &(rtc->DALRM), + date, month, year); + RTC_WaitDataLoading(rtc); +} + + +void RTC_SetAlarmMask(RTC_TypeDef* rtc, + bool date, bool month, bool year, + bool hours, bool minutes, bool seconds, + bool miliseconds, bool day_of_week +) +{ + uint32_t temp; + + temp = rtc->TALRM; + temp &= ~(RTC_TALRM_CDOW_M | RTC_TALRM_CH_M | + RTC_TALRM_CM_M | RTC_TALRM_CS_M | RTC_TALRM_CTOS_M); + temp |= (hours ? RTC_TALRM_CH_M : 0) | + (minutes ? RTC_TALRM_CM_M : 0) | + (seconds ? RTC_TALRM_CS_M : 0) | + (miliseconds ? RTC_TALRM_CTOS_M : 0) | + (day_of_week ? RTC_TALRM_CDOW_M : 0); + rtc->TALRM = temp; + + temp = rtc->DALRM; + temp &= ~(RTC_DALRM_CC_M | RTC_DALRM_CY_M | + RTC_DALRM_CM_M | RTC_DALRM_CD_M); + temp |= (date ? RTC_DALRM_CD_M : 0) | + (month ? RTC_DALRM_CM_M : 0) | + (year ? (RTC_DALRM_CC_M | RTC_DALRM_CY_M) : 0); + rtc->DALRM = temp; + +} \ No newline at end of file diff --git a/cores/arduino/mik32/shared/libs/rtc_lib.h b/cores/arduino/mik32/shared/libs/rtc_lib.h new file mode 100644 index 0000000..b059093 --- /dev/null +++ b/cores/arduino/mik32/shared/libs/rtc_lib.h @@ -0,0 +1,170 @@ +#ifndef RTC_LIB_H_INCLUDED +#define RTC_LIB_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file + Библиотека для работы с контроллером часов реального времени RTC. +*/ + +#include "inttypes.h" +#include "stdbool.h" + +#include "rtc.h" + + +/** Запускает RTC + + \note Дата и время должны быть заданы предварительно. + + \param rtc Указатель для доступа к RTC +*/ +void RTC_Enable(RTC_TypeDef* rtc); + +/** Останавливает RTC + + \param rtc Указатель для доступа к RTC +*/ +void RTC_Disable(RTC_TypeDef* rtc); + +/** Сбрасывает флаг будильника + + \note Если текущее время все еще подходит + для срабатвания будильника, то флаг выставится вновь. + Чтобы этого избежать, можно, например, + обнулить маску будильника. + + \param rtc Указатель для доступа к RTC +*/ +void RTC_ClearAlarmFlag(RTC_TypeDef* rtc); + + +/** Ожидает завершение синхронизации после записи в регистры RTC + + Функция опрашивает поле FLAG регистра RRTC_CTRL, + пока он не станет равным 0. + + \note Когда флаг равен 1, + то идет синхронизация данных между доменами + и нельзя производить запись в другие регистры RTC. + + \param rtc Указатель для доступа к RTC +*/ +void RTC_WaitDataLoading(RTC_TypeDef* rtc); + + +/** Ожидает срабатывания будильника + + Функция опрашивает флаг ALRM регистра RRTC_CTRL, + пока он не станет равным 1. + + \param rtc Указатель для доступа к RTC +*/ +void RTC_WaitAlarm(RTC_TypeDef* rtc); + + +/** Загружает время и день недели + + \warning Загружаемые значения должны быть корректными. + Функция не производит их проверку. + + \note RTC работает с сотнями милисекунд. + Значения не кратные 100 будут округляются вниз. + + \param rtc Указатель для доступа к RTC + + \param hours часы + \param minutes минуты + \param seconds секунды + \param miliseconds милисекунды + \param day_of_week порядковый номер дня недели +*/ +void RTC_LoadTime(RTC_TypeDef* rtc, + uint8_t hours, uint8_t minutes, uint8_t seconds, + uint16_t miliseconds, uint8_t day_of_week +); + +/** Загружает время и день недели для будильника + + \warning Загружаемые значения должны быть корректными. + Функция не производит их проверку. + + \note RTC работает с сотнями милисекунд. + Значения не кратные 100 округляются вниз. + + \param rtc Указатель для доступа к RTC + + \param hours часы + \param minutes минуты + \param seconds секунды + \param miliseconds милисекунды + \param day_of_week порядковый номер дня недели +*/ +void RTC_LoadTimeAlarm(RTC_TypeDef* rtc, + uint8_t hours, uint8_t minutes, uint8_t seconds, + uint16_t miliseconds, uint8_t day_of_week +); + + +/** Загружает дату + + \warning Загружаемые значения должны быть корректными. + Функция не производит их проверку. + + \param rtc Указатель для доступа к RTC + + \param date число + \param month месяц + \param year год +*/ +void RTC_LoadDate(RTC_TypeDef* rtc, + uint8_t date, uint8_t month, uint16_t year +); + + +/** Загружает дату будильника + + \warning Загружаемые значения должны быть корректными. + Функция не производит их проверку. + + \param rtc Указатель для доступа к RTC + + \param date число + \param month месяц + \param year год +*/ +void RTC_LoadDateAlarm(RTC_TypeDef* rtc, + uint8_t date, uint8_t month, uint16_t year +); + + +/** Устанавливает маску будильника + + Если значение маски равно true, + то поле участвует в сравнении при + определении срабатывания будильника. + + \param rtc Указатель для доступа к RTC + + \param date число + \param month месяц + \param year год + \param hours часы + \param minutes минуты + \param seconds секунды + \param miliseconds милисекунды + \param day_of_week порядковый номер дня недели +*/ +void RTC_SetAlarmMask(RTC_TypeDef* rtc, + bool date, bool month, bool year, + bool hours, bool minutes, bool seconds, + bool miliseconds, bool day_of_week +); + +#ifdef __cplusplus +} +#endif + +#endif // RTC_LIB_H_INCLUDED diff --git a/cores/arduino/mik32/shared/libs/spi_lib.c b/cores/arduino/mik32/shared/libs/spi_lib.c new file mode 100644 index 0000000..2c08e26 --- /dev/null +++ b/cores/arduino/mik32/shared/libs/spi_lib.c @@ -0,0 +1,105 @@ + +#include "spi_lib.h" + + +void SPI_CS_Enable(SPI_TypeDef* SPI, unsigned int CS_M) { + SPI->CONFIG = (SPI->CONFIG & ~SPI_CONFIG_CS_M) | CS_M; +} + + +void SPI_CS_Disable(SPI_TypeDef* SPI, unsigned int CS_M) { + SPI->CONFIG = (SPI->CONFIG & ~SPI_CONFIG_CS_M) | SPI_CONFIG_CS_NONE_M; +} + + +void SPI_Init(SPI_TypeDef* s, uint32_t config) +{ + s->ENABLE = 0; + SPI_ClearRxBuffer(s); + s->CONFIG = config; + s->ENABLE = SPI_ENABLE_M; +} + + +void SPI_WaitTxNotFull(SPI_TypeDef* s) +{ + while ((s->INT_STATUS & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M) == 0) ; +} + +int SPI_TimeoutWaitTxNotFull(SPI_TypeDef* s, uint32_t timeout) +{ + while ((s->INT_STATUS & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M) == 0) + { + if (timeout-- == 0) + { + return -1; + } + } + return 0; +} + + +void SPI_WaitRxNotEmpty(SPI_TypeDef* s) +{ + while ((s->INT_STATUS & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M) == 0) ; +} + + +int SPI_TimeoutWaitRxNotEmpty(SPI_TypeDef* s, uint32_t timeout) +{ + while ((s->INT_STATUS & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M) == 0) + { + if (timeout-- == 0) + { + return -1; + } + } + return 0; +} + + +void SPI_ClearRxBuffer(SPI_TypeDef* s) +{ + volatile uint32_t dummy; + while ((s->INT_STATUS & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M) != 0) + { + dummy = s->RXDATA; + } + (void) dummy; +} + + +void SPI_Exchange(SPI_TypeDef* s, uint8_t* input_bytes, uint8_t* output_bytes, uint32_t count) +{ + while (count-- > 0) + { + SPI_WaitTxNotFull(s); + s->TXDATA = *input_bytes++; + SPI_WaitRxNotEmpty(s); + if (output_bytes != 0) + { + *output_bytes++ = s->RXDATA; + } + else + { + (void)s->RXDATA; + } + } + +} + + + + + + + + + + + + + + + + diff --git a/cores/arduino/mik32/shared/libs/spi_lib.h b/cores/arduino/mik32/shared/libs/spi_lib.h new file mode 100644 index 0000000..84f59b7 --- /dev/null +++ b/cores/arduino/mik32/shared/libs/spi_lib.h @@ -0,0 +1,28 @@ +#ifndef SPI_LIB_H_INCLUDED +#define SPI_LIB_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "spi_.h" + + +void SPI_CS_Enable(SPI_TypeDef* SPI, unsigned int CS_M); +void SPI_CS_Disable(SPI_TypeDef* SPI, unsigned int CS_M); + +void SPI_Init(SPI_TypeDef* s, uint32_t config); +void SPI_WaitTxNotFull(SPI_TypeDef* s); +int SPI_TimeoutWaitTxNotFull(SPI_TypeDef* s, uint32_t timeout); +void SPI_WaitRxNotEmpty(SPI_TypeDef* s); +int SPI_TimeoutWaitRxNotEmpty(SPI_TypeDef* s, uint32_t timeout); +void SPI_ClearRxBuffer(SPI_TypeDef* s); + +void SPI_Exchange(SPI_TypeDef* s, uint8_t* input_bytes, uint8_t* output_bytes, uint32_t count); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/cores/arduino/mik32/shared/libs/uart_lib.c b/cores/arduino/mik32/shared/libs/uart_lib.c new file mode 100644 index 0000000..2fa0711 --- /dev/null +++ b/cores/arduino/mik32/shared/libs/uart_lib.c @@ -0,0 +1,149 @@ + +#include "uart_lib.h" + +__attribute__((weak)) void HAL_UART_MspInit(UART_TypeDef* uart) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + if (uart == UART_0) + { + __HAL_PCC_UART_0_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); + } + + if (uart == UART_1) + { + __HAL_PCC_UART_1_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + } +} + +bool UART_Init(UART_TypeDef* uart, + uint32_t divider, uint32_t control1, + uint32_t control2, uint32_t control3) +{ + HAL_UART_MspInit(uart); + + bool ready; + uint32_t flags; + + if (divider < 16) + { + return false; + } + + uart->CONTROL1 = 0; + uart->DIVIDER = divider; + uart->FLAGS = 0xFFFFFFFF; + + uart->CONTROL2 = control2; + uart->CONTROL3 = control3; + uart->CONTROL1 = control1 | UART_CONTROL1_UE_M; + + do + { + flags = uart->FLAGS; + ready = true; + if(control1 & UART_CONTROL1_RE_M) + { + ready = ready && ((flags & UART_FLAGS_REACK_M) != 0); + } + if(control1 & UART_CONTROL1_TE_M) + { + ready = ready && ((flags & UART_FLAGS_TEACK_M) != 0); + } + } + while (!ready); + + return true; +} + + +bool UART_IsTransmissionFinished(UART_TypeDef* uart) +{ + // if ((uart->FLAGS & UART_FLAGS_TC_M) == 0) // с этим флагом есть какая-то доп задержка в стоп-битах длиной почти с бит + if ((uart->FLAGS & UART_FLAGS_TXE_M) == 0) // а этот не дожидается по факту окончания передачи, зато со стоп-битами все четко + { + return false; + } + else + { + return true; + } +} + +void UART_WaitTransmission(UART_TypeDef* uart) +{ + while (!UART_IsTransmissionFinished(uart)) ; +} + +bool UART_IsTxBufferFreed(UART_TypeDef* uart) +{ + return ((uart->FLAGS & UART_FLAGS_TXE_M) != 0); +} + +void UART_WriteByte(UART_TypeDef* uart, uint16_t byte) +{ + uart->TXDATA = byte; +} + +void UART_Write(UART_TypeDef* uart, uint16_t* byte_array, uint32_t count) +{ + while (count-- > 0) + { + UART_WriteByte(uart, *byte_array++); + UART_WaitTransmission(uart); + } +} + + + +bool UART_IsRxFifoEmpty(UART_TypeDef* uart) +{ + return ((uart->FLAGS & UART_FLAGS_RXNE_M) == 0); +} + +bool UART_IsRxFifoFull(UART_TypeDef* uart) +{ + return (!UART_IsRxFifoEmpty(uart)); +} + +void UART_WaitReceiving(UART_TypeDef* uart) +{ + while (UART_IsRxFifoEmpty(uart)) ; +} + +uint16_t UART_ReadByte(UART_TypeDef* uart) +{ + return (uint16_t)uart->RXDATA; +} + +void UART_Read(UART_TypeDef* uart, uint8_t* byte_array, uint32_t count) +{ + while (count-- > 0) + { + UART_WaitReceiving(uart); + *byte_array++ = UART_ReadByte(uart); + } +} + + +void UART_ClearRxFifo(UART_TypeDef* uart) +{ + while (!UART_IsRxFifoEmpty(uart)) + { + (void)uart->RXDATA; + } +} + +void __attribute__((weak)) xputc(char c) +{ + UART_WriteByte(UART_0, c); + UART_WaitTransmission(UART_0); +} diff --git a/cores/arduino/mik32/shared/libs/uart_lib.h b/cores/arduino/mik32/shared/libs/uart_lib.h new file mode 100644 index 0000000..8cc75de --- /dev/null +++ b/cores/arduino/mik32/shared/libs/uart_lib.h @@ -0,0 +1,135 @@ +#ifndef UART_LIB_H_INCLUDED +#define UART_LIB_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file + Библиотека для работы с контроллером USART. +*/ +#include "mik32_hal_pcc.h" +#include "mik32_hal_gpio.h" +#include "inttypes.h" +#include + +#include "uart.h" +#include "mcu32_memory_map.h" + +void HAL_UART_MspInit(UART_TypeDef* uart); + +/** Инициализирует контроллер USART + + Функция задает режим работы и делитель скорости обмена. + `Скорость обмена = частоты тактирования контроллера / divider` + \warning Делитель должен быть не менее 16 + + \param uart указатель для доступа к UART + \param divider делитель частоты тактирования контроллера + \param control1 значение регистра управления 1 + \param control2 значение регистра управления 2 + \param control3 значение регистра управления 3 + + \return Если инициализация выполнена успешно, + то возвращается true + +*/ +bool UART_Init(UART_TypeDef* uart, uint32_t divider, + uint32_t control1, uint32_t control2, uint32_t control3 +); + + +/** Определяет, активен ли передатчик модуля + + \param uart указатель для доступа к UART + + \return Если передача завершена, возвращается true + */ +bool UART_IsTransmissionFinished(UART_TypeDef* uart); + + +/** Ожидает, пока модуль передаст все записанные в буфер байты + + \param uart указатель для доступа к UART + */ +void UART_WaitTransmission(UART_TypeDef* uart); + + +/** Ожидает, пока модуль примет данные + + \param uart указатель для доступа к UART + */ +void UART_WaitReceiving(UART_TypeDef* uart); + +/** Определяет, был ли байт забран передатчиком из передающего буфера + + \param uart указатель для доступа к UART + + \return Если передающий буфер полон, то возвращается true + */ +bool UART_IsTxBufferFreed(UART_TypeDef* uart); + +/** Определяет, полон ли принимающий буфер + + \param uart указатель для доступа к UART + + \return Если в принимающем буфере есть данные, то возвращается true + */ +bool UART_IsRxFifoFull(UART_TypeDef* uart); + +/** Определяет, пуст ли принимающий буфер + + \param uart указатель для доступа к UART + + \return Если в принимающем буфере нет данных, то возвращается true + */ +bool UART_IsRxFifoEmpty(UART_TypeDef* uart); + +/** Записывает байт в передающий буфер USART + Функция записывает байт в передающий буфер. + Если перед записью буфер полон, + то функция ожидает, пока в буфере не появится место. + + \param uart указатель для доступа к UART + \param byte отправляемые данные +*/ +void UART_WriteByte(UART_TypeDef* uart, uint16_t byte); + +/** Читает байт из принимающего буфер USART + Функция читает байт из принимающего буфера. + Если перед чтением буфер пуст, + то функция ожидает приема нового байта. + + \param uart указатель для доступа к UART + + \return принятые данные +*/ +uint16_t UART_ReadByte(UART_TypeDef* uart); + +/** Записывает массив байт в передающий буфер USART + + \param uart указатель для доступа к UART + \param byte_array + \param count + */ +void UART_Write(UART_TypeDef* uart, uint16_t* byte_array, uint32_t count); + +/** Читает массив байт из принимающего буфер USART + + \param uart указатель для доступа к UART + */ +void UART_Read(UART_TypeDef* uart, uint8_t* byte_array, uint32_t count); + +/** Очищает принимающий буфер + + \param uart указатель для доступа к UART + */ +void UART_ClearRxFifo(UART_TypeDef* uart); + +void __attribute__((weak)) xputc(char c); + +#ifdef __cplusplus +} +#endif + +#endif // UART_LIB_H_INCLUDED diff --git a/cores/arduino/mik32/shared/libs/xprintf.c b/cores/arduino/mik32/shared/libs/xprintf.c new file mode 100644 index 0000000..c6fa6c1 --- /dev/null +++ b/cores/arduino/mik32/shared/libs/xprintf.c @@ -0,0 +1,447 @@ +/*------------------------------------------------------------------------/ +/ Universal String Handler for Console Input and Output +/-------------------------------------------------------------------------/ +/ +/ Copyright (C) 2014, ChaN, all right reserved. +/ +/ xprintf module is an open source software. Redistribution and use of +/ xprintf module in source and binary forms, with or without modification, +/ are permitted provided that the following condition is met: +/ +/ 1. Redistributions of source code must retain the above copyright notice, +/ this condition and the following disclaimer. +/ +/ This software is provided by the copyright holder and contributors "AS IS" +/ and any warranties related to this software are DISCLAIMED. +/ The copyright owner or contributors be NOT LIABLE for any damages caused +/ by use of this software. +/ +/-------------------------------------------------------------------------*/ + +#include "xprintf.h" + + +#if _USE_XFUNC_OUT +#include +void (*xfunc_out)(unsigned char); /* Pointer to the output stream */ +static char *outptr; + +/*----------------------------------------------*/ +/* Put a character */ +/*----------------------------------------------*/ + + + +void xfputc ( /* Put a character to the specified device */ + void(*func)(unsigned char), /* Pointer to the output function */ + char chr /* Character to be put */ +) +{ + void (*pf)(unsigned char); + + + pf = xfunc_out; /* Save current output device */ + xfunc_out = func; /* Switch output to specified device */ + xputc(chr); + xfunc_out = pf; /* Restore output device */ +} + + + +/*----------------------------------------------*/ +/* Put a null-terminated string */ +/*----------------------------------------------*/ + +void xputs ( /* Put a string to the default device */ + const char* str /* Pointer to the string */ +) +{ + while (*str) { + xputc(*str++); + } +} + + +void xfputs ( /* Put a string to the specified device */ + void(*func)(unsigned char), /* Pointer to the output function */ + const char* str /* Pointer to the string */ +) +{ + void (*pf)(unsigned char); + + + pf = xfunc_out; /* Save current output device */ + xfunc_out = func; /* Switch output to specified device */ + while (*str) { /* Put the string */ + xputc(*str++); + } + xfunc_out = pf; /* Restore output device */ +} + + + +/*----------------------------------------------*/ +/* Formatted string output */ +/*----------------------------------------------*/ +/* xprintf("%d", 1234); "1234" + xprintf("%6d,%3d%%", -200, 5); " -200, 5%" + xprintf("%-6u", 100); "100 " + xprintf("%ld", 12345678); "12345678" + xprintf("%llu", 0x100000000); "4294967296" <_USE_LONGLONG> + xprintf("%04x", 0xA3); "00a3" + xprintf("%08lX", 0x123ABC); "00123ABC" + xprintf("%016b", 0x550F); "0101010100001111" + xprintf("%*d", 6, 100); " 100" + xprintf("%s", "String"); "String" + xprintf("%-5s", "abc"); "abc " + xprintf("%5s", "abc"); " abc" + xprintf("%c", 'a'); "a" + xprintf("%f", 10.0); +*/ + +static +void xvprintf ( + const char* fmt, /* Pointer to the format string */ + va_list arp /* Pointer to arguments */ +) +{ + unsigned int r, i, j, w, f; + int n; + char s[32], c, d, *p; +#if _USE_LONGLONG + _LONGLONG_t v; + unsigned _LONGLONG_t vs; +#else + long v; + unsigned long vs; +#endif + + + for (;;) { + c = *fmt++; /* Get a format character */ + if (!c) break; /* End of format? */ + if (c != '%') { /* Pass it through if not a % sequense */ + xputc(c); continue; + } + f = w = 0; /* Clear parms */ + c = *fmt++; /* Get first char of the sequense */ + if (c == '0') { /* Flag: left '0' padded */ + f = 1; c = *fmt++; + } else { + if (c == '-') { /* Flag: left justified */ + f = 2; c = *fmt++; + } + } + if (c == '*') { /* Minimum width from an argument */ + n = va_arg(arp, int); + if (n < 0) { /* Flag: left justified */ + n = 0 - n; + f = 2; + } + w = n; c = *fmt++; + } else { + while (c >= '0' && c <= '9') { /* Minimum width */ + w = w * 10 + c - '0'; + c = *fmt++; + } + } + if (c == 'l' || c == 'L') { /* Prefix: Size is long */ + f |= 4; c = *fmt++; +#if _USE_LONGLONG + if (c == 'l' || c == 'L') { /* Prefix: Size is long long */ + f |= 8; c = *fmt++; + } +#endif + } + if (!c) break; /* End of format? */ + d = c; + if (d >= 'a') d -= 0x20; + switch (d) { /* Type is... */ + case 'S' : /* String */ + p = va_arg(arp, char*); + for (j = 0; p[j]; j++) ; + while (!(f & 2) && j++ < w) xputc(' '); + xputs(p); + while (j++ < w) xputc(' '); + continue; + case 'C' : /* Character */ + xputc((char)va_arg(arp, int)); continue; + case 'B' : /* Binary */ + r = 2; break; + case 'O' : /* Octal */ + r = 8; break; + case 'D' : /* Signed decimal */ + case 'U' : /* Unsigned decimal */ + r = 10; break; + case 'X' : /* Hexdecimal */ + r = 16; break; + default: /* Unknown type (passthrough) */ + xputc(c); continue; + } + + /* Get an argument and put it in numeral */ +#if _USE_LONGLONG + if (f & 8) { /* long long argument? */ + v = va_arg(arp, _LONGLONG_t); + } else { + if (f & 4) { /* long argument? */ + v = (d == 'D') ? (long)va_arg(arp, long) : (long)va_arg(arp, unsigned long); + } else { /* int/short/char argument */ + v = (d == 'D') ? (long)va_arg(arp, int) : (long)va_arg(arp, unsigned int); + } + } +#else + if (f & 4) { /* long argument? */ + v = va_arg(arp, long); + } else { /* int/short/char argument */ + v = (d == 'D') ? (long)va_arg(arp, int) : (long)va_arg(arp, unsigned int); + } +#endif + if (d == 'D' && v < 0) { /* Negative value? */ + v = 0 - v; f |= 16; + } + i = 0; vs = v; + do { + d = (char)(vs % r); vs /= r; + if (d > 9) d += (c == 'x') ? 0x27 : 0x07; + s[i++] = d + '0'; + } while (vs != 0 && i < sizeof s); + if (f & 16) s[i++] = '-'; + j = i; d = (f & 1) ? '0' : ' '; + while (!(f & 2) && j++ < w) xputc(d); + do xputc(s[--i]); while (i != 0); + while (j++ < w) xputc(' '); + } +} + + +void xprintf ( /* Put a formatted string to the default device */ + const char* fmt, /* Pointer to the format string */ + ... /* Optional arguments */ +) +{ + va_list arp; + + + va_start(arp, fmt); + xvprintf(fmt, arp); + va_end(arp); +} + + +void xsprintf ( /* Put a formatted string to the memory */ + char* buff, /* Pointer to the output buffer */ + const char* fmt, /* Pointer to the format string */ + ... /* Optional arguments */ +) +{ + va_list arp; + + + outptr = buff; /* Switch destination for memory */ + + va_start(arp, fmt); + xvprintf(fmt, arp); + va_end(arp); + + *outptr = 0; /* Terminate output string with a \0 */ + outptr = 0; /* Switch destination for device */ +} + + +void xfprintf ( /* Put a formatted string to the specified device */ + void(*func)(unsigned char), /* Pointer to the output function */ + const char* fmt, /* Pointer to the format string */ + ... /* Optional arguments */ +) +{ + va_list arp; + void (*pf)(unsigned char); + + + pf = xfunc_out; /* Save current output device */ + xfunc_out = func; /* Switch output to specified device */ + + va_start(arp, fmt); + xvprintf(fmt, arp); + va_end(arp); + + xfunc_out = pf; /* Restore output device */ +} + + + +/*----------------------------------------------*/ +/* Dump a line of binary dump */ +/*----------------------------------------------*/ + +void put_dump ( + const void* buff, /* Pointer to the array to be dumped */ + unsigned long addr, /* Heading address value */ + int len, /* Number of items to be dumped */ + int width /* Size of the items (DF_CHAR, DF_SHORT, DF_LONG) */ +) +{ + int i; + const unsigned char *bp; + const unsigned short *sp; + const unsigned long *lp; + + + xprintf("%08lX ", addr); /* address */ + + switch (width) { + case DW_CHAR: + bp = buff; + for (i = 0; i < len; i++) /* Hexdecimal dump */ + xprintf(" %02X", bp[i]); + xputc(' '); + for (i = 0; i < len; i++) /* ASCII dump */ + xputc((unsigned char)((bp[i] >= ' ' && bp[i] <= '~') ? bp[i] : '.')); + break; + case DW_SHORT: + sp = buff; + do /* Hexdecimal dump */ + xprintf(" %04X", *sp++); + while (--len); + break; + case DW_LONG: + lp = buff; + do /* Hexdecimal dump */ + xprintf(" %08LX", *lp++); + while (--len); + break; + } + + xputc('\n'); +} + +#endif /* _USE_XFUNC_OUT */ + + + +#if _USE_XFUNC_IN +unsigned char (*xfunc_in)(void); /* Pointer to the input stream */ + +/*----------------------------------------------*/ +/* Get a line from the input */ +/*----------------------------------------------*/ + +int xgets ( /* 0:End of stream, 1:A line arrived */ + char* buff, /* Pointer to the buffer */ + int len /* Buffer length */ +) +{ + int c, i; + + + if (!xfunc_in) return 0; /* No input function specified */ + + i = 0; + for (;;) { + c = xfunc_in(); /* Get a char from the incoming stream */ + if (!c) return 0; /* End of stream? */ + if (c == '\r') break; /* End of line? */ + if (c == '\b' && i) { /* Back space? */ + i--; + if (_LINE_ECHO) xputc((unsigned char)c); + continue; + } + if (c >= ' ' && i < len - 1) { /* Visible chars */ + buff[i++] = c; + if (_LINE_ECHO) xputc((unsigned char)c); + } + } + buff[i] = 0; /* Terminate with a \0 */ + if (_LINE_ECHO) xputc('\n'); + return 1; +} + + +int xfgets ( /* 0:End of stream, 1:A line arrived */ + unsigned char (*func)(void), /* Pointer to the input stream function */ + char* buff, /* Pointer to the buffer */ + int len /* Buffer length */ +) +{ + unsigned char (*pf)(void); + int n; + + + pf = xfunc_in; /* Save current input device */ + xfunc_in = func; /* Switch input to specified device */ + n = xgets(buff, len); /* Get a line */ + xfunc_in = pf; /* Restore input device */ + + return n; +} + + +/*----------------------------------------------*/ +/* Get a value of the string */ +/*----------------------------------------------*/ +/* "123 -5 0x3ff 0b1111 0377 w " + ^ 1st call returns 123 and next ptr + ^ 2nd call returns -5 and next ptr + ^ 3rd call returns 1023 and next ptr + ^ 4th call returns 15 and next ptr + ^ 5th call returns 255 and next ptr + ^ 6th call fails and returns 0 +*/ + +int xatoi ( /* 0:Failed, 1:Successful */ + char **str, /* Pointer to pointer to the string */ + long *res /* Pointer to the valiable to store the value */ +) +{ + unsigned long val; + unsigned char c, r, s = 0; + + + *res = 0; + + while ((c = **str) == ' ') (*str)++; /* Skip leading spaces */ + + if (c == '-') { /* negative? */ + s = 1; + c = *(++(*str)); + } + + if (c == '0') { + c = *(++(*str)); + switch (c) { + case 'x': /* hexdecimal */ + r = 16; c = *(++(*str)); + break; + case 'b': /* binary */ + r = 2; c = *(++(*str)); + break; + default: + if (c <= ' ') return 1; /* single zero */ + if (c < '0' || c > '9') return 0; /* invalid char */ + r = 8; /* octal */ + } + } else { + if (c < '0' || c > '9') return 0; /* EOL or invalid char */ + r = 10; /* decimal */ + } + + val = 0; + while (c > ' ') { + if (c >= 'a') c -= 0x20; + c -= '0'; + if (c >= 17) { + c -= 7; + if (c <= 9) return 0; /* invalid char */ + } + if (c >= r) return 0; /* invalid char for current radix */ + val = val * r + c; + c = *(++(*str)); + } + if (s) val = 0 - val; /* apply sign if needed */ + + *res = val; + return 1; +} + +#endif /* _USE_XFUNC_IN */ diff --git a/cores/arduino/mik32/shared/libs/xprintf.h b/cores/arduino/mik32/shared/libs/xprintf.h new file mode 100644 index 0000000..a0e6231 --- /dev/null +++ b/cores/arduino/mik32/shared/libs/xprintf.h @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------------*/ +/* Universal string handler for user console interface (C)ChaN, 2012 */ +/*------------------------------------------------------------------------*/ + +#ifndef _STRFUNC +#define _STRFUNC + +#ifdef __cplusplus +extern "C" { +#endif + +#define _USE_XFUNC_OUT 1 /* 1: Use output functions */ +#define _CR_CRLF 1 /* 1: Convert \n ==> \r\n in the output char */ +#define _USE_LONGLONG 0 /* 1: Enable long long integer in type "ll". */ +#define _LONGLONG_t long long /* Platform dependent long long integer type */ + +#define _USE_XFUNC_IN 1 /* 1: Use input function */ +#define _LINE_ECHO 1 /* 1: Echo back input chars in xgets function */ + + +#if _USE_XFUNC_OUT +#define xdev_out(func) xfunc_out = (void(*)(unsigned char))(func) +extern void (*xfunc_out)(unsigned char); +extern void xputc (char c); +void xfputc (void (*func)(unsigned char), char c); +void xputs (const char* str); +void xfputs (void (*func)(unsigned char), const char* str); +void xprintf (const char* fmt, ...); +void xsprintf (char* buff, const char* fmt, ...); +void xfprintf (void (*func)(unsigned char), const char* fmt, ...); +void put_dump (const void* buff, unsigned long addr, int len, int width); +#define DW_CHAR sizeof(char) +#define DW_SHORT sizeof(short) +#define DW_LONG sizeof(long) +#endif + +#if _USE_XFUNC_IN +#define xdev_in(func) xfunc_in = (unsigned char(*)(void))(func) +extern unsigned char (*xfunc_in)(void); +int xgets (char* buff, int len); +int xfgets (unsigned char (*func)(void), char* buff, int len); +int xatoi (char** str, long* res); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cores/arduino/mik32/shared/periphery/analog_reg.h b/cores/arduino/mik32/shared/periphery/analog_reg.h new file mode 100644 index 0000000..7eab020 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/analog_reg.h @@ -0,0 +1,145 @@ +#ifndef ANALOG_REG_H_INCLUDED +#define ANALOG_REG_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define DAC_CFG_EN18_S 0 +#define DAC_CFG_EN18_M (1 << DAC_CFG_EN18_S) +#define DAC_CFG_RESN_S 1 +#define DAC_CFG_RESN_M (1 << DAC_CFG_RESN_S) +#define DAC_CFG_DIV_S 2 +#define DAC_CFG_DIV_M (0xFF << DAC_CFG_DIV_S) +#define DAC_CFG_DIV(v) (((v) << DAC_CFG_DIV_S) & DAC_CFG_DIV_M) +#define DAC_CFG_EXTEN_S 10 +#define DAC_CFG_EXTEN_M (1 << DAC_CFG_EXTEN_S) +#define DAC_EXTPAD_EN_S 11 +#define DAC_EXTPAD_EN_M (1 << DAC_EXTPAD_EN_S) +#define DAC_EMPTY_READ_S 13 //Need New Name +#define DAC_EMPTY_READ_M (1 << DAC_EMPTY_READ_S) + + + +#define TSENS_CFG_NPD_S 0 +#define TSENS_CFG_NPD_M (1 << TSENS_CFG_NPD_S) +#define TSENS_CFG_NPD_CLK_S 1 +#define TSENS_CFG_NPD_CLK_M (1 << TSENS_CFG_NPD_CLK_S) +#define TSENS_CFG_NRST_S 2 +#define TSENS_CFG_NRST_M (1 << TSENS_CFG_NRST_S) +#define TSENS_CFG_CLK_MUX_S 3 +#define TSENS_CFG_CLK_MUX_M (0b111 << TSENS_CFG_CLK_MUX_S) +#define TSENS_CFG_DIV_S 6 +#define TSENS_CFG_DIV_M (0x3FF << TSENS_CFG_DIV_S) + +#define TSENS_TRESHOLD_HI_S 0 +#define TSENS_TRESHOLD_HI_M (0x3FF << TSENS_TRESHOLD_HI_S) +#define TSENS_TRESHOLD_LOW_S 10 +#define TSENS_TRESHOLD_LOW_M (0x3FF << TSENS_TRESHOLD_LOW_S) + +#define TSENS_IRQ_EOC_MASK_S 0 +#define TSENS_IRQ_EOC_MASK_M (1 << TSENS_IRQ_EOC_MASK_S) +#define TSENS_IRQ_HI_MASK_S 1 +#define TSENS_IRQ_HI_MASK_M (1 << TSENS_IRQ_HI_MASK_S) +#define TSENS_IRQ_LOW_MASK_S 2 +#define TSENS_IRQ_LOW_MASK_M (1 << TSENS_IRQ_LOW_MASK_S) +#define TSENS_IRQ_EOC_IRQ_S 3 +#define TSENS_IRQ_EOC_IRQ_M (1 << TSENS_IRQ_EOC_IRQ_S) +#define TSENS_IRQ_HI_IRQ_S 4 +#define TSENS_IRQ_HI_IRQ_M (1 << TSENS_IRQ_HI_IRQ_S) +#define TSENS_IRQ_LOW_IRQ_S 5 +#define TSENS_IRQ_LOW_IRQ_M (1 << TSENS_IRQ_LOW_IRQ_S) + +#define TSENS_CLEAR_IRQ_EOC_CLEAR_S 0 +#define TSENS_CLEAR_IRQ_EOC_CLEAR_M (1 << TSENS_CLEAR_IRQ_EOC_CLEAR_S) +#define TSENS_CLEAR_IRQ_HI_CLEAR_S 1 +#define TSENS_CLEAR_IRQ_HI_CLEAR_M (1 << TSENS_CLEAR_IRQ_HI_CLEAR_S) +#define TSENS_CLEAR_IRQ_LOW_CLEAR_S 2 +#define TSENS_CLEAR_IRQ_LOW_CLEAR_M (1 << TSENS_CLEAR_IRQ_LOW_CLEAR_S) + +#define TSENS_VALUE_EOC_S 10 +#define TSENS_VALUE_EOC_M (1 << TSENS_VALUE_EOC_S) +#define TSENS_VALUE_VALUE_S 0 +#define TSENS_VALUE_VALUE_M (0x3FF << TSENS_VALUE_VALUE_S) +#define TSENS_CELSIUS_TO_VALUE(i) (40960*100/(((6406600-93*((int)(i)*100+27315))*100)/((int)(i)*100+27315))) // (uint32_t)(4096/((10.3*622)/(i+273.15)-10.3 +1)) +#define TSENS_VALUE_TO_CELSIUS(v) ((640660*(uint32_t)(v))/(40960+93*(uint32_t)(v))*10-27315) // Значение температуры в 100 раз больше + + +#define ADC_CONFIG_EN_S 0 +#define ADC_CONFIG_EN_M (1 << ADC_CONFIG_EN_S) +#define ADC_CONFIG_RESETN_S 1 +#define ADC_CONFIG_RESETN_M (1 << ADC_CONFIG_RESETN_S) +#define ADC_CONFIG_EXTREF_S 2 +#define ADC_CONFIG_EXTREF_M (1 << ADC_CONFIG_EXTREF_S) +#define ADC_CONFIG_EXTPAD_EN_S 3 +#define ADC_CONFIG_EXTPAD_EN_M (1 << ADC_CONFIG_EXTPAD_EN_S) +#define ADC_CONFIG_SEL_S 4 +#define ADC_CONFIG_SEL_M (0b111 << ADC_CONFIG_SEL_S) +#define ADC_CONFIG_SAH_TIME_S 8 +#define ADC_CONFIG_SAH_TIME_M (0x3F << ADC_CONFIG_SAH_TIME_S) + +#define REF_CLB_VCOEF_S 0 +#define REF_CLB_VCOEF_M (0xF << REF_CLB_VCOEF_S) +#define REF_CLB_ICOEF_S 4 +#define REF_CLB_ICOEF_M (0xF << REF_CLB_ICOEF_S) +#define REF_CLB_EN_S 8 +#define REF_CLB_EN_M (1 << REF_CLB_EN_S) + +#define TEST_DIG_MUX_COV_LDO_M (0 << 9) +#define TEST_DIG_MUX_BATON_M (1 << 9) +#define TEST_DIG_MUX_BOR_M (2 << 9) +#define TEST_DIG_MUX_PGL_BU_M (3 << 9) +#define TEST_DIG_MUX_POR_M (4 << 9) +#define TEST_DIG_MUX_BGO_M (5 << 9) +#define TEST_DIG_MUX_PGL_M (6 << 9) + +#define TEST_DIG_MUX_OSC_CLK32M_M (12 << 9) +#define TEST_DIG_MUX_OSC_CLK32K_M (13 << 9) +#define TEST_DIG_MUX_RC_CLK32M_M (14 << 9) +#define TEST_DIG_MUX_RC_CLK32K_M (15 << 9) + + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t CFG; + volatile uint32_t VALUE; + } DAC_TypeDef; + + + typedef struct + { + volatile DAC_TypeDef DAC0; + volatile DAC_TypeDef DAC1; + volatile uint32_t PVD_DPF_VALUE; + volatile uint32_t PVD_CONFIG; + volatile uint32_t PVD_STATUS; + volatile uint32_t TSENS_CFG; + volatile uint32_t TSENS_THRESHOLD; + volatile uint32_t TSENS_IRQ; + volatile uint32_t TSENS_CLEAR_IRQ; + volatile uint32_t TSENS_VALUE; + volatile uint32_t TSENS_SINGLE; + volatile uint32_t TSENS_CONTINUOUS; + volatile uint32_t REFV_CONFIG; + volatile uint32_t ADC_CONFIG; + volatile uint32_t ADC_CONTINUOUS; + volatile uint32_t ADC_SINGLE; + volatile uint32_t ADC_VALID; + volatile uint32_t ADC_VALUE; + volatile uint32_t TEST_MUX; + + + } ANALOG_REG_TypeDef; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif // ANALOG_REG_H_INCLUDED + + \ No newline at end of file diff --git a/cores/arduino/mik32/shared/periphery/boot.h b/cores/arduino/mik32/shared/periphery/boot.h new file mode 100644 index 0000000..0a1ad50 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/boot.h @@ -0,0 +1,25 @@ +#ifndef BOOT_MANAGER_H_INCLUDED +#define BOOT_MANAGER_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define BOOT_EEPROM 0 +#define BOOT_RAM 1 +#define BOOT_SPIFI 2 + +#ifndef _ASSEMBLER_ + #include + typedef struct + { + volatile uint32_t BOOT; + } BOOT_MANAGER_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/cores/arduino/mik32/shared/periphery/crc.h b/cores/arduino/mik32/shared/periphery/crc.h new file mode 100644 index 0000000..f4d5e45 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/crc.h @@ -0,0 +1,57 @@ +#ifndef CRC_H_INCLUDED +#define CRC_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define CRC_DATA 0x00 +#define CRC_POLY 0x04 +#define CRC_CTRL 0x08 + +#define CRC_CTRL_TOT_S 30 +#define CRC_CTRL_TOT_M (3 << CRC_CTRL_TOT_S) +#define CRC_CTRL_TOT_NONE_M (0 << CRC_CTRL_TOT_S) +#define CRC_CTRL_TOT_BITS_M (1 << CRC_CTRL_TOT_S) +#define CRC_CTRL_TOT_BITS_BYTES_M (2 << CRC_CTRL_TOT_S) +#define CRC_CTRL_TOT_BYTES_M (3 << CRC_CTRL_TOT_S) + +// +#define CRC_CTRL_TOTR_S 28 +#define CRC_CTRL_TOTR_M (3 << CRC_CTRL_TOTR_S) +#define CRC_CTRL_TOTR_NONE_M (0 << CRC_CTRL_TOTR_S) +#define CRC_CTRL_TOTR_BITS_M (1 << CRC_CTRL_TOTR_S) +#define CRC_CTRL_TOTR_BITS_BYTES_M (2 << CRC_CTRL_TOTR_S) +#define CRC_CTRL_TOTR_BYTES_M (3 << CRC_CTRL_TOTR_S) +// +#define CRC_CTRL_FXOR_S 26 +#define CRC_CTRL_FXOR_M (1 << CRC_CTRL_FXOR_S) +#define CRC_CTRL_WAS_S 25 +#define CRC_CTRL_WAS_M (1 << CRC_CTRL_WAS_S) +// +#define CRC_CTRL_BUSY_S 0 +#define CRC_CTRL_BUSY_M (1 << CRC_CTRL_BUSY_S) + + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + union + { + volatile uint8_t DATA8; + volatile uint16_t DATA16; + volatile uint32_t DATA32; + }; + volatile uint32_t POLY; + volatile uint32_t CTRL; + } CRC_TypeDef; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif // CRC_H_INCLUDED \ No newline at end of file diff --git a/cores/arduino/mik32/shared/periphery/crypto.h b/cores/arduino/mik32/shared/periphery/crypto.h new file mode 100644 index 0000000..c37af9a --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/crypto.h @@ -0,0 +1,57 @@ +#ifndef CRYPTO_H_INCLUDED +#define CRYPTO_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define CRYPTO_CONFIG_DECODE_S 0 +#define CRYPTO_CONFIG_ENCODE_M (0 << CRYPTO_CONFIG_DECODE_S) +#define CRYPTO_CONFIG_DECODE_M (1 << CRYPTO_CONFIG_DECODE_S) +#define CRYPTO_CONFIG_CORE_SEL_S 1 +#define CRYPTO_CONFIG_CORE_SEL_M (0X3 << CRYPTO_CONFIG_CORE_SEL_S) +#define CRYPTO_CONFIG_CORE_SEL_KUZNECHIK_M (0X0 << CRYPTO_CONFIG_CORE_SEL_S) +#define CRYPTO_CONFIG_CORE_SEL_MAGMA_M (0X1 << CRYPTO_CONFIG_CORE_SEL_S) +#define CRYPTO_CONFIG_CORE_SEL_AES_M (0X2 << CRYPTO_CONFIG_CORE_SEL_S) +#define CRYPTO_CONFIG_MODE_SEL_S 3 +#define CRYPTO_CONFIG_MODE_SEL_M (0X3 << CRYPTO_CONFIG_MODE_SEL_S) +#define CRYPTO_CONFIG_MODE_SEL_ECB_M (0X0 << CRYPTO_CONFIG_MODE_SEL_S) +#define CRYPTO_CONFIG_MODE_SEL_CBC_M (0X1 << CRYPTO_CONFIG_MODE_SEL_S) +#define CRYPTO_CONFIG_MODE_SEL_CTR_M (0X2 << CRYPTO_CONFIG_MODE_SEL_S) +#define CRYPTO_CONFIG_SWAP_MODE_S 5 +#define CRYPTO_CONFIG_SWAP_MODE_M (0X3 << CRYPTO_CONFIG_SWAP_MODE_S) +#define CRYPTO_CONFIG_SWAP_MODE_NONE_M (0X0 << CRYPTO_CONFIG_SWAP_MODE_S) +#define CRYPTO_CONFIG_SWAP_MODE_HALF_WORD_M (0X1 << CRYPTO_CONFIG_SWAP_MODE_S) +#define CRYPTO_CONFIG_SWAP_MODE_BYTE_M (0X2 << CRYPTO_CONFIG_SWAP_MODE_S) +#define CRYPTO_CONFIG_SWAP_MODE_BIT_M (0X3 << CRYPTO_CONFIG_SWAP_MODE_S) +#define CRYPTO_CONFIG_ORDER_MODE_S 7 +#define CRYPTO_CONFIG_ORDER_MODE_M (1 << CRYPTO_CONFIG_ORDER_MODE_S) +#define CRYPTO_CONFIG_ORDER_MODE_LSW_M (0 << CRYPTO_CONFIG_ORDER_MODE_S) +#define CRYPTO_CONFIG_ORDER_MODE_MSW_M (1 << CRYPTO_CONFIG_ORDER_MODE_S) +#define CRYPTO_CONFIG_C_RESET_S 8 +#define CRYPTO_CONFIG_C_RESET_M (1 << CRYPTO_CONFIG_C_RESET_S) +#define CRYPTO_CONFIG_READY_S 9 +#define CRYPTO_CONFIG_READY_M (1 << CRYPTO_CONFIG_READY_S) +#define CRYPTO_CONFIG_WRITE_STATUS_S 10 +#define CRYPTO_CONFIG_WRITE_STATUS_M (1 << CRYPTO_CONFIG_WRITE_STATUS_S) +#define CRYPTO_CONFIG_READ_STATUS_S 11 +#define CRYPTO_CONFIG_READ_STATUS_M (1 << CRYPTO_CONFIG_READ_STATUS_S) + + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t BLOCK; + volatile uint32_t KEY; + volatile uint32_t INIT; + volatile uint32_t CONFIG; + } CRYPTO_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif // CRYPTO_H_INCLUDED \ No newline at end of file diff --git a/cores/arduino/mik32/shared/periphery/dma_config.h b/cores/arduino/mik32/shared/periphery/dma_config.h new file mode 100644 index 0000000..326f247 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/dma_config.h @@ -0,0 +1,117 @@ +#ifndef DMA_MC_H_INCLUDED +#define DMA_MC_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define DMA_CHANNEL_COUNT 4 + + +#define DMA_CH_CFG_ENABLE_S 0 +#define DMA_CH_CFG_ENABLE_M (1 << DMA_CH_CFG_ENABLE_S) +#define DMA_CH_CFG_DISABLE_M (0 << DMA_CH_CFG_ENABLE_S) + +#define DMA_CH_CFG_PRIOR_S 1 +#define DMA_CH_CFG_PRIOR_M (0X3 << DMA_CH_CFG_PRIOR_S) +#define DMA_CH_CFG_PRIOR_LOW_M (0B00 << DMA_CH_CFG_PRIOR_S) +#define DMA_CH_CFG_PRIOR_MEDIUM_M (0B01 << DMA_CH_CFG_PRIOR_S) +#define DMA_CH_CFG_PRIOR_HIGH_M (0B10 << DMA_CH_CFG_PRIOR_S) +#define DMA_CH_CFG_PRIOR_VERY_HIGH_M (0B11 << DMA_CH_CFG_PRIOR_S) + +#define DMA_CH_CFG_READ_MODE_S 3 +#define DMA_CH_CFG_READ_MODE_MEMORY_M (1 << DMA_CH_CFG_READ_MODE_S) +#define DMA_CH_CFG_READ_MODE_PERIPHERY_M (0 << DMA_CH_CFG_READ_MODE_S) + +#define DMA_CH_CFG_WRITE_MODE_S 4 +#define DMA_CH_CFG_WRITE_MODE_MEMORY_M (1 << DMA_CH_CFG_WRITE_MODE_S) +#define DMA_CH_CFG_WRITE_MODE_PERIPHERY_M (0 << DMA_CH_CFG_WRITE_MODE_S) + +#define DMA_CH_CFG_READ_INCREMENT_S 5 +#define DMA_CH_CFG_READ_INCREMENT_M (1 << DMA_CH_CFG_READ_INCREMENT_S) +#define DMA_CH_CFG_READ_NO_INCREMENT_M (0 << DMA_CH_CFG_READ_INCREMENT_S) + +#define DMA_CH_CFG_WRITE_INCREMENT_S 6 +#define DMA_CH_CFG_WRITE_INCREMENT_M (1 << DMA_CH_CFG_WRITE_INCREMENT_S) +#define DMA_CH_CFG_WRITE_NO_INCREMENT_M (0 << DMA_CH_CFG_WRITE_INCREMENT_S) + +#define DMA_CH_CFG_READ_SIZE_S 7 +#define DMA_CH_CFG_READ_SIZE_BYTE_M (0B00 << DMA_CH_CFG_READ_SIZE_S) // байт +#define DMA_CH_CFG_READ_SIZE_2BYTE_M (0B01 << DMA_CH_CFG_READ_SIZE_S) // полуслово +#define DMA_CH_CFG_READ_SIZE_4BYTE_M (0B10 << DMA_CH_CFG_READ_SIZE_S) // слово +#define DMA_CH_CFG_READ_SIZE_REZ_M (0B11 << DMA_CH_CFG_READ_SIZE_S) // резерв + +#define DMA_CH_CFG_WRITE_SIZE_S 9 +#define DMA_CH_CFG_WRITE_SIZE_BYTE_M (0B00 << DMA_CH_CFG_WRITE_SIZE_S) // байт +#define DMA_CH_CFG_WRITE_SIZE_2BYTE_M (0B01 << DMA_CH_CFG_WRITE_SIZE_S) // полуслово +#define DMA_CH_CFG_WRITE_SIZE_4BYTE_M (0B10 << DMA_CH_CFG_WRITE_SIZE_S) // слово +#define DMA_CH_CFG_WRITE_SIZE_REZ_M (0B11 << DMA_CH_CFG_WRITE_SIZE_S) // резерв + +#define DMA_CH_CFG_READ_BURST_SIZE_S 11 //Кол-во байт пакетной передачи: 2^Read_burst_size +#define DMA_CH_CFG_WRITE_BURST_SIZE_S 14 //Кол-во байт пакетной передачи: 2^Write_burst_size + +#define DMA_CH_CFG_READ_REQUETS_S 17 // выбор канала чтения +#define DMA_CH_CFG_READ_REQUETS_M (0xF << DMA_CH_CFG_READ_REQUETS_S) +#define DMA_CH_CFG_READ_REQUETS(v) (((v) << DMA_CH_CFG_READ_REQUETS_S) & DMA_CH_CFG_READ_REQUETS_M) + +#define DMA_CH_CFG_WRITE_REQUETS_S 21 // выбор канала записи +#define DMA_CH_CFG_WRITE_REQUETS_M (0xF << DMA_CH_CFG_WRITE_REQUETS_S) +#define DMA_CH_CFG_WRITE_REQUETS(v) (((v) << DMA_CH_CFG_WRITE_REQUETS_S) & DMA_CH_CFG_WRITE_REQUETS_M) + + +#define DMA_CH_CFG_READ_ACK_EN_S 25 +#define DMA_CH_CFG_READ_ACK_EN_M (1 << DMA_CH_CFG_READ_ACK_EN_S) +#define DMA_CH_CFG_WRITE_ACK_EN_S 26 +#define DMA_CH_CFG_WRITE_ACK_EN_M (1 << DMA_CH_CFG_WRITE_ACK_EN_S) +#define DMA_CH_CFG_IRQ_EN_S 27 +#define DMA_CH_CFG_IRQ_EN_M (1 << DMA_CH_CFG_IRQ_EN_S) + +#define DMA_CHANNEL_M ((1 << DMA_CHANNEL_COUNT) - 1) + +#define DMA_STATUS_READY_S 0 +#define DMA_STATUS_READY_M (DMA_CHANNEL_M << DMA_STATUS_READY_S) +#define DMA_STATUS_READY(i) ((1 << (DMA_STATUS_READY_S + (i))) & DMA_STATUS_READY_M) +#define DMA_STATUS_CHANNEL_IRQ_S 1 * DMA_CHANNEL_COUNT +#define DMA_STATUS_CHANNEL_IRQ_M (DMA_CHANNEL_M << DMA_STATUS_CHANNEL_IRQ_S) +#define DMA_STATUS_CHANNEL_BUS_ERROR_S 2 * DMA_CHANNEL_COUNT +#define DMA_STATUS_CHANNEL_BUS_ERROR_M (DMA_CHANNEL_M << DMA_STATUS_CHANNEL_BUS_ERROR_S) + +#define DMA_CONFIG_CLEAR_LOCAL_IRQ_S 0 +#define DMA_CONFIG_CLEAR_LOCAL_IRQ_M (DMA_CHANNEL_M << DMA_CONFIG_CLEAR_LOCAL_IRQ_S) +#define DMA_CONFIG_CLEAR_LOCAL_IRQ(i) ((1 << (DMA_CONTROL_CLEAR_LOCAL_IRQ_S + (i))) & DMA_CONTROL_CLEAR_LOCAL_IRQ_M) +#define DMA_CONFIG_CLEAR_GLOBAL_IRQ_S (DMA_CHANNEL_COUNT + 0) +#define DMA_CONFIG_CLEAR_GLOBAL_IRQ_M (1 << DMA_CONFIG_CLEAR_GLOBAL_IRQ_S) +#define DMA_CONFIG_CLEAR_ERROR_IRQ_S (DMA_CHANNEL_COUNT + 1) +#define DMA_CONFIG_CLEAR_ERROR_IRQ_M (1 << DMA_CONFIG_CLEAR_ERROR_IRQ_S) +#define DMA_CONFIG_GLOBAL_IRQ_ENA_S (DMA_CHANNEL_COUNT + 2) +#define DMA_CONFIG_GLOBAL_IRQ_ENA_M (1 << DMA_CONFIG_GLOBAL_IRQ_ENA_S) +#define DMA_CONFIG_ERROR_IRQ_ENA_S (DMA_CHANNEL_COUNT + 3) +#define DMA_CONFIG_ERROR_IRQ_ENA_M (1 << DMA_CONFIG_ERROR_IRQ_ENA_S) +#define DMA_CONFIG_CURRENT_VALUE_S (DMA_CHANNEL_COUNT + 4) +#define DMA_CONFIG_CURRENT_VALUE_M (1 << DMA_CONFIG_CURRENT_VALUE_S) + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + + volatile uint32_t DST; // 0x00 + volatile uint32_t SRC; // 0x04 + volatile uint32_t LEN; // 0x08 + volatile uint32_t CFG; // 0x0c + } DMA_CHANNEL_TypeDef; + + typedef struct + { + DMA_CHANNEL_TypeDef CHANNELS[DMA_CHANNEL_COUNT]; + volatile uint32_t CONFIG_STATUS; // 0x40 + } DMA_CONFIG_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + + +#endif // diff --git a/cores/arduino/mik32/shared/periphery/eeprom.h b/cores/arduino/mik32/shared/periphery/eeprom.h new file mode 100644 index 0000000..55432e5 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/eeprom.h @@ -0,0 +1,120 @@ +#ifndef EEPROM_H_INCLUDED +#define EEPROM_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +//-------------------------- +// EEPROM register fields +//-------------------------- + +//EEDAT +//EEA +#define EEPROM_EEA_ADDR_S 2 +#define EEPROM_EEA_ADDR_M (0b7FF << EEPROM_EEA_ADDR_S) +#define EEPROM_EEA_ADDR(v) (((v) << EEPROM_EEA_ADDR_S) & EEPROM_EEA_ADDR_M) +//EECON +#define EEPROM_EECON_EX_S 0 +#define EEPROM_EECON_EX_M (1 << EEPROM_EECON_EX_S) +#define EEPROM_EECON_OP_S 1 +#define EEPROM_EECON_OP_M (0b11 << EEPROM_EECON_OP_S) +#define EEPROM_EECON_OP(v) (((v) << EEPROM_EECON_OP_S) & EEPROM_EECON_OP_M) +#define EEPROM_EECON_WRBEH_S 3 +#define EEPROM_EECON_WRBEH_M (0b11 << EEPROM_EECON_WRBEH_S) +#define EEPROM_EECON_WRBEH(v) (((v) << EEPROM_EECON_WRBEH_S) & EEPROM_EECON_WRBEH_M) +#define EEPROM_EECON_APBNWS_S 5 +#define EEPROM_EECON_APBNWS_M (1 << EEPROM_EECON_APBNWS_S) +#define EEPROM_EECON_DISECC_S 6 +#define EEPROM_EECON_DISECC_M (1 << EEPROM_EECON_DISECC_S) +#define EEPROM_EECON_BWE_S 7 +#define EEPROM_EECON_BWE_M (1 << EEPROM_EECON_BWE_S) +#define EEPROM_EECON_IESERR_S 8 +#define EEPROM_EECON_IESERR_M (1 << EEPROM_EECON_IESERR_S) +//EESTA +#define EEPROM_EESTA_BSY_S 0 +#define EEPROM_EESTA_BSY_M (1 << EEPROM_EESTA_BSY_S) +#define EEPROM_EESTA_SERR_S 1 +#define EEPROM_EESTA_SERR_M (1 << EEPROM_EESTA_SERR_S) +//EERB +#define EEPROM_EERB_CORRECT_S 0 +#define EEPROM_EERB_CORRECT_M (0b111111 << EEPROM_EERB_CORRECT_S) +//EEADJ +#define EEPROM_EEADJ_OSCX2_S 0 +#define EEPROM_EEADJ_OSCX2_M (1 << EEPROM_EEADJ_OSCX2_S) +#define EEPROM_EEADJ_HIVCTL_S 0 +#define EEPROM_EEADJ_HIVCTL_M (0b111 << EEPROM_EEADJ_HIVCTL_S) +#define EEPROM_EEADJ_PLUSIMIX_S 0 +#define EEPROM_EEADJ_PLUSIMIX_M (1 << EEPROM_EEADJ_PLUSIMIX_S) +#define EEPROM_EEADJ_VBOOSTCTL_S 0 +#define EEPROM_EEADJ_VBOOSTCTL_M (0b11 << EEPROM_EEADJ_VBOOSTCTL_S) +#define EEPROM_EEADJ_MINUSIMIX_S 0 +#define EEPROM_EEADJ_MINUSIMIX_M (1 << EEPROM_EEADJ_MINUSIMIX_S) +#define EEPROM_EEADJ_DUMMYCTL_S 0 +#define EEPROM_EEADJ_DUMMYCTL_M (0b11 << EEPROM_EEADJ_DUMMYCTL_S) +#define EEPROM_EEADJ_VBGCTL_S 0 +#define EEPROM_EEADJ_VBGCTL_M (0b111 << EEPROM_EEADJ_VBGCTL_S) +#define EEPROM_EEADJ_REFCTL_S 0 +#define EEPROM_EEADJ_REFCTL_M (0b111 << EEPROM_EEADJ_REFCTL_S) +#define EEPROM_EEADJ_VCGCTL_S 0 +#define EEPROM_EEADJ_VCGCTL_M (0b111 << EEPROM_EEADJ_VCGCTL_S) +#define EEPROM_EEADJ_CGSTRICT_S 0 +#define EEPROM_EEADJ_CGSTRICT_M (1 << EEPROM_EEADJ_CGSTRICT_S) +#define EEPROM_EEADJ_VPPCTL_S 0 +#define EEPROM_EEADJ_VPPCTL_M (0b11 << EEPROM_EEADJ_VPPCTL_S) +#define EEPROM_EEADJ_STOPEE_S 0 +#define EEPROM_EEADJ_STOPEE_M (1 << EEPROM_EEADJ_STOPEE_S) +#define EEPROM_EEADJ_IDDQEN_S 0 +#define EEPROM_EEADJ_IDDQEN_M (1 << EEPROM_EEADJ_IDDQEN_S) +//NCYCRL +#define EEPROM_NCYCRL_N_LD_S 0 +#define EEPROM_NCYCRL_N_LD_M (0xFF << EEPROM_NCYCRL_N_LD_S) +#define EEPROM_NCYCRL_N_R_1_S 8 +#define EEPROM_NCYCRL_N_R_1_M (0xFF << EEPROM_NCYCRL_N_R_1_S) +#define EEPROM_NCYCRL_N_R_2_S 16 +#define EEPROM_NCYCRL_N_R_2_M (0xFF << EEPROM_NCYCRL_N_R_2_S) +//NCYCEP1 +#define EEPROM_NCYCEP1_N_EP_1_S 0 +#define EEPROM_NCYCEP1_N_EP_1_M (0x3FFFF << EEPROM_NCYCEP1_N_EP_1_S) +//NCYCEP2 +#define EEPROM_NCYCEP2_N_EP_2_S 0 +#define EEPROM_NCYCEP2_N_EP_2_M (0x7FF << EEPROM_NCYCEP2_N_EP_2_S) + +//-------------------------- +// EEPROM codes +//-------------------------- + +#define EEPROM_EECON_OP_RD 0 +#define EEPROM_EECON_OP_ER 1 +#define EEPROM_EECON_OP_PR 2 +#define EEPROM_WRBEH_SINGLE 0 +#define EEPROM_WRBEH_EVEN 1 +#define EEPROM_WRBEH_ODD 2 +#define EEPROM_WRBEH_GLOB 3 + + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t EEDAT; + volatile uint32_t EEA; + volatile uint32_t EECON; + volatile uint32_t EESTA; + volatile uint32_t EERB; + volatile uint32_t EEADJ; + volatile uint32_t NCYCRL; + volatile uint32_t NCYCEP1; + volatile uint32_t NCYCEP2; + + } EEPROM_REGS_TypeDef; +#endif + + +#ifdef __cplusplus +} +#endif + +#endif // EEPROM_H_INCLUDED + diff --git a/cores/arduino/mik32/shared/periphery/epic.h b/cores/arduino/mik32/shared/periphery/epic.h new file mode 100644 index 0000000..8962694 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/epic.h @@ -0,0 +1,72 @@ +#ifndef EPIC_H_INCLUDED +#define EPIC_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define EPIC_MASK_EDGE_SET 0x00 +#define EPIC_MASK_EDGE_CLEAR 0x04 +#define EPIC_MASK_LEVEL_SET 0x08 +#define EPIC_MASK_LEVEL_CLEAR 0x0C +#define EPIC_CLEAR 0x18 +#define EPIC_STATUS 0x1C +#define EPIC_RAW_STATUS 0x20 + +// Линии прерываний +#define EPIC_LINE_TIMER32_0_S 0 +#define EPIC_LINE_UART_0_S 1 +#define EPIC_LINE_UART_1_S 2 +#define EPIC_LINE_SPI_0_S 3 +#define EPIC_LINE_SPI_1_S 4 +#define EPIC_LINE_GPIO_IRQ_S 5 +#define EPIC_LINE_I2C_0_S 6 +#define EPIC_LINE_I2C_1_S 7 +#define EPIC_LINE_WDT_S 8 +#define EPIC_LINE_TIMER16_0_S 9 +#define EPIC_LINE_TIMER16_1_S 10 +#define EPIC_LINE_TIMER16_2_S 11 +#define EPIC_LINE_TIMER32_1_S 12 +#define EPIC_LINE_TIMER32_2_S 13 +#define EPIC_LINE_SPIFI_S 14 +#define EPIC_LINE_RTC_S 15 +#define EPIC_LINE_EEPROM_S 16 +#define EPIC_LINE_WDT_DOM3_S 17 +#define EPIC_LINE_WDT_SPIFI_S 18 +#define EPIC_LINE_WDT_EEPROM_S 19 +#define EPIC_LINE_DMA_S 20 +#define EPIC_LINE_FREQ_MON_S 21 +#define EPIC_LINE_PVD_AVCC_UNDER_S 22 +#define EPIC_LINE_PVD_AVCC_OVER_S 23 +#define EPIC_LINE_PVD_VCC_UNDER_S 24 +#define EPIC_LINE_PVD_VCC_OVER_S 25 +#define EPIC_LINE_BATTERY_NON_GOOD_S 26 +#define EPIC_LINE_BOR_S 27 +#define EPIC_LINE_TSENS_S 28 +#define EPIC_LINE_ADC_S 29 +#define EPIC_LINE_DAC0_S 30 +#define EPIC_LINE_DAC1_S 31 +#define EPIC_LINE_M(interrupt_line) (1 << interrupt_line) + + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t MASK_EDGE_SET; // 0x00 + volatile uint32_t MASK_EDGE_CLEAR; // 0x04 + volatile uint32_t MASK_LEVEL_SET; // 0x08 + volatile uint32_t MASK_LEVEL_CLEAR; // 0x0C + volatile uint32_t reserved[2]; // reserved + volatile uint32_t CLEAR; // 0x18 + volatile uint32_t STATUS; // 0x1C + volatile uint32_t RAW_STATUS; // 0x20 + } EPIC_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif // EPIC_H_INCLUDED diff --git a/cores/arduino/mik32/shared/periphery/gpio.h b/cores/arduino/mik32/shared/periphery/gpio.h new file mode 100644 index 0000000..0b34fc3 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/gpio.h @@ -0,0 +1,42 @@ +#ifndef GPIO_H_INCLUDED +#define GPIO_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define GPIO_STATE 0x00 +#define GPIO_SET 0x00 +#define GPIO_CLEAR 0x04 +#define GPIO_DIRECTION_OUT 0x08 +#define GPIO_DIRECTION_IN 0x0C +#define GPIO_OUTPUT 0x10 +#define GPIO_CONTROL 0x14 + + + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + union + { + volatile uint32_t SET; + volatile uint32_t STATE; + }; + volatile uint32_t CLEAR; + volatile uint32_t DIRECTION_OUT; + volatile uint32_t DIRECTION_IN; + volatile uint32_t OUTPUT_; + volatile uint32_t CONTROL; + + } GPIO_TypeDef; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/shared/periphery/gpio_irq.h b/cores/arduino/mik32/shared/periphery/gpio_irq.h new file mode 100644 index 0000000..e6979a8 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/gpio_irq.h @@ -0,0 +1,39 @@ +#ifndef GPIO_IRQ_H_INCLUDED +#define GPIO_IRQ_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + + +#define GPIO_IRQ_LINE_M(line_num) (1 << (line_num)) +// LINE_MUX +#define GPIO_IRQ_LINE_MUX_M(line_num) (0xF << ((line_num) << 2)) +#define GPIO_IRQ_LINE_MUX(mux, line_num) (((mux) << ((line_num) << 2)) & GPIO_IRQ_LINE_MUX_M(line_num)) + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t STATE; + volatile uint32_t LINE_MUX; + volatile uint32_t INTERRUPT; + volatile uint32_t ENABLE_SET; + volatile uint32_t ENABLE_CLEAR; + volatile uint32_t EDGE; + volatile uint32_t LEVEL; + volatile uint32_t LEVEL_SET; + volatile uint32_t LEVEL_CLEAR; + volatile uint32_t ANY_EDGE_SET; + volatile uint32_t ANY_EDGE_CLEAR; + volatile uint32_t CLEAR; + } GPIO_IRQ_TypeDef; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/cores/arduino/mik32/shared/periphery/i2c.h b/cores/arduino/mik32/shared/periphery/i2c.h new file mode 100644 index 0000000..fbccf4c --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/i2c.h @@ -0,0 +1,175 @@ +#ifndef I2C_H_INCLUDED +#define I2C_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + + +#define I2C_CR1_PE_S 0 +#define I2C_CR1_PE_M (1 << I2C_CR1_PE_S) +#define I2C_CR1_TXIE_S 1 +#define I2C_CR1_TXIE_M (1 << I2C_CR1_TXIE_S) +#define I2C_CR1_RXIE_S 2 +#define I2C_CR1_RXIE_M (1 << I2C_CR1_RXIE_S) +#define I2C_CR1_ADDRIE_S 3 +#define I2C_CR1_ADDRIE_M (1 << I2C_CR1_ADDRIE_S) +#define I2C_CR1_NACKIE_S 4 +#define I2C_CR1_NACKIE_M (1 << I2C_CR1_NACKIE_S) +#define I2C_CR1_STOPIE_S 5 +#define I2C_CR1_STOPIE_M (1 << I2C_CR1_STOPIE_S) +#define I2C_CR1_TCIE_S 6 +#define I2C_CR1_TCIE_M (1 << I2C_CR1_TCIE_S) +#define I2C_CR1_ERRIE_S 7 +#define I2C_CR1_ERRIE_M (1 << I2C_CR1_ERRIE_S) +#define I2C_CR1_DNF_S 8 +#define I2C_CR1_DNF_M (0xF << I2C_CR1_DNF_S) +#define I2C_CR1_DNF(v) (((v) << I2C_CR1_DNF_S) & I2C_CR1_DNF_M) +#define I2C_CR1_ANFOFF_S 12 +#define I2C_CR1_ANFOFF_M (1 << I2C_CR1_ANFOFF_S) +// +#define I2C_CR1_TXDMAEN_S 14 +#define I2C_CR1_TXDMAEN_M (1 << I2C_CR1_TXDMAEN_S) +#define I2C_CR1_RXDMAEN_S 15 +#define I2C_CR1_RXDMAEN_M (1 << I2C_CR1_RXDMAEN_S) +#define I2C_CR1_SBC_S 16 +#define I2C_CR1_SBC_M (1 << I2C_CR1_SBC_S) +#define I2C_CR1_NOSTRETCH_S 17 +#define I2C_CR1_NOSTRETCH_M (1 << I2C_CR1_NOSTRETCH_S) +// +#define I2C_CR1_GCEN_S 19 +#define I2C_CR1_GCEN_M (1 << I2C_CR1_GCEN_S) + + +#define I2C_CR2_SADD_S 0 +#define I2C_CR2_SADD_M (0x3FF << I2C_CR2_SADD_S) +#define I2C_CR2_SADD(v) (((v) << I2C_CR2_SADD_S) &I2C_CR2_SADD_M) +#define I2C_CR2_RD_WRN_S 10 +#define I2C_CR2_RD_WRN_M (1 << I2C_CR2_RD_WRN_S) +#define I2C_CR2_RD_M (1 << I2C_CR2_RD_WRN_S) +#define I2C_CR2_WR_M (0 << I2C_CR2_RD_WRN_S) +#define I2C_CR2_ADD10_S 11 +#define I2C_CR2_ADD10_M (1 << I2C_CR2_ADD10_S) +#define I2C_CR2_HEAD10R_S 12 +#define I2C_CR2_HEAD10R_M (1 << I2C_CR2_HEAD10R_S) +#define I2C_CR2_START_S 13 +#define I2C_CR2_START_M (1 << I2C_CR2_START_S) +#define I2C_CR2_STOP_S 14 +#define I2C_CR2_STOP_M (1 << I2C_CR2_STOP_S) +#define I2C_CR2_NACK_S 15 +#define I2C_CR2_NACK_M (1 << I2C_CR2_NACK_S) +#define I2C_CR2_NBYTES_S 16 +#define I2C_CR2_NBYTES_M (0xFF << I2C_CR2_NBYTES_S) +#define I2C_CR2_NBYTES(v) (((v) << I2C_CR2_NBYTES_S) & I2C_CR2_NBYTES_M) +#define I2C_CR2_RELOAD_S 24 +#define I2C_CR2_RELOAD_M (1 << I2C_CR2_RELOAD_S) +#define I2C_CR2_AUTOEND_S 25 +#define I2C_CR2_AUTOEND_M (1 << I2C_CR2_AUTOEND_S) + + +#define I2C_OAR1_OA1_S 0 +#define I2C_OAR1_OA1_M (0x3FF << I2C_OAR1_OA1_S) +#define I2C_OAR1_OA1MODE_S 10 +#define I2C_OAR1_OA1MODE_M (1 << I2C_OAR1_OA1MODE_S) +// +#define I2C_OAR1_OA1EN_S 15 +#define I2C_OAR1_OA1EN_M (1 << I2C_OAR1_OA1EN_S) + + +#define I2C_OAR2_OA2_S 1 +#define I2C_OAR2_OA2_M (0x7F << I2C_OAR2_OA2_S) +#define I2C_OAR2_OA2MSK_S 8 +#define I2C_OAR2_OA2MSK_M (0x7 << I2C_OAR2_OA2MSK_S) +// +#define I2C_OAR2_OA2EN_S 15 +#define I2C_OAR2_OA2EN_M (1 << I2C_OAR2_OA2EN_S) + + +#define I2C_TIMINGR_SCLL_S 0 +#define I2C_TIMINGR_SCLL_M (0xFF << I2C_TIMINGR_SCLL_S) +#define I2C_TIMINGR_SCLL(v) (((v) << I2C_TIMINGR_SCLL_S) & I2C_TIMINGR_SCLL_M) +#define I2C_TIMINGR_SCLH_S 8 +#define I2C_TIMINGR_SCLH_M (0xFF << I2C_TIMINGR_SCLH_S) +#define I2C_TIMINGR_SCLH(v) (((v) << I2C_TIMINGR_SCLH_S) & I2C_TIMINGR_SCLH_M) +#define I2C_TIMINGR_SDADEL_S 16 +#define I2C_TIMINGR_SDADEL_M (0xF << I2C_TIMINGR_SDADEL_S) +#define I2C_TIMINGR_SDADEL(v) (((v) << I2C_TIMINGR_SDADEL_S) & I2C_TIMINGR_SDADEL_M) +#define I2C_TIMINGR_SCLDEL_S 20 +#define I2C_TIMINGR_SCLDEL_M (0xF << I2C_TIMINGR_SCLDEL_S) +#define I2C_TIMINGR_SCLDEL(v) (((v) << I2C_TIMINGR_SCLDEL_S) & I2C_TIMINGR_SCLDEL_M) +#define I2C_TIMINGR_PRESC_S 28 +#define I2C_TIMINGR_PRESC_M (0xF << I2C_TIMINGR_PRESC_S) +#define I2C_TIMINGR_PRESC(v) (((v) << I2C_TIMINGR_PRESC_S) & I2C_TIMINGR_PRESC_M) + + +#define I2C_ISR_TXE_S 0 +#define I2C_ISR_TXE_M (1 << I2C_ISR_TXE_S) +#define I2C_ISR_TXIS_S 1 +#define I2C_ISR_TXIS_M (1 << I2C_ISR_TXIS_S) +#define I2C_ISR_RXNE_S 2 +#define I2C_ISR_RXNE_M (1 << I2C_ISR_RXNE_S) +#define I2C_ISR_ADDR_S 3 +#define I2C_ISR_ADDR_M (1 << I2C_ISR_ADDR_S) +#define I2C_ISR_NACKF_S 4 +#define I2C_ISR_NACKF_M (1 << I2C_ISR_NACKF_S) +#define I2C_ISR_STOPF_S 5 +#define I2C_ISR_STOPF_M (1 << I2C_ISR_STOPF_S) +#define I2C_ISR_TC_S 6 +#define I2C_ISR_TC_M (1 << I2C_ISR_TC_S) +#define I2C_ISR_TCR_S 7 +#define I2C_ISR_TCR_M (1 << I2C_ISR_TCR_S) +#define I2C_ISR_BERR_S 8 +#define I2C_ISR_BERR_M (1 << I2C_ISR_BERR_S) +#define I2C_ISR_ARLO_S 9 +#define I2C_ISR_ARLO_M (1 << I2C_ISR_ARLO_S) +#define I2C_ISR_OVR_S 10 +#define I2C_ISR_OVR_M (1 << I2C_ISR_OVR_S) +// +#define I2C_ISR_BUSY_S 15 +#define I2C_ISR_BUSY_M (1 << I2C_ISR_BUSY_S) +#define I2C_ISR_DIR_S 16 +#define I2C_ISR_DIR_M (1 << I2C_ISR_DIR_S) +#define I2C_ISR_ADDCODE_S 17 +#define I2C_ISR_ADDCODE_M (0x7F << I2C_ISR_ADDCODE_S) + + +#define I2C_ICR_ADDRCF_S 3 +#define I2C_ICR_ADDRCF_M (1 << I2C_ICR_ADDRCF_S) +#define I2C_ICR_NACKCF_S 4 +#define I2C_ICR_NACKCF_M (1 << I2C_ICR_NACKCF_S) +#define I2C_ICR_STOPCF_S 5 +#define I2C_ICR_STOPCF_M (1 << I2C_ICR_STOPCF_S) +// +#define I2C_ICR_BERRCF_S 8 +#define I2C_ICR_BERRCF_M (1 << I2C_ICR_BERRCF_S) +#define I2C_ICR_ARLOCF_S 9 +#define I2C_ICR_ARLOCF_M (1 << I2C_ICR_ARLOCF_S) +#define I2C_ICR_OVRCF_S 10 +#define I2C_ICR_OVRCF_M (1 << I2C_ICR_OVRCF_S) + + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t CR1; + volatile uint32_t CR2; + volatile uint32_t OAR1; + volatile uint32_t OAR2; + volatile uint32_t TIMINGR; + volatile uint32_t reserved0; + volatile uint32_t ISR; + volatile uint32_t ICR; + volatile uint32_t reserved1; + volatile uint32_t RXDR; + volatile uint32_t TXDR; + } I2C_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif // I2C_H_INCLUDED + diff --git a/cores/arduino/mik32/shared/periphery/otp.h b/cores/arduino/mik32/shared/periphery/otp.h new file mode 100644 index 0000000..49d96b6 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/otp.h @@ -0,0 +1,98 @@ +#ifndef OTP_H_INCLUDED +#define OTP_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +//-------------------------- +// OTP register fields +//-------------------------- + + +#define OTP_APBNWS_S 0 +#define OTP_BSY_S 0 +#define OTP_N_RA_S 8 +#define OTP_N_RSU_S 0 +#define OTP_N_RH_S 16 +#define OTP_SEL_UPP_READ 24 +#define OTP_SEL_READ_CUR 27 + + +/* Регистр управления OTPCON */ +#define OTP_OTPCON_APBNWS_S 0 +#define OTP_OTPCON_APBNWS_M (0b1 << OTP_OTPCON_APBNWS_S) +#define OTP_OTPCON_MAN_WE_I_S 1 +#define OTP_OTPCON_MAN_WE_I_M (0b1 << OTP_OTPCON_MAN_WE_I_S) +#define OTP_OTPCON_MAN_RE_I_S 2 +#define OTP_OTPCON_MAN_RE_I_M (0b1 << OTP_OTPCON_MAN_RE_I_S) +#define OTP_OTPCON_MME_S 3 +#define OTP_OTPCON_MME_M (0b1 << OTP_OTPCON_MME_S) + +/* Регистр статуса OTPSTA */ +#define OTP_OTPSTA_BSY_S 0 +#define OTP_OTPSTA_BSY_M (0b1 << OTP_OTPSTA_BSY_S) + +/* Регистр бит дешифратора OTPDEC */ +#define OTP_OTPDEC_DECO_S 0 +#define OTP_OTPDEC_DECO_M (0x3FF << OTP_OTPDEC_DECO_S) + +/* Регистр управления временными параметрами OTPADJ */ +#define OTP_OTPADJ_N_RSU_S 0 +#define OTP_OTPADJ_N_RSU_M (0b111 << OTP_OTPADJ_N_RSU_S) +#define OTP_OTPADJ_N_RA_S 8 +#define OTP_OTPADJ_N_RA_M (0b111 << OTP_OTPADJ_N_RA_S) +#define OTP_OTPADJ_N_RH_S 16 +#define OTP_OTPADJ_N_RH_M (0b111 << OTP_OTPADJ_N_RH_S) +#define OTP_OTPADJ_SEL_UPP_READ_I_S 24 +#define OTP_OTPADJ_SEL_UPP_READ_I_M (0b111 << OTP_OTPADJ_SEL_UPP_READ_I_S) +#define OTP_OTPADJ_SEL_UPP_READ_I_2_0V_M (0b000 << OTP_OTPADJ_SEL_UPP_READ_I_S) +#define OTP_OTPADJ_SEL_UPP_READ_I_2_5V_M (0b001 << OTP_OTPADJ_SEL_UPP_READ_I_S) +#define OTP_OTPADJ_SEL_UPP_READ_I_3_0V_M (0b011 << OTP_OTPADJ_SEL_UPP_READ_I_S) +#define OTP_OTPADJ_SEL_UPP_READ_I_VDD18_M (0b010 << OTP_OTPADJ_SEL_UPP_READ_I_S) +#define OTP_OTPADJ_SEL_UPP_READ_I_VDD5_M (0b110 << OTP_OTPADJ_SEL_UPP_READ_I_S) +#define OTP_OTPADJ_SEL_READ_CUR_I_S 27 +#define OTP_OTPADJ_SEL_READ_CUR_I_M (0b1 << OTP_OTPADJ_SEL_READ_CUR_I_S) +#define OTP_OTPADJ_POWER_OFF_I_S 28 +#define OTP_OTPADJ_POWER_OFF_I_M (0b1 << OTP_OTPADJ_POWER_OFF_I_S) + +/* Регистр подстройки длительности процедуры записи 1 OTPWT1 */ +#define OTP_OTPWT1_N_SU_S 0 +#define OTP_OTPWT1_N_SU_M (0b111 << OTP_OTPWT1_N_SU_S) +#define OTP_OTPWT1_N_H_S 8 +#define OTP_OTPWT1_N_H_M (0b111 << OTP_OTPWT1_N_H_S) + +/* Регистр подстройки длительности процедуры записи 2 OTPWT2 */ +#define OTP_OTPWT2_N_W_S 0 +#define OTP_OTPWT2_N_W_M (0xFFFFFF << OTP_OTPWT2_N_W_S) + + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + //-------------------------- + // OTP registers + //-------------------------- + + volatile uint32_t OTPDAT; + volatile uint32_t OTPA; + volatile uint32_t OTPCON; + volatile uint32_t OTPSTA; + volatile uint32_t OTPDEC; + volatile uint32_t OTPADJ; + volatile uint32_t OTPWT1; + volatile uint32_t OTPWT2; + + + } OTP_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + + +#endif // OTP_H_INCLUDED + diff --git a/cores/arduino/mik32/shared/periphery/pad_config.h b/cores/arduino/mik32/shared/periphery/pad_config.h new file mode 100644 index 0000000..b09d89d --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/pad_config.h @@ -0,0 +1,36 @@ +#ifndef PAD_CONFIG_H_INCLUDED +#define PAD_CONFIG_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define PAD_CONFIG_PIN_M(pin) (0b11 << ((pin) << 1)) +#define PAD_CONFIG_PIN(pin, value) ((value) << ((pin) << 1)) + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t PORT_0_CFG; + volatile uint32_t PORT_0_DS; + volatile uint32_t PORT_0_PUPD; + + volatile uint32_t PORT_1_CFG; + volatile uint32_t PORT_1_DS; + volatile uint32_t PORT_1_PUPD; + + volatile uint32_t PORT_2_CFG; + volatile uint32_t PORT_2_DS; + volatile uint32_t PORT_2_PUPD; + } PAD_CONFIG_TypeDef; + +#endif + +#ifdef __cplusplus +} +#endif + + +#endif // PAD_CONFIG_H_INCLUDED \ No newline at end of file diff --git a/cores/arduino/mik32/shared/periphery/power_manager.h b/cores/arduino/mik32/shared/periphery/power_manager.h new file mode 100644 index 0000000..e1e8561 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/power_manager.h @@ -0,0 +1,123 @@ +#ifndef PM_H_INCLUDED +#define PM_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define PM_DIV_AHB_OFFSET 0x00 +#define PM_DIV_APB_M_OFFSET 0x04 +#define PM_DIV_APB_P_OFFSET 0x08 +#define PM_CLK_AHB_SET_OFFSET 0x0C +#define PM_CLK_AHB_CLEAR_OFFSET 0x10 +#define PM_CLK_APB_M_SET_OFFSET 0x14 +#define PM_CLK_APB_M_CLEAR_OFFSET 0x18 +#define PM_CLK_APB_P_SET_OFFSET 0x1C +#define PM_CLK_APB_P_CLEAR_OFFSET 0x20 +#define PM_AHB_CLK_MUX_OFFSET 0x24 +#define PM_WDT_CLK_MUX_OFFSET 0x28 +#define PM_CPU_RTC_CLK_MUX_OFFSET 0x2C +#define PM_TIMER_CFG_OFFSET 0x30 +#define PM_FREQ_MASK_OFFSET 0x34 +#define PM_FREQ_STATUS_OFFSET 0x38 +#define PM_SLEEP_MODE_OFFSET 0x3C + + +#define PM_AHB_CLK_MUX_S 0 +#define PM_AHB_CLK_MUX_M (0x3 << PM_AHB_CLK_MUX_S) +#define PM_AHB_CLK_MUX_OSC32M_M (0x0 << PM_AHB_CLK_MUX_S) +#define PM_AHB_CLK_MUX_HSI32M_M (0x1 << PM_AHB_CLK_MUX_S) +#define PM_AHB_CLK_MUX_OSC32K_M (0x2 << PM_AHB_CLK_MUX_S) +#define PM_AHB_CLK_MUX_LSI32K_M (0x3 << PM_AHB_CLK_MUX_S) +#define PM_AHB_FORCE_MUX_S 2 +#define PM_AHB_FORCE_MUX_M (1 << PM_AHB_FORCE_MUX_S) +#define PM_AHB_FORCE_MUX_FIXED (1 << PM_AHB_FORCE_MUX_S) +#define PM_AHB_FORCE_MUX_UNFIXED (0 << PM_AHB_FORCE_MUX_S) + +#define PM_WDT_CLK_MUX_S 0 +#define PM_WDT_CLK_MUX_M (3 << PM_WDT_CLK_MUX_S) +#define PM_WDT_CLK_MUX_OSC32M_M (0 << PM_WDT_CLK_MUX_S) +#define PM_WDT_CLK_MUX_HSI32M_M (1 << PM_WDT_CLK_MUX_S) +#define PM_WDT_CLK_MUX_OSC32K_M (2 << PM_WDT_CLK_MUX_S) +#define PM_WDT_CLK_MUX_LSI32K_M (3 << PM_WDT_CLK_MUX_S) + +#define PM_CPU_RTC_CLK_MUX_S 0 +#define PM_CPU_RTC_CLK_MUX_M (1 << PM_CPU_RTC_CLK_MUX_S) +#define PM_CPU_RTC_CLK_MUX_OSC32K_M (0 << PM_CPU_RTC_CLK_MUX_S) +#define PM_CPU_RTC_CLK_MUX_LSI32K_M (1 << PM_CPU_RTC_CLK_MUX_S) + +#define PM_TIMER_CFG_MUX_TIMER32_0_S 0 +#define PM_TIMER_CFG_MUX_TIMER32_1_S 3 +#define PM_TIMER_CFG_MUX_TIMER32_2_S 6 +#define PM_TIMER_CFG_MUX_TIMER32_TIM1_SYS_CLK_M(timer_index) (0b00 << (timer_index)) +#define PM_TIMER_CFG_MUX_TIMER32_TIM1_HCLK_M(timer_index) (0b01 << (timer_index)) +#define PM_TIMER_CFG_MUX_TIMER32_TIM2_OSC32K_M(timer_index) (0b01 << (timer_index)) +#define PM_TIMER_CFG_MUX_TIMER32_TIM2_LSI32K_M(timer_index) (0b10 << (timer_index)) + +#define PM_TIMER_CFG_MUX_TIMER16_0_S 9 +#define PM_TIMER_CFG_MUX_TIMER16_1_S 12 +#define PM_TIMER_CFG_MUX_TIMER16_2_S 15 +#define PM_TIMER_CFG_MUX_TIMER16_SYS_CLK_M(timer_index) (0x0 << (timer_index)) +#define PM_TIMER_CFG_MUX_TIMER16_HCLK_M(timer_index) (0x1 << (timer_index)) +#define PM_TIMER_CFG_MUX_TIMER16_OSC32M_M(timer_index) (0x2 << (timer_index)) +#define PM_TIMER_CFG_MUX_TIMER16_HSI32M_M(timer_index) (0x3 << (timer_index)) +#define PM_TIMER_CFG_MUX_TIMER16_OSC32K_M(timer_index) (0x4 << (timer_index)) +#define PM_TIMER_CFG_MUX_TIMER16_LSI32K_M(timer_index) (0x5 << (timer_index)) + +#define PM_TIMER_CFG_MUX_TIMER_M(timer_index) (0x7 << (timer_index)) + +#define PM_FREQ_MASK_FORCE_DIV_S 4 +#define PM_FREQ_MASK_FORCE_DIV_M (1 << PM_FREQ_MASK_FORCE_DIV_S) +#define PM_FREQ_MASK_OSC32M_S 3 +#define PM_FREQ_MASK_OSC32M_M (1 << PM_FREQ_MASK_OSC32M_S) +#define PM_FREQ_MASK_HSI32M_S 2 +#define PM_FREQ_MASK_HSI32M_M (1 << PM_FREQ_MASK_HSI32M_S) +#define PM_FREQ_MASK_OSC32K_S 1 +#define PM_FREQ_MASK_OSC32K_M (1 << PM_FREQ_MASK_OSC32K_S) +#define PM_FREQ_MASK_LSI32K_S 0 +#define PM_FREQ_MASK_LSI32K_M (1 << PM_FREQ_MASK_LSI32K_S) + +#define PM_FREQ_STATUS_OSC32M_S 3 +#define PM_FREQ_STATUS_OSC32M_M (1 << PM_FREQ_STATUS_OSC32M_S) +#define PM_FREQ_STATUS_HSI32M_S 2 +#define PM_FREQ_STATUS_HSI32M_M (1 << PM_FREQ_STATUS_HSI32M_S) +#define PM_FREQ_STATUS_OSC32K_S 1 +#define PM_FREQ_STATUS_OSC32K_M (1 << PM_FREQ_STATUS_OSC32K_S) +#define PM_FREQ_STATUS_LSI32K_S 0 +#define PM_FREQ_STATUS_LSI32K_M (1 << PM_FREQ_STATUS_LSI32K_S) + +#define PM_SLEEP_MODE_S 0 +#define PM_SLEEP_MODE_M (1 << PM_SLEEP_MODE_S) + +#ifndef _ASSEMBLER_ + #include + typedef struct + { + + + volatile uint32_t DIV_AHB; + volatile uint32_t DIV_APB_M; + volatile uint32_t DIV_APB_P; + volatile uint32_t CLK_AHB_SET; + volatile uint32_t CLK_AHB_CLEAR; + volatile uint32_t CLK_APB_M_SET; + volatile uint32_t CLK_APB_M_CLEAR; + volatile uint32_t CLK_APB_P_SET; + volatile uint32_t CLK_APB_P_CLEAR; + volatile uint32_t AHB_CLK_MUX; + volatile uint32_t WDT_CLK_MUX; + volatile uint32_t CPU_RTC_CLK_MUX; + volatile uint32_t TIMER_CFG; + volatile uint32_t FREQ_MASK; + volatile uint32_t FREQ_STATUS; + volatile uint32_t SLEEP_MODE; + + } PM_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/cores/arduino/mik32/shared/periphery/pvd_control.h b/cores/arduino/mik32/shared/periphery/pvd_control.h new file mode 100644 index 0000000..9ed30df --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/pvd_control.h @@ -0,0 +1,52 @@ +#ifndef PVD_CONTROL_H_INCLUDED +#define PVD_CONTROL_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define PVD_DPF_VALUE_S 0 +#define PVD_DPF_VALUE_M (0xFFFF << PVD_DPF_VALUE_S) + +#define PVD_CONFIG_PD_S 0 +#define PVD_CONFIG_PD_M (1 << PVD_CONFIG_PD_S) +#define PVD_CONFIG_NRESETU_S 1 +#define PVD_CONFIG_NRESETU_M (1 << PVD_CONFIG_NRESETU_S) +#define PVD_CONFIG_NRESETO_S 2 +#define PVD_CONFIG_NRESETO_M (1 << PVD_CONFIG_NRESETO_S) +#define PVD_CONFIG_TESTMODE_S 3 +#define PVD_CONFIG_TESTMODE_M (1 << PVD_CONFIG_TESTMODE_S) +#define PVD_CONFIG_UNDER_THRESH_S 4 +#define PVD_CONFIG_UNDER_THRESH_M (0b1111 << PVD_CONFIG_UNDER_THRESH_S) +#define PVD_CONFIG_OVER_THRESH_S 8 +#define PVD_CONFIG_OVER_THRESH_M (0b1111 << PVD_CONFIG_OVER_THRESH_S) +#define PVD_CONFIG_EN_VREFCLB_S 12 +#define PVD_CONFIG_EN_VREFCLB_M (1 << PVD_CONFIG_EN_VREFCLB_S) + +#define PVD_STATUS_UNDER_VALUE_S 0 +#define PVD_STATUS_UNDER_VALUE_M (1 << PVD_STATUS_UNDER_VALUE_S) +#define PVD_STATUS_OVER_VALUE_S 1 +#define PVD_STATUS_OVER_VALUE_M (1 << PVD_STATUS_OVER_VALUE_S) +#define PVD_STATUS_UNDER_FLAG_S 2 +#define PVD_STATUS_UNDER_FLAG_M (1 << PVD_STATUS_UNDER_FLAG_S) +#define PVD_STATUS_OVER_FLAG_S 3 +#define PVD_STATUS_OVER_FLAG_S (1 << PVD_STATUS_OVER_FLAG_S) + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t DPF_VALUE; + volatile uint32_t CONFIG; + volatile uint32_t STATUS; + } PVD_CONTROL_TypeDef; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif // PVD_CONTROL_H_INCLUDED + diff --git a/cores/arduino/mik32/shared/periphery/rtc.h b/cores/arduino/mik32/shared/periphery/rtc.h new file mode 100644 index 0000000..11f74fd --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/rtc.h @@ -0,0 +1,119 @@ +#ifndef RTC_H_INCLUDED +#define RTC_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define RTC_TIME_OFFSET 0x00 +#define RTC_DATE_OFFSET 0x04 +#define RTC_TALRM_OFFSET 0x08 +#define RTC_DALRM_OFFSET 0x0C +#define RTC_CTRL_OFFSET 0x10 +#define RTC_BACKUP_REG_OFFSET 0x20 + + + +#define RTC_CTRL_EN_S 31 +#define RTC_CTRL_EN_M (1 << RTC_CTRL_EN_S) +#define RTC_CTRL_ALRM_S 30 +#define RTC_CTRL_ALRM_M (1 << RTC_CTRL_ALRM_S) +#define RTC_CTRL_INTE_S 29 +#define RTC_CTRL_INTE_M (1 << RTC_CTRL_INTE_S) +#define RTC_CTRL_FLAG_S 28 +#define RTC_CTRL_FLAG_M (1 << RTC_CTRL_FLAG_S) +#define RTC_CTRL_RESET_STROBE_S 27 +#define RTC_CTRL_RESET_STROBE_M (1 << RTC_CTRL_RESET_STROBE_S) + + +#define RTC_TALRM_CDOW_S 31 +#define RTC_TALRM_CDOW_M (1 << RTC_TALRM_CDOW_S) +#define RTC_TALRM_CH_S 30 +#define RTC_TALRM_CH_M (1 << RTC_TALRM_CH_S) +#define RTC_TALRM_CM_S 29 +#define RTC_TALRM_CM_M (1 << RTC_TALRM_CM_S) +#define RTC_TALRM_CS_S 28 +#define RTC_TALRM_CS_M (1 << RTC_TALRM_CS_S) +#define RTC_TALRM_CTOS_S 27 +#define RTC_TALRM_CTOS_M (1 << RTC_TALRM_CTOS_S) + +#define RTC_DALRM_CC_S 30 +#define RTC_DALRM_CC_M (1 << RTC_DALRM_CC_S) +#define RTC_DALRM_CY_S 29 +#define RTC_DALRM_CY_M (1 << RTC_DALRM_CY_S) +#define RTC_DALRM_CM_S 28 +#define RTC_DALRM_CM_M (1 << RTC_DALRM_CM_S) +#define RTC_DALRM_CD_S 27 +#define RTC_DALRM_CD_M (1 << RTC_DALRM_CD_S) + +#define RTC_TIME_DOW_S 24 +#define RTC_TIME_DOW_M (0x7 << RTC_TIME_DOW_S) +#define RTC_TIME_TH_S 22 +#define RTC_TIME_TH_M (0x3 << RTC_TIME_TH_S) +#define RTC_TIME_H_S 18 +#define RTC_TIME_H_M (0xF << RTC_TIME_H_S) +#define RTC_TIME_TM_S 15 +#define RTC_TIME_TM_M (0x7 << RTC_TIME_TM_S) +#define RTC_TIME_M_S 11 +#define RTC_TIME_M_M (0xF << RTC_TIME_M_S) +#define RTC_TIME_TS_S 8 +#define RTC_TIME_TS_M (0x7 << RTC_TIME_TS_S) +#define RTC_TIME_S_S 4 +#define RTC_TIME_S_M (0xF << RTC_TIME_S_S) +#define RTC_TIME_TOS_S 0 +#define RTC_TIME_TOS_M (0xF << RTC_TIME_TOS_S) + +#define RTC_DATE_TC_S 23 +#define RTC_DATE_TC_M (0xF << RTC_DATE_TC_S) +#define RTC_DATE_C_S 19 +#define RTC_DATE_C_M (0xF << RTC_DATE_C_S) +#define RTC_DATE_TY_S 15 +#define RTC_DATE_TY_M (0xF << RTC_DATE_TY_S) +#define RTC_DATE_Y_S 11 +#define RTC_DATE_Y_M (0xF << RTC_DATE_Y_S) +#define RTC_DATE_TM_S 10 +#define RTC_DATE_TM_M (0x1 << RTC_DATE_TM_S) +#define RTC_DATE_M_S 6 +#define RTC_DATE_M_M (0xF << RTC_DATE_M_S) +#define RTC_DATE_TD_S 4 +#define RTC_DATE_TD_M (0x3 << RTC_DATE_TD_S) +#define RTC_DATE_D_S 0 +#define RTC_DATE_D_M (0xF << RTC_DATE_D_S) + + + +#ifndef _ASSEMBLER_ + #include + typedef struct + { + + union + { + struct { + volatile uint32_t TOS:4; + volatile uint32_t S:4; + volatile uint32_t TS:3; + volatile uint32_t M:4; + volatile uint32_t TM:3; + volatile uint32_t H:4; + volatile uint32_t TH:2; + volatile uint32_t DOW:3; + }; + uint32_t TIME; + }; + + volatile uint32_t DATE; + volatile uint32_t TALRM; + volatile uint32_t DALRM; + volatile uint32_t CTRL; + volatile uint32_t _space[3]; + volatile uint32_t REG[16]; + } RTC_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/cores/arduino/mik32/shared/periphery/scr1_timer.h b/cores/arduino/mik32/shared/periphery/scr1_timer.h new file mode 100644 index 0000000..8b86e9f --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/scr1_timer.h @@ -0,0 +1,35 @@ +#ifndef SCR1_TIMER_H_INCLUDED +#define SCR1_TIMER_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCR1_TIMER_CTRL_ENABLE_S 0 +#define SCR1_TIMER_CTRL_ENABLE_M (1 << SCR1_TIMER_CTRL_ENABLE_S) + +#define SCR1_TIMER_CTRL_CLKSRC_S 1 +#define SCR1_TIMER_CTRL_CLKSRC_M (1 << SCR1_TIMER_CTRL_CLKSRC_S) +#define SCR1_TIMER_CTRL_CLKSRC_INTERNAL_M (0 << SCR1_TIMER_CTRL_CLKSRC_S) +#define SCR1_TIMER_CTRL_CLKSRC_RTC_M (1 << SCR1_TIMER_CTRL_CLKSRC_S) + + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t TIMER_CTRL; + volatile uint32_t TIMER_DIV; + volatile uint32_t MTIME; + volatile uint32_t MTIMEH; + volatile uint32_t MTIMECMP; + volatile uint32_t MTIMECMPH; + } SCR1_TIMER_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif // SCR1_TIMER_H_INCLUDED diff --git a/cores/arduino/mik32/shared/periphery/spi_.h b/cores/arduino/mik32/shared/periphery/spi_.h new file mode 100644 index 0000000..5114ad1 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/spi_.h @@ -0,0 +1,123 @@ +#ifndef SPI_H_INCLUDED +#define SPI_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPI_CONFIG 0X00 +#define SPI_STATUS 0X04 +#define SPI_IEN 0X08 +#define SPI_IDIS 0X0C +#define SPI_IMASK 0X10 +#define SPI_ENABLE 0X14 +#define SPI_DELAY 0X18 +#define SPI_TXD 0X1C +#define SPI_RXD 0X20 +#define SPI_SIC 0X24 +#define SPI_THRESHOLD 0X28 +#define SPI_MODULE_ID 0XFC + + +#define SPI_CONFIG_MANUAL_CS_S 14 +#define SPI_CONFIG_MANUAL_CS_M (1 << SPI_CONFIG_MANUAL_CS_S) +// +#define SPI_CONFIG_CS_S 10 +#define SPI_CONFIG_CS_M (0XF << SPI_CONFIG_CS_S) +#define SPI_CONFIG_CS_0_M (0XE << SPI_CONFIG_CS_S) +#define SPI_CONFIG_CS_1_M (0XD << SPI_CONFIG_CS_S) +#define SPI_CONFIG_CS_2_M (0XB << SPI_CONFIG_CS_S) +#define SPI_CONFIG_CS_3_M (0X7 << SPI_CONFIG_CS_S) +#define SPI_CONFIG_CS_NONE_M (0XF << SPI_CONFIG_CS_S) +// +#define SPI_CONFIG_PERI_SEL_S 9 +#define SPI_CONFIG_PERI_SEL_M (1 << SPI_CONFIG_PERI_SEL_S) +#define SPI_CONFIG_REF_CLK_S 8 +#define SPI_CONFIG_REF_CLK_M (1 << SPI_CONFIG_REF_CLK_S) +// +#define SPI_CONFIG_BAUD_RATE_DIV_S 3 +#define SPI_CONFIG_BAUD_RATE_DIV_M (0X7 << SPI_CONFIG_BAUD_RATE_DIV_S) +#define SPI_CONFIG_BAUD_RATE_DIV_2_M (0X0 << SPI_CONFIG_BAUD_RATE_DIV_S) +#define SPI_CONFIG_BAUD_RATE_DIV_4_M (0X1 << SPI_CONFIG_BAUD_RATE_DIV_S) +#define SPI_CONFIG_BAUD_RATE_DIV_8_M (0X2 << SPI_CONFIG_BAUD_RATE_DIV_S) +#define SPI_CONFIG_BAUD_RATE_DIV_16_M (0X3 << SPI_CONFIG_BAUD_RATE_DIV_S) +#define SPI_CONFIG_BAUD_RATE_DIV_32_M (0X4 << SPI_CONFIG_BAUD_RATE_DIV_S) +#define SPI_CONFIG_BAUD_RATE_DIV_64_M (0X5 << SPI_CONFIG_BAUD_RATE_DIV_S) +#define SPI_CONFIG_BAUD_RATE_DIV_128_M (0X6 << SPI_CONFIG_BAUD_RATE_DIV_S) +#define SPI_CONFIG_BAUD_RATE_DIV_256_M (0X7 << SPI_CONFIG_BAUD_RATE_DIV_S) +// +#define SPI_MAXIMUM_BAUD_RATE_DIV 256 +// +#define SPI_CONFIG_CLK_PH_S 2 +#define SPI_CONFIG_CLK_PH_M (1 << SPI_CONFIG_CLK_PH_S) +#define SPI_CONFIG_CLK_POL_S 1 +#define SPI_CONFIG_CLK_POL_M (1 << SPI_CONFIG_CLK_POL_S) +#define SPI_CONFIG_MODE_SEL_S 0 +#define SPI_CONFIG_MODE_SEL_M (1 << SPI_CONFIG_MODE_SEL_S) +#define SPI_CONFIG_MASTER_M (1 << SPI_CONFIG_MODE_SEL_S) +#define SPI_CONFIG_SLAVE_M (0 << SPI_CONFIG_MODE_SEL_S) + + +#define SPI_ENABLE_CLEAR_RX_FIFO_S 3 +#define SPI_ENABLE_CLEAR_RX_FIFO_M (1 << SPI_ENABLE_CLEAR_RX_FIFO_S) +#define SPI_ENABLE_CLEAR_TX_FIFO_S 2 +#define SPI_ENABLE_CLEAR_TX_FIFO_M (1 << SPI_ENABLE_CLEAR_TX_FIFO_S) +#define SPI_ENABLE_S 0 +#define SPI_ENABLE_M (1 << SPI_ENABLE_S) + + +#define SPI_DELAY_BTWN_S 16 +#define SPI_DELAY_BTWN_M (0XFF << SPI_DELAY_BTWN_S) +#define SPI_DELAY_BTWN(V) (((V) << SPI_DELAY_BTWN_S) & SPI_DELAY_BTWN_M) +#define SPI_DELAY_AFTER_S 8 +#define SPI_DELAY_AFTER_M (0XFF << SPI_DELAY_AFTER_S) +#define SPI_DELAY_AFTER(V) (((V) << SPI_DELAY_AFTER_S) & SPI_DELAY_AFTER_M) +#define SPI_DELAY_INIT_S 0 +#define SPI_DELAY_INIT_M (0XFF << SPI_DELAY_INIT_S) +#define SPI_DELAY_INIT(V) (((V) << SPI_DELAY_INIT_S) & SPI_DELAY_INIT_M) + + +#define SPI_INT_STATUS_SPI_ACTIVE_S 15 +#define SPI_INT_STATUS_SPI_ACTIVE_M (1 << SPI_INT_STATUS_SPI_ACTIVE_S) +#define SPI_INT_STATUS_TX_FIFO_UNDERFLOW_S 6 +#define SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M (1 << SPI_INT_STATUS_TX_FIFO_UNDERFLOW_S) +#define SPI_INT_STATUS_RX_OVERFLOW_S 0 +#define SPI_INT_STATUS_RX_OVERFLOW_M (1 << SPI_INT_STATUS_RX_OVERFLOW_S) +#define SPI_INT_STATUS_MODE_FAIL_S 1 +#define SPI_INT_STATUS_MODE_FAIL_M (1 << SPI_INT_STATUS_MODE_FAIL_S) +#define SPI_INT_STATUS_TX_FIFO_NOT_FULL_S 2 +#define SPI_INT_STATUS_TX_FIFO_NOT_FULL_M (1 << SPI_INT_STATUS_TX_FIFO_NOT_FULL_S) +#define SPI_INT_STATUS_TX_FIFO_FULL_S 3 +#define SPI_INT_STATUS_TX_FIFO_FULL_M (1 << SPI_INT_STATUS_TX_FIFO_FULL_S) +#define SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_S 4 +#define SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M (1 << SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_S) +#define SPI_INT_STATUS_RX_FIFO_FULL_S 5 +#define SPI_INT_STATUS_RX_FIFO_FULL_M (1 << SPI_INT_STATUS_RX_FIFO_FULL_S) + + + +#ifndef _ASSEMBLER_ + #include + typedef struct + { + volatile uint32_t CONFIG; /* Offset: 0x000 (R/W) */ + volatile uint32_t INT_STATUS; /* Offset: 0x004 (R/RC) */ + volatile uint32_t INT_ENABLE; /* Offset: 0x008 (WO) */ + volatile uint32_t INT_DISABLE; /* Offset: 0x00C (WO) */ + volatile uint32_t INT_MASK; /* Offset: 0x010 (R) */ + volatile uint32_t ENABLE; /* Offset: 0x014 (R/W) */ + volatile uint32_t DELAY; /* Offset: 0x018 (R/W) */ + volatile uint32_t TXDATA; /* Offset: 0x01C (WO) */ + volatile uint32_t RXDATA; /* Offset: 0x020 (RO) */ + volatile uint32_t SIC; /* Offset: 0x024 (R/W) Slave_Idle_Count */ + volatile uint32_t TX_THR; /* Offset: 0x028 (R/W) TX threshold */ + volatile uint32_t reserved[0X34]; /* Empty array to fill the space*/ + volatile uint32_t ID; /* Offset: 0x0FC (RO) Module ID 0x01090100 */ + }SPI_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif // SPI_H_INCLUDED diff --git a/cores/arduino/mik32/shared/periphery/spifi.h b/cores/arduino/mik32/shared/periphery/spifi.h new file mode 100644 index 0000000..999815a --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/spifi.h @@ -0,0 +1,137 @@ +#ifndef SPIFI_H_INCLUDED +#define SPIFI_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +//CTRL +#define SPIFI_CONFIG_CTRL_TIMEOUT_S 0 +#define SPIFI_CONFIG_CTRL_TIMEOUT_M (0xFFFF << SPIFI_CONFIG_CTRL_TIMEOUT_S) +#define SPIFI_CONFIG_CTRL_TIMEOUT(v) (((v) << SPIFI_CONFIG_CTRL_TIMEOUT_S) & SPIFI_CONFIG_CTRL_TIMEOUT_M) +#define SPIFI_CONFIG_CTRL_CSHIGH_S 16 +#define SPIFI_CONFIG_CTRL_CSHIGH_M (0xF << SPIFI_CONFIG_CTRL_CSHIGH_S) +#define SPIFI_CONFIG_CTRL_CSHIGH(v) (((v) << SPIFI_CONFIG_CTRL_CSHIGH_S) & SPIFI_CONFIG_CTRL_CSHIGH_M) +#define SPIFI_CONFIG_CTRL_CACHE_EN_S 20 +#define SPIFI_CONFIG_CTRL_CACHE_EN_M (0x1 << SPIFI_CONFIG_CTRL_CACHE_EN_S) +#define SPIFI_CONFIG_CTRL_D_CACHE_DIS_S 21 +#define SPIFI_CONFIG_CTRL_D_CACHE_DIS_M (0x1 << SPIFI_CONFIG_CTRL_D_CACHE_DIS_S) +#define SPIFI_CONFIG_CTRL_INTEN_S 22 +#define SPIFI_CONFIG_CTRL_INTEN_M (0x1 << SPIFI_CONFIG_CTRL_INTEN_S) +#define SPIFI_CONFIG_CTRL_MODE3_S 23 +#define SPIFI_CONFIG_CTRL_MODE3_M (0x1 << SPIFI_CONFIG_CTRL_MODE3_S) +#define SPIFI_CONFIG_CTRL_SCK_DIV_S 24 +#define SPIFI_CONFIG_CTRL_SCK_DIV_M (0x7 << SPIFI_CONFIG_CTRL_SCK_DIV_S) +#define SPIFI_CONFIG_CTRL_SCK_DIV(v) (((v) << SPIFI_CONFIG_CTRL_SCK_DIV_S) & SPIFI_CONFIG_CTRL_SCK_DIV_M) +#define SPIFI_CONFIG_CTRL_PREFETCH_DIS_S 27 +#define SPIFI_CONFIG_CTRL_PREFETCH_DIS_M (0x1 << SPIFI_CONFIG_CTRL_PREFETCH_DIS_S) +#define SPIFI_CONFIG_CTRL_DUAL_S 28 +#define SPIFI_CONFIG_CTRL_DUAL_M (0x1 << SPIFI_CONFIG_CTRL_DUAL_S) +#define SPIFI_CONFIG_CTRL_RFCLK_S 29 +#define SPIFI_CONFIG_CTRL_RFCLK_M (0x1 << SPIFI_CONFIG_CTRL_RFCLK_S) +#define SPIFI_CONFIG_CTRL_FBCLK_S 30 +#define SPIFI_CONFIG_CTRL_FBCLK_M (0x1 << SPIFI_CONFIG_CTRL_FBCLK_S) +#define SPIFI_CONFIG_CTRL_DMAEN_S 31 +#define SPIFI_CONFIG_CTRL_DMAEN_M (0x1 << SPIFI_CONFIG_CTRL_DMAEN_S) + +//CMD +#define SPIFI_CONFIG_CMD_DATALEN_S 0 +#define SPIFI_CONFIG_CMD_DATALEN_M (0x3FFF << SPIFI_CONFIG_CMD_DATALEN_S) +#define SPIFI_CONFIG_CMD_DATALEN(v) (((v) << SPIFI_CONFIG_CMD_DATALEN_S) & SPIFI_CONFIG_CMD_DATALEN_M) +#define SPIFI_CONFIG_CMD_POLL_INDEX_S 0 +#define SPIFI_CONFIG_CMD_POLL_INDEX_M (0b111 << SPIFI_CONFIG_CMD_POLL_INDEX_S) +#define SPIFI_CONFIG_CMD_POLL_INDEX(v) (((v) << SPIFI_CONFIG_CMD_POLL_INDEX_S) & SPIFI_CONFIG_CMD_POLL_INDEX_M) +#define SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE_S 3 +#define SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE_M (1 << SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE_S) +#define SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE(v) (((v) << SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE_S) & SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE_M) +#define SPIFI_CONFIG_CMD_POLL_S 14 +#define SPIFI_CONFIG_CMD_POLL_M (0x1 << SPIFI_CONFIG_CMD_POLL_S) +#define SPIFI_CONFIG_CMD_DOUT_S 15 +#define SPIFI_CONFIG_CMD_DOUT_M (0x1 << SPIFI_CONFIG_CMD_DOUT_S) +#define SPIFI_CONFIG_CMD_INTLEN_S 16 +#define SPIFI_CONFIG_CMD_INTLEN_M (0x7 << SPIFI_CONFIG_CMD_INTLEN_S) +#define SPIFI_CONFIG_CMD_INTLEN(v) (((v) << SPIFI_CONFIG_CMD_INTLEN_S) & SPIFI_CONFIG_CMD_INTLEN_M) +#define SPIFI_CONFIG_CMD_FIELDFORM_S 19 +#define SPIFI_CONFIG_CMD_FIELDFORM_M (0x3 << SPIFI_CONFIG_CMD_FIELDFORM_S) +#define SPIFI_CONFIG_CMD_FIELDFORM(v) (((v) << SPIFI_CONFIG_CMD_FIELDFORM_S) & SPIFI_CONFIG_CMD_FIELDFORM_M) +#define SPIFI_CONFIG_CMD_FRAMEFORM_S 21 +#define SPIFI_CONFIG_CMD_FRAMEFORM_M (0x7 << SPIFI_CONFIG_CMD_FRAMEFORM_S) +#define SPIFI_CONFIG_CMD_FRAMEFORM(v) (((v) << SPIFI_CONFIG_CMD_FRAMEFORM_S) & SPIFI_CONFIG_CMD_FRAMEFORM_M) +#define SPIFI_CONFIG_CMD_OPCODE_S 24 +#define SPIFI_CONFIG_CMD_OPCODE_M (0xFF << SPIFI_CONFIG_CMD_OPCODE_S) +#define SPIFI_CONFIG_CMD_OPCODE(v) (((v) << SPIFI_CONFIG_CMD_OPCODE_S) & SPIFI_CONFIG_CMD_OPCODE_M) + +#define SPIFI_CONFIG_CMD_FRAMEFORM_RESERVED 0 +#define SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_NOADDR 1 +#define SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_1ADDR 2 +#define SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_2ADDR 3 +#define SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_3ADDR 4 +#define SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_4ADDR 5 +#define SPIFI_CONFIG_CMD_FRAMEFORM_NOOPCODE_3ADDR 6 +#define SPIFI_CONFIG_CMD_FRAMEFORM_NOOPCODE_4ADDR 7 + +#define SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL 0 +#define SPIFI_CONFIG_CMD_FIELDFORM_DATA_PARALLEL 1 +#define SPIFI_CONFIG_CMD_FIELDFORM_OPCODE_SERIAL 2 +#define SPIFI_CONFIG_CMD_FIELDFORM_ALL_PARALLEL 3 + +//ADDR +//IDATA +//CLIMIT +//DATA + +//MCMD +#define SPIFI_CONFIG_MCMD_POLL_S 14 +#define SPIFI_CONFIG_MCMD_POLL_M (0x1 << SPIFI_CONFIG_MCMD_POLL_S) +#define SPIFI_CONFIG_MCMD_DOUT_S 15 +#define SPIFI_CONFIG_MCMD_DOUT_M (0x1 << SPIFI_CONFIG_MCMD_DOUT_S) +#define SPIFI_CONFIG_MCMD_INTLEN_S 16 +#define SPIFI_CONFIG_MCMD_INTLEN_M (0x7 << SPIFI_CONFIG_MCMD_INTLEN_S) +#define SPIFI_CONFIG_MCMD_FIELDFORM_S 19 +#define SPIFI_CONFIG_MCMD_FIELDFORM_M (0x3 << SPIFI_CONFIG_MCMD_FIELDFORM_S) +#define SPIFI_CONFIG_MCMD_FRAMEFORM_S 21 +#define SPIFI_CONFIG_MCMD_FRAMEFORM_M (0x7 << SPIFI_CONFIG_MCMD_FRAMEFORM_S) +#define SPIFI_CONFIG_MCMD_OPCODE_S 24 +#define SPIFI_CONFIG_MCMD_OPCODE_M (0xFF << SPIFI_CONFIG_MCMD_OPCODE_S) + +//STATUS +#define SPIFI_CONFIG_STAT_MCINIT_S 0 +#define SPIFI_CONFIG_STAT_MCINIT_M (0x1 << SPIFI_CONFIG_STAT_MCINIT_S) +#define SPIFI_CONFIG_STAT_CMD_S 1 +#define SPIFI_CONFIG_STAT_CMD_M (0x1 << SPIFI_CONFIG_STAT_CMD_S) +#define SPIFI_CONFIG_STAT_RESET_S 4 +#define SPIFI_CONFIG_STAT_RESET_M (0x1 << SPIFI_CONFIG_STAT_RESET_S) +#define SPIFI_CONFIG_STAT_INTRQ_S 5 +#define SPIFI_CONFIG_STAT_INTRQ_M (0x1 << SPIFI_CONFIG_STAT_INTRQ_S) +#define SPIFI_CONFIG_STAT_VERSION_S 24 +#define SPIFI_CONFIG_STAT_VERSION_M (0xFF << SPIFI_CONFIG_STAT_VERSION_S) + + +#ifndef _ASSEMBLER_ + #include + typedef struct + { + volatile uint32_t CTRL; //Offset: 0x000 + volatile uint32_t CMD; //Offset: 0x004 + volatile uint32_t ADDR; //Offset: 0x008 + volatile uint32_t IDATA; //Offset: 0x00C + volatile uint32_t CLIMIT; //Offset: 0x010 + union + { + volatile uint32_t DATA; //Offset: 0x014 + volatile uint8_t DATA8; + volatile uint16_t DATA16; + volatile uint32_t DATA32; + }; + + volatile uint32_t MCMD; //Offset: 0x018 + volatile uint32_t STAT; //Offset: 0x01C + }SPIFI_CONFIG_TypeDef; +#endif + + +#ifdef __cplusplus +} +#endif + +#endif // SPIFI_H_INCLUDED diff --git a/cores/arduino/mik32/shared/periphery/timer16.h b/cores/arduino/mik32/shared/periphery/timer16.h new file mode 100644 index 0000000..ac615fc --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/timer16.h @@ -0,0 +1,178 @@ +#ifndef TIMER16_H_INCLUDED +#define TIMER16_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define TIMER16_SYNC_CLOCKS 2 + +#define TIMER16_ISR 0x00 +#define TIMER16_ICR 0x04 +#define TIMER16_IER 0x08 +#define TIMER16_CFGR 0x0C +#define TIMER16_CR 0x10 +#define TIMER16_CMP 0x14 +#define TIMER16_ARR 0x18 +#define TIMER16_CNT 0x1C + +#define TIMER16_ENABLE_S 0 +#define TIMER16_ENABLE_M (1 << TIMER16_ENABLE_S) +#define TIMER16_DISABLE_M (0 << TIMER16_ENABLE_S) +#define TIMER16_START_SINGLE_MODE_S 1 +#define TIMER16_START_SINGLE_MODE_M (1 << TIMER16_START_SINGLE_MODE_S) +#define TIMER16_START_CONTIN_MODE_S 2 +#define TIMER16_START_CONTIN_MODE_M (1 << TIMER16_START_CONTIN_MODE_S) + + +#define TIMER16_PRESCALER_S 9 +#define TIMER16_PRESCALER_1_M (0x0 << TIMER16_PRESCALER_S) +#define TIMER16_PRESCALER_2_M (0x1 << TIMER16_PRESCALER_S) +#define TIMER16_PRESCALER_4_M (0x2 << TIMER16_PRESCALER_S) +#define TIMER16_PRESCALER_8_M (0x3 << TIMER16_PRESCALER_S) +#define TIMER16_PRESCALER_16_M (0x4 << TIMER16_PRESCALER_S) +#define TIMER16_PRESCALER_32_M (0x5 << TIMER16_PRESCALER_S) +#define TIMER16_PRESCALER_64_M (0x6 << TIMER16_PRESCALER_S) +#define TIMER16_PRESCALER_128_M (0x7 << TIMER16_PRESCALER_S) + +// Alias for CFGR.ENC bit +#define TIMER16_ENCODER_S 24 +#define TIMER16_ENCODER_DISABLE_M (0x0 << TIMER16_ENCODER_S) +#define TIMER16_ENCODER_ENABLE_M (0x1 << TIMER16_ENCODER_S) + +// Маски и сдвиги флагов прерываний +#define TIMER16_INT_CMP_MATCH_S 0 +#define TIMER16_INT_CMP_MATCH_M (0x1 << TIMER16_INT_CMP_MATCH_S) +#define TIMER16_INT_ARR_MATCH_S 1 +#define TIMER16_INT_ARR_MATCH_M (0x1 << TIMER16_INT_ARR_MATCH_S) +#define TIMER16_INT_EXT_TRIG_S 2 +#define TIMER16_INT_EXT_TRIG_M (0x1 << TIMER16_INT_EXT_TRIG_S) +#define TIMER16_INT_CMP_OK_S 3 +#define TIMER16_INT_CMP_OK_M (0x1 << TIMER16_INT_CMP_OK_S) +#define TIMER16_INT_ARR_OK_S 4 +#define TIMER16_INT_ARR_OK_M (0x1 << TIMER16_INT_ARR_OK_S) +#define TIMER16_INT_UP_S 5 +#define TIMER16_INT_UP_M (0x1 << TIMER16_INT_UP_S) +#define TIMER16_INT_DOWN_S 6 +#define TIMER16_INT_DOWN_M (0x1 << TIMER16_INT_DOWN_S) + +// Регистр ISR +#define TIMER16_ISR_CMP_MATCH_S 0 +#define TIMER16_ISR_CMP_MATCH_M (0x1 << TIMER16_ISR_CMP_MATCH_S) +#define TIMER16_ISR_ARR_MATCH_S 1 +#define TIMER16_ISR_ARR_MATCH_M (0x1 << TIMER16_ISR_ARR_MATCH_S) +#define TIMER16_ISR_EXT_TRIG_S 2 +#define TIMER16_ISR_EXT_TRIG_M (0x1 << TIMER16_ISR_EXT_TRIG_S) +#define TIMER16_ISR_CMP_OK_S 3 +#define TIMER16_ISR_CMP_OK_M (0x1 << TIMER16_ISR_CMP_OK_S) +#define TIMER16_ISR_ARR_OK_S 4 +#define TIMER16_ISR_ARR_OK_M (0x1 << TIMER16_ISR_ARR_OK_S) +#define TIMER16_ISR_UP_S 5 +#define TIMER16_ISR_UP_M (0x1 << TIMER16_ISR_UP_S) +#define TIMER16_ISR_DOWN_S 6 +#define TIMER16_ISR_DOWN_M (0x1 << TIMER16_ISR_DOWN_S) + +// Регистр ICR +#define TIMER16_ICR_DOWNCF_S 6 +#define TIMER16_ICR_DOWNCF_M (0x1 << TIMER16_ICR_DOWNCF_S) +#define TIMER16_ICR_UPCF_S 5 +#define TIMER16_ICR_UPCF_M (0x1 << TIMER16_ICR_UPCF_S) +#define TIMER16_ICR_ARROKCF_S 4 +#define TIMER16_ICR_ARROKCF_M (0x1 << TIMER16_ICR_ARROKCF_S) +#define TIMER16_ICR_CMPOKCF_S 3 +#define TIMER16_ICR_CMPOKCF_M (0x1 << TIMER16_ICR_CMPOKCF_S) +#define TIMER16_ICR_EXTTRIGCF_S 2 +#define TIMER16_ICR_EXTTRIGCF_M (0x1 << TIMER16_ICR_EXTTRIGCF_S) +#define TIMER16_ICR_ARRMCF_S 1 +#define TIMER16_ICR_ARRMCF_M (0x1 << TIMER16_ICR_ARRMCF_S) +#define TIMER16_ICR_CMPMCF_S 0 +#define TIMER16_ICR_CMPMCF_M (0x1 << TIMER16_ICR_CMPMCF_S) + +// Регистр IER +#define TIMER16_IER_DOWNIE_S 6 +#define TIMER16_IER_DOWNIE_M (0x1 << TIMER16_IER_DOWNIE_S) +#define TIMER16_IER_UPIE_S 5 +#define TIMER16_IER_UPIE_M (0x1 << TIMER16_IER_UPIE_S) +#define TIMER16_IER_ARROKIE_S 4 +#define TIMER16_IER_ARROKIE_M (0x1 << TIMER16_IER_ARROKIE_S) +#define TIMER16_IER_CMPOKIE_S 3 +#define TIMER16_IER_CMPOKIE_M (0x1 << TIMER16_IER_CMPOKIE_S) +#define TIMER16_IER_EXTTRIGIE_S 2 +#define TIMER16_IER_EXTTRIGIE_M (0x1 << TIMER16_IER_EXTTRIGIE_S) +#define TIMER16_IER_ARRMIE_S 1 +#define TIMER16_IER_ARRMIE_M (0x1 << TIMER16_IER_ARRMIE_S) +#define TIMER16_IER_CMPMIE_S 0 +#define TIMER16_IER_CMPMIE_M (0x1 << TIMER16_IER_CMPMIE_S) + +// Регистр CFGR +#define TIMER16_CFGR_ENC_S 24 +#define TIMER16_CFGR_ENC_M (1 << TIMER16_CFGR_ENC_S) +#define TIMER16_CFGR_COUNTMODE_S 23 +#define TIMER16_CFGR_COUNTMODE_M (1 << TIMER16_CFGR_COUNTMODE_S) +#define TIMER16_CFGR_PRELOAD_S 22 +#define TIMER16_CFGR_PRELOAD_M (1 << TIMER16_CFGR_PRELOAD_S) +#define TIMER16_CFGR_WAVPOL_S 21 +#define TIMER16_CFGR_WAVPOL_M (1 << TIMER16_CFGR_WAVPOL_S) +#define TIMER16_CFGR_WAVE_S 20 +#define TIMER16_CFGR_WAVE_M (1 << TIMER16_CFGR_WAVE_S) +#define TIMER16_CFGR_TIMOUT_S 19 +#define TIMER16_CFGR_TIMOUT_M (1 << TIMER16_CFGR_TIMOUT_S) +#define TIMER16_CFGR_TRIGEN_S 17 +#define TIMER16_CFGR_TRIGEN_M (0x3 << TIMER16_CFGR_TRIGEN_S) +// +#define TIMER16_CFGR_TRIGSEL_S 13 +#define TIMER16_CFGR_TRIGSEL_M (0x7 << TIMER16_CFGR_TRIGSEL_S) +#define TIMER16_CFGR_PRESC_S 9 +#define TIMER16_CFGR_PRESC_M (0x111 << TIMER16_CFGR_PRESC_S) +// +#define TIMER16_CFGR_TRGFLT_S 6 +#define TIMER16_CFGR_TRGFLT_M (0x3 << TIMER16_CFGR_TRGFLT_S) +#define TIMER16_CFGR_TRGFLT_DISABLED_M (0x0 << TIMER16_CFGR_TRGFLT_S) +#define TIMER16_CFGR_TRGFLT_2_M (0x1 << TIMER16_CFGR_TRGFLT_S) +#define TIMER16_CFGR_TRGFLT_4_M (0x2 << TIMER16_CFGR_TRGFLT_S) +#define TIMER16_CFGR_TRGFLT_8_M (0x3 << TIMER16_CFGR_TRGFLT_S) +#define TIMER16_CFGR_CKFLT_S 3 +#define TIMER16_CFGR_CKFLT_M (0x3 << TIMER16_CFGR_CKFLT_S) +#define TIMER16_CFGR_CKFLT_DISABLED_M (0x0 << TIMER16_CFGR_CKFLT_S) +#define TIMER16_CFGR_CKFLT_2_M (0x1 << TIMER16_CFGR_CKFLT_S) +#define TIMER16_CFGR_CKFLT_4_M (0x2 << TIMER16_CFGR_CKFLT_S) +#define TIMER16_CFGR_CKFLT_8_M (0x3 << TIMER16_CFGR_CKFLT_S) +#define TIMER16_CFGR_CKPOL_S 1 +#define TIMER16_CFGR_CKPOL_M (0x3 << TIMER16_CFGR_CKPOL_S) +#define TIMER16_CFGR_CKPOL_RISING_M (0x0 << TIMER16_CFGR_CKPOL_S) +#define TIMER16_CFGR_CKPOL_FALLING_M (0x1 << TIMER16_CFGR_CKPOL_S) +#define TIMER16_CFGR_CKPOL_ANY_M (0x2 << TIMER16_CFGR_CKPOL_S) +#define TIMER16_CFGR_CKSEL_S 0 +#define TIMER16_CFGR_CKSEL_M (1 << TIMER16_CFGR_CKSEL_S) +#define TIMER16_CFGR_CKSEL_INTERNAL_M (0x0 << TIMER16_CFGR_CKSEL_S) +#define TIMER16_CFGR_CKSEL_EXTERNAL_M (0x1 << TIMER16_CFGR_CKSEL_S) + +// Регистр CR +#define TIMER16_CR_CNTSTRT_S 2 +#define TIMER16_CR_CNTSTRT_M (1 << TIMER16_CR_CNTSTRT_S) +#define TIMER16_CR_SNGSTRT_S 1 +#define TIMER16_CR_SNGSTRT_M (1 << TIMER16_CR_SNGSTRT_S) +#define TIMER16_CR_ENABLE_S 0 +#define TIMER16_CR_ENABLE_M (1 << TIMER16_CR_ENABLE_S) + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t ISR; + volatile uint32_t ICR; + volatile uint32_t IER; + volatile uint32_t CFGR; + volatile uint32_t CR; + volatile uint32_t CMP; + volatile uint32_t ARR; + volatile uint32_t CNT; + } TIMER16_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif // TIMER16_H_INCLUDED diff --git a/cores/arduino/mik32/shared/periphery/timer32.h b/cores/arduino/mik32/shared/periphery/timer32.h new file mode 100644 index 0000000..68941dc --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/timer32.h @@ -0,0 +1,123 @@ +#ifndef TIMER32_H_INCLUDED +#define TIMER32_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define TIMER32_VALUE 0x00 +#define TIMER32_TOP 0x04 +#define TIMER32_PRESCALER 0x08 +#define TIMER32_CONTROL 0x0C +#define TIMER32_ENABLE 0x10 + +#define TIMER32_INT_MASK 0x14 +#define TIMER32_INT_CLEAR 0x18 +#define TIMER32_INT_FLAGS 0x1C + +#define TIMER32_CH_BASE 0x80 +#define TIMER32_CH_CONTROL_OFFSET 0x00 +#define TIMER32_CH_OCR_OFFSET 0x04 +#define TIMER32_CH_ICR_OFFSET 0x08 +#define TIMER32_CH_SIZE 0x10 + + +// PRESCALER +#define TIMER32_PRESCALER_ENABLE_S 8 +#define TIMER32_PRESCALER_ENABLE_M (1 << TIMER32_PRESCALER_ENABLE_S) +#define TIMER32_PRESCALER_DISABLE_M (0 << TIMER32_PRESCALER_ENABLE_S) +// +#define TIMER32_PRESCALER_S 0 +#define TIMER32_PRESCALER_M (0xFF << TIMER32_PRESCALER_S) + +// CONTROL +#define TIMER32_CONTROL_CLOCK_S 2 +#define TIMER32_CONTROL_CLOCK_M (0x3 << TIMER32_CONTROL_CLOCK_S) +#define TIMER32_CONTROL_CLOCK_PRESCALER_M (0x0 << TIMER32_CONTROL_CLOCK_S) +#define TIMER32_CONTROL_CLOCK_TIM1_M (0x1 << TIMER32_CONTROL_CLOCK_S) +#define TIMER32_CONTROL_CLOCK_TX_PIN_M (0x2 << TIMER32_CONTROL_CLOCK_S) +#define TIMER32_CONTROL_CLOCK_TIM2_M (0x3 << TIMER32_CONTROL_CLOCK_S) +// +#define TIMER32_CONTROL_MODE_S 0 +#define TIMER32_CONTROL_MODE_M (0x3 << TIMER32_CONTROL_MODE_S) +#define TIMER32_CONTROL_MODE_UP_M (0 << TIMER32_CONTROL_MODE_S) +#define TIMER32_CONTROL_MODE_DOWN_M (1 << TIMER32_CONTROL_MODE_S) +#define TIMER32_CONTROL_MODE_BIDIR_M (2 << TIMER32_CONTROL_MODE_S) + +// ENABLE +#define TIMER32_ENABLE_TIM_CLR_S 1 +#define TIMER32_ENABLE_TIM_CLR_M (1 << TIMER32_ENABLE_TIM_CLR_S) +// +#define TIMER32_ENABLE_TIM_EN_S 0 +#define TIMER32_ENABLE_TIM_EN_M (1 << TIMER32_ENABLE_TIM_EN_S) + +// INT_MASK, INT_CLEAR, INT_FLAGS +#define TIMER32_INT_OVERFLOW_S 0 +#define TIMER32_INT_OVERFLOW_M (1 << TIMER32_INT_OVERFLOW_S) +#define TIMER32_INT_UNDERFLOW_S 1 +#define TIMER32_INT_UNDERFLOW_M (1 << TIMER32_INT_UNDERFLOW_S) +#define TIMER32_INT_IC_S 2 +#define TIMER32_INT_IC_M(channelIndex) ((1 << channelIndex) << TIMER32_INT_IC_S) +#define TIMER32_INT_OC_S 6 +#define TIMER32_INT_OC_M(channelIndex) ((1 << channelIndex) << TIMER32_INT_OC_S) + + +//CH_CNTRL +#define TIMER32_CH_CNTRL_NOISE_S 0 +#define TIMER32_CH_CNTRL_NOISE_M (1 << TIMER32_CH_CNTRL_NOISE_S) +// +#define TIMER32_CH_CNTRL_CAPTURE_EDGE_S 4 +#define TIMER32_CH_CNTRL_CAPTURE_EDGE_M (1 << TIMER32_CH_CNTRL_CAPTURE_EDGE_S) +#define TIMER32_CH_CNTRL_CAPTURE_POS_M (0 << TIMER32_CH_CNTRL_CAPTURE_EDGE_S) +#define TIMER32_CH_CNTRL_CAPTURE_NEG_M (1 << TIMER32_CH_CNTRL_CAPTURE_EDGE_S) +// +#define TIMER32_CH_CNTRL_MODE_S 5 +#define TIMER32_CH_CNTRL_MODE_M (3 << TIMER32_CH_CNTRL_MODE_S) +#define TIMER32_CH_CNTRL_MODE_COMPARE_M (1 << TIMER32_CH_CNTRL_MODE_S) +#define TIMER32_CH_CNTRL_MODE_CAPTURE_M (2 << TIMER32_CH_CNTRL_MODE_S) +#define TIMER32_CH_CNTRL_MODE_PWM_M (3 << TIMER32_CH_CNTRL_MODE_S) +// +#define TIMER32_CH_CNTRL_ENABLE_S 7 +#define TIMER32_CH_CNTRL_ENABLE_M (1 << TIMER32_CH_CNTRL_ENABLE_S) +#define TIMER32_CH_CNTRL_DISABLE_M (0 << TIMER32_CH_CNTRL_ENABLE_S) +// +#define TIMER32_CH_CNTRL_INVERTED_PWM_S 8 +#define TIMER32_CH_CNTRL_INVERTED_PWM_M (1 << TIMER32_CH_CNTRL_INVERTED_PWM_S) +// +#define TIMER32_CH_CNTRL_DIR_S 9 +#define TIMER32_CH_CNTRL_DIR_M (1 << TIMER32_CH_CNTRL_DIR_S) + + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t CNTRL; + volatile uint32_t OCR; + volatile uint32_t ICR; + volatile uint32_t reserved0; + } TIMER32_CHANNEL_TypeDef; + + typedef struct + { + volatile uint32_t VALUE; /* Offset: 0x000 (R) */ + volatile uint32_t TOP; /* Offset: 0x004 (R/W) */ + volatile uint32_t PRESCALER; /* Offset: 0x008 (R/W) */ + volatile uint32_t CONTROL; /* Offset: 0x00C (R/W) */ + volatile uint32_t ENABLE; /* Offset: 0x010 (R/W) */ + volatile uint32_t INT_MASK; /* Offset: 0x014 (R/W) */ + volatile uint32_t INT_CLEAR; /* Offset: 0x018 (R/W) */ + volatile uint32_t INT_FLAGS; /* Offset: 0x01C (R) */ + + volatile uint8_t reserved0[0x60]; + TIMER32_CHANNEL_TypeDef CHANNELS[4]; + + } TIMER32_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif // TIMER32_H_INCLUDED diff --git a/cores/arduino/mik32/shared/periphery/uart.h b/cores/arduino/mik32/shared/periphery/uart.h new file mode 100644 index 0000000..329cd4a --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/uart.h @@ -0,0 +1,158 @@ +#ifndef UART_H_INCLUDED +#define UART_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define UART_CONTROL1_M1_S 28 +#define UART_CONTROL1_M1_M (1 << UART_CONTROL1_M1_S) +#define UART_CONTROL1_M0_S 12 +#define UART_CONTROL1_M0_M (1 << UART_CONTROL1_M0_S) +#define UART_CONTROL1_M_8BIT_M (0) +#define UART_CONTROL1_M_9BIT_M (UART_CONTROL1_M0_M) +#define UART_CONTROL1_M_7BIT_M (UART_CONTROL1_M1_M) +#define UART_CONTROL1_M_M (UART_CONTROL1_M1_M | UART_CONTROL1_M0_M) +#define UART_CONTROL1_M(V) (((((v) / 10) << UART_CONTROL1_M1_S) | (((v) % 10) << UART_CONTROL1_M0_S)) & UART_CONTROL1_M_M) +#define UART_CONTROL1_PCE_S 10 +#define UART_CONTROL1_PCE_M (1 << UART_CONTROL1_PCE_S) +#define UART_CONTROL1_PS_S 9 +#define UART_CONTROL1_PS_M (1 << UART_CONTROL1_PS_S) +#define UART_CONTROL1_PEIE_S 8 +#define UART_CONTROL1_PEIE_M (1 << UART_CONTROL1_PEIE_S) +#define UART_CONTROL1_TXEIE_S 7 +#define UART_CONTROL1_TXEIE_M (1 << UART_CONTROL1_TXEIE_S) +#define UART_CONTROL1_TCIE_S 6 +#define UART_CONTROL1_TCIE_M (1 << UART_CONTROL1_TCIE_S) +#define UART_CONTROL1_RXNEIE_S 5 +#define UART_CONTROL1_RXNEIE_M (1 << UART_CONTROL1_RXNEIE_S) +#define UART_CONTROL1_IDLEIE_S 4 +#define UART_CONTROL1_IDLEIE_M (1 << UART_CONTROL1_IDLEIE_S) +#define UART_CONTROL1_TE_S 3 +#define UART_CONTROL1_TE_M (1 << UART_CONTROL1_TE_S) +#define UART_CONTROL1_RE_S 2 +#define UART_CONTROL1_RE_M (1 << UART_CONTROL1_RE_S) +#define UART_CONTROL1_UE_S 0 +#define UART_CONTROL1_UE_M (1 << UART_CONTROL1_UE_S) + +#define UART_CONTROL2_MSBFIRST_S 19 +#define UART_CONTROL2_MSBFIRST_M (1 << UART_CONTROL2_MSBFIRST_S) +#define UART_CONTROL2_DATAINV_S 18 +#define UART_CONTROL2_DATAINV_M (1 << UART_CONTROL2_DATAINV_S) +#define UART_CONTROL2_TXINV_S 17 +#define UART_CONTROL2_TXINV_M (1 << UART_CONTROL2_TXINV_S) +#define UART_CONTROL2_RXINV_S 16 +#define UART_CONTROL2_RXINV_M (1 << UART_CONTROL2_RXINV_S) +#define UART_CONTROL2_SWAP_S 15 +#define UART_CONTROL2_SWAP_M (1 << UART_CONTROL2_SWAP_S) +#define UART_CONTROL2_LBM_S 14 +#define UART_CONTROL2_LBM_M (1 << UART_CONTROL2_LBM_S) +#define UART_CONTROL2_STOP_1_S 13 +#define UART_CONTROL2_STOP_1_M (1 << UART_CONTROL2_STOP_1_S) +#define UART_CONTROL2_CLKEN_S 11 +#define UART_CONTROL2_CLKEN_M (1 << UART_CONTROL2_CLKEN_S) +#define UART_CONTROL2_CPOL_S 10 +#define UART_CONTROL2_CPOL_M (1 << UART_CONTROL2_CPOL_S) +#define UART_CONTROL2_CPHA_S 9 +#define UART_CONTROL2_CPHA_M (1 << UART_CONTROL2_CPHA_S) +#define UART_CONTROL2_LBCL_S 8 +#define UART_CONTROL2_LBCL_M (1 << UART_CONTROL2_LBCL_S) +#define UART_CONTROL2_LBDIE_S 6 +#define UART_CONTROL2_LBDIE_M (1 << UART_CONTROL2_LBDIE_S) + +#define UART_CONTROL3_OVRDIS_S 12 +#define UART_CONTROL3_OVRDIS_M (1 << UART_CONTROL3_OVRDIS_S) +#define UART_CONTROL3_CTSIE_S 10 +#define UART_CONTROL3_CTSIE_M (1 << UART_CONTROL3_CTSIE_S) +#define UART_CONTROL3_CTSE_S 9 +#define UART_CONTROL3_CTSE_M (1 << UART_CONTROL3_CTSE_S) +#define UART_CONTROL3_RTSE_S 8 +#define UART_CONTROL3_RTSE_M (1 << UART_CONTROL3_RTSE_S) +#define UART_CONTROL3_DMAT_S 7 +#define UART_CONTROL3_DMAT_M (1 << UART_CONTROL3_DMAT_S) +#define UART_CONTROL3_DMAR_S 6 +#define UART_CONTROL3_DMAR_M (1 << UART_CONTROL3_DMAR_S) +#define UART_CONTROL3_HDSEL_S 3 +#define UART_CONTROL3_HDSEL_M (1 << UART_CONTROL3_HDSEL_S) +#define UART_CONTROL3_BKRQ_S 2 +#define UART_CONTROL3_BKRQ_M (1 << UART_CONTROL3_BKRQ_S) +// #define UART_CONTROL3_IREN_S 1 +// #define UART_CONTROL3_IREN_M (1 << UART_CONTROL3_IREN_S) +#define UART_CONTROL3_EIE_S 0 +#define UART_CONTROL3_EIE_M (1 << UART_CONTROL3_EIE_S) + +#define UART_DIVIDER_BRR_S 0 +#define UART_DIVIDER_BRR_M (0xFFFF << UART_DIVIDER_BRR_S) + +#define UART_FLAGS_REACK_S 22 +#define UART_FLAGS_REACK_M (1 << UART_FLAGS_REACK_S) +#define UART_FLAGS_TEACK_S 21 +#define UART_FLAGS_TEACK_M (1 << UART_FLAGS_TEACK_S) +#define UART_FLAGS_BUSY_S 16 +#define UART_FLAGS_BUSY_M (1 << UART_FLAGS_BUSY_S) +#define UART_FLAGS_CTS_S 10 +#define UART_FLAGS_CTS_M (1 << UART_FLAGS_CTS_S) +#define UART_FLAGS_CTSIF_S 9 +#define UART_FLAGS_CTSIF_M (1 << UART_FLAGS_CTSIF_S) +#define UART_FLAGS_LBDF_S 8 +#define UART_FLAGS_LBDF_M (1 << UART_FLAGS_LBDF_S) +#define UART_FLAGS_TXE_S 7 +#define UART_FLAGS_TXE_M (1 << UART_FLAGS_TXE_S) +#define UART_FLAGS_TC_S 6 +#define UART_FLAGS_TC_M (1 << UART_FLAGS_TC_S) +#define UART_FLAGS_RXNE_S 5 +#define UART_FLAGS_RXNE_M (1 << UART_FLAGS_RXNE_S) +#define UART_FLAGS_IDLE_S 4 +#define UART_FLAGS_IDLE_M (1 << UART_FLAGS_IDLE_S) +#define UART_FLAGS_ORE_S 3 +#define UART_FLAGS_ORE_M (1 << UART_FLAGS_ORE_S) +#define UART_FLAGS_NF_S 2 +#define UART_FLAGS_NF_M (1 << UART_FLAGS_NF_S) +#define UART_FLAGS_FE_S 1 +#define UART_FLAGS_FE_M (1 << UART_FLAGS_FE_S) +#define UART_FLAGS_PE_S 0 +#define UART_FLAGS_PE_M (1 << UART_FLAGS_PE_S) + +#define UART_MODEM_DTR_S 8 +#define UART_MODEM_DTR_M (1 << UART_MODEM_DTR_S) +#define UART_MODEM_DCD_S 7 +#define UART_MODEM_DCD_M (1 << UART_MODEM_DCD_S) +#define UART_MODEM_RI_S 6 +#define UART_MODEM_RI_M (1 << UART_MODEM_RI_S) +#define UART_MODEM_DSR_S 5 +#define UART_MODEM_DSR_M (1 << UART_MODEM_DSR_S) +#define UART_MODEM_DCDIF_S 3 +#define UART_MODEM_DCDIF_M (1 << UART_MODEM_DCDIF_S) +#define UART_MODEM_RIIF_S 2 +#define UART_MODEM_RIIF_M (1 << UART_MODEM_RIIF_S) +#define UART_MODEM_DSRIF_S 1 +#define UART_MODEM_DSRIF_M (1 << UART_MODEM_DSRIF_S) + + +#ifndef _ASSEMBLER_ + #include + + + typedef struct + { + volatile uint32_t CONTROL1; + volatile uint32_t CONTROL2; + volatile uint32_t CONTROL3; + volatile uint32_t DIVIDER; + volatile uint32_t _reserved0; + volatile uint32_t _reserved1; + volatile uint32_t _reserved2; + volatile uint32_t FLAGS; + volatile uint32_t _reserved3; + volatile uint32_t RXDATA; + volatile uint32_t TXDATA; + volatile uint32_t MODEM; + + } UART_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif // UART_H_INCLUDED diff --git a/cores/arduino/mik32/shared/periphery/wakeup.h b/cores/arduino/mik32/shared/periphery/wakeup.h new file mode 100644 index 0000000..6b67c77 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/wakeup.h @@ -0,0 +1,110 @@ +#ifndef WU_H_INCLUDED +#define WU_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define WU_SYS_Mask_OFFSET 0x00 +#define WU_SYS_Level_OFFSET 0x04 +#define WU_SYS_PowerOff_OFFSET 0x08 +#define WU_PowerSwitch_On_Bat_OFFSET 0x0C +#define WU_Clocks_OFFSET 0x10 +#define WU_RTC_Control_OFFSET 0x14 +#define WU_BOOT 0x28 + + +// SYS_MASK +#define WU_MASK_WAKEUP_RTC_S 0 +#define WU_MASK_WAKEUP_RTC_M (1 << WU_MASK_WAKEUP_RTC_S) +#define WU_MASK_WAKEUP_EXT_S 1 +#define WU_MASK_WAKEUP_EXT_M (1 << WU_MASK_WAKEUP_EXT_S) +#define WU_MASK_SYS_RESET_LDO_S 2 +#define WU_MASK_SYS_RESET_LDO_M (1 << WU_MASK_SYS_RESET_LDO_S) +#define WU_MASK_SYS_RESET_VOLTMON_S 3 +#define WU_MASK_SYS_RESET_VOLTMON_M (1 << WU_MASK_SYS_RESET_VOLTMON_S) +#define WU_MASK_SYS_RESET_BOR_S 4 +#define WU_MASK_SYS_RESET_BOR_M (1 << WU_MASK_SYS_RESET_BOR_S) +#define WU_MASK_BU_RESET_BOR_S 5 +#define WU_MASK_BU_RESET_BOR_M (1 << WU_MASK_BU_RESET_BOR_S) + +// SYS_LEVEL +#define WU_SYS_LEVEL_RTC_ALARM_S 0 +#define WU_SYS_LEVEL_RTC_ALARM_M (0x1 << WU_SYS_LEVEL_RTC_ALARM_S) +#define WU_SYS_LEVEL_EXT_LINE_S 1 +#define WU_SYS_LEVEL_EXT_LINE_M (0x1 << WU_SYS_LEVEL_EXT_LINE_S) + +// SYS_POWEROFF +#define WU_SYS_POWEROFF_S 0 +#define WU_SYS_POWEROFF_M (1 << WU_SYS_POWEROFF_S) + +// POWER_SWITCH +#define WU_POWER_SWITCH_EN_S 0 +#define WU_POWER_SWITCH_EN_M (1 << WU_POWER_SWITCH_EN_S) +#define WU_POWER_SWITCH_CONTROL_S 1 +#define WU_POWER_SWITCH_CONTROL_M (1 << WU_POWER_SWITCH_CONTROL_S) +#define WU_POWER_SWITCH_CONTROL_VCC_M (0 << WU_POWER_SWITCH_CONTROL_S) +#define WU_POWER_SWITCH_CONTROL_VCC_BU_M (1 << WU_POWER_SWITCH_CONTROL_S) +#define WU_POWER_SWITCH_BATT_GOOD_S 2 +#define WU_POWER_SWITCH_BATT_GOOD_M (1 << WU_POWER_SWITCH_BATT_GOOD_S) + +//CLOCKS_BU +#define WU_CLOCKS_BU_OSC32K_EN_S 0 +#define WU_CLOCKS_BU_OSC32K_EN_M (1 << WU_CLOCKS_BU_OSC32K_EN_S) +#define WU_CLOCKS_BU_LSI32K_EN_S 1 +#define WU_CLOCKS_BU_LSI32K_EN_M (1 << WU_CLOCKS_BU_LSI32K_EN_S) +#define WU_CLOCKS_BU_ADJ_LSI32K_S 2 +#define WU_CLOCKS_BU_ADJ_LSI32K_M (0xFF << WU_CLOCKS_BU_ADJ_LSI32K_S) +#define WU_CLOCKS_BU_ADJ_LSI32K(v) (((v) << WU_CLOCKS_BU_ADJ_LSI32K_S) & WU_CLOCKS_BU_ADJ_LSI32K_M) +#define WU_CLOCKS_BU_RTC_CLK_MUX_S 10 +#define WU_CLOCKS_BU_RTC_CLK_MUX_M (0x3 << WU_CLOCKS_BU_RTC_CLK_MUX_S) +#define WU_CLOCKS_BU_RTC_CLK_MUX_LSI32K_M (0x1 << WU_CLOCKS_BU_RTC_CLK_MUX_S) +#define WU_CLOCKS_BU_RTC_CLK_MUX_OSC32K_M (0x2 << WU_CLOCKS_BU_RTC_CLK_MUX_S) +#define WU_CLOCKS_BU_OSC32K_SM_S 14 +#define WU_CLOCKS_BU_OSC32K_SM_M (1 << WU_CLOCKS_BU_OSC32K_SM_S) + +// CLOCKS_SYS +#define WU_CLOCKS_SYS_OSC32M_EN_S 0 +#define WU_CLOCKS_SYS_OSC32M_EN_M (1 << WU_CLOCKS_SYS_OSC32M_EN_S) +#define WU_CLOCKS_SYS_HSI32M_EN_S 1 +#define WU_CLOCKS_SYS_HSI32M_EN_M (1 << WU_CLOCKS_SYS_HSI32M_EN_S) +#define WU_CLOCKS_SYS_ADJ_HSI32M_S 2 +#define WU_CLOCKS_SYS_ADJ_HSI32M_M (0xFF << WU_CLOCKS_SYS_ADJ_HSI32M_S) +#define WU_CLOCKS_SYS_ADJ_HSI32M(v) (((v) << WU_CLOCKS_SYS_ADJ_HSI32M_S) & WU_CLOCKS_SYS_ADJ_HSI32M_M) +#define WU_CLOCKS_SYS_FORCE_32K_CLK_S 10 +#define WU_CLOCKS_SYS_FORCE_32K_CLK_M (0b11 << WU_CLOCKS_SYS_FORCE_32K_CLK_S) +#define WU_CLOCKS_SYS_FORCE_32K_CLK_LSI32K_M (0b01 << WU_CLOCKS_SYS_FORCE_32K_CLK_S) +#define WU_CLOCKS_SYS_FORCE_32K_CLK_OSC32K_M (0b10 << WU_CLOCKS_SYS_FORCE_32K_CLK_S) + +// RTC_CONRTOL +#define WU_RTC_CONTROL_RESET_S 0 +#define WU_RTC_CONTROL_RESET_SET_M (0 << WU_RTC_CONTROL_RESET_S) +#define WU_RTC_CONTROL_RESET_CLEAR_M (1 << WU_RTC_CONTROL_RESET_S) + +// STOP +#define WU_STOP_S 0 +#define WU_STOP_M (1 << WU_STOP_S) + + +#ifndef _ASSEMBLER_ + #include + typedef struct + { + + volatile uint32_t SYS_MASK; + volatile uint32_t SYS_LEVEL; + volatile uint32_t SYS_POWEROFF; + volatile uint32_t POWER_SWITCH; + volatile uint32_t CLOCKS_BU; + volatile uint32_t CLOCKS_SYS; + volatile uint32_t RTC_CONRTOL; + volatile uint32_t STOP; + } WU_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/cores/arduino/mik32/shared/periphery/wdt.h b/cores/arduino/mik32/shared/periphery/wdt.h new file mode 100644 index 0000000..316dd9f --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/wdt.h @@ -0,0 +1,72 @@ +#ifndef WDT_H_INCLUDED +#define WDT_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define WDT_KEY 0x9C +#define WDT_CON 0x84 +#define WDT_STA 0x9C + + +#define WDT_KEY_UNLOCK 0x1E +#define WDT_KEY_START 0x71 +#define WDT_KEY_STOP 0xE8 + +#define WDT_INTERRUPT_THRESHOLD 0x100 + +//CON +#define WDT_CON_PRELOAD_S 0 +#define WDT_CON_PRELOAD_M (0xFFF << WDT_CON_PRELOAD_S) +#define WDT_CON_PRELOAD(v) (((v) << WDT_CON_PRELOAD_S) & WDT_CON_PRELOAD_M) +// +#define WDT_CON_PRESCALE_S 12 +#define WDT_CON_PRESCALE_M (0x7 << WDT_CON_PRESCALE_S) +#define WDT_CON_PRESCALE_1_M (0x0 << WDT_CON_PRESCALE_S) +#define WDT_CON_PRESCALE_2_M (0x1 << WDT_CON_PRESCALE_S) +#define WDT_CON_PRESCALE_4_M (0x2 << WDT_CON_PRESCALE_S) +#define WDT_CON_PRESCALE_16_M (0x3 << WDT_CON_PRESCALE_S) +#define WDT_CON_PRESCALE_64_M (0x4 << WDT_CON_PRESCALE_S) +#define WDT_CON_PRESCALE_256_M (0x5 << WDT_CON_PRESCALE_S) +#define WDT_CON_PRESCALE_1024_M (0x6 << WDT_CON_PRESCALE_S) +#define WDT_CON_PRESCALE_4096_M (0x7 << WDT_CON_PRESCALE_S) +//STA +#define WDT_STA_ENABLED_S 0 +#define WDT_STA_ENABLED_M (1 << WDT_STA_ENABLED_S) +#define WDT_STA_LOADING_S 1 +#define WDT_STA_LOADING_M (1 << WDT_STA_LOADING_S) +#define WDT_STA_RST_FLAG_S 8 +#define WDT_STA_RST_FLAG_M (1 << WDT_STA_RST_FLAG_S) + + +#ifndef _ASSEMBLER_ + #include + typedef struct + { + union + { + struct + { + volatile uint8_t _space_Key[WDT_KEY]; + volatile uint8_t KEY; + }; + struct + { + volatile uint8_t _space_Con[WDT_CON]; + volatile uint32_t CON; + }; + struct + { + volatile uint8_t _space_Sta[WDT_STA]; + volatile uint32_t STA; + }; + }; + } WDT_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif // WDT_H_INCLUDED diff --git a/cores/arduino/mik32/shared/periphery/wdt_bus.h b/cores/arduino/mik32/shared/periphery/wdt_bus.h new file mode 100644 index 0000000..1e38908 --- /dev/null +++ b/cores/arduino/mik32/shared/periphery/wdt_bus.h @@ -0,0 +1,30 @@ +#ifndef WDT_BUS_H_INCLUDED +#define WDT_BUS_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define WDT_BUS_EEPROM_S 2 +#define WDT_BUS_SPIFI_S 1 +#define WDT_BUS_DOM3_S 0 + + + +#ifndef _ASSEMBLER_ + #include + + typedef struct + { + volatile uint32_t TIMEOUT; + volatile uint32_t INT_CLEAR; + volatile uint32_t ENABLE; + } WDT_BUS_TypeDef; +#endif + +#ifdef __cplusplus +} +#endif + +#endif // OTP_H_INCLUDED + diff --git a/cores/arduino/mik32/shared/runtime/crt0.S b/cores/arduino/mik32/shared/runtime/crt0.S new file mode 100644 index 0000000..e058b76 --- /dev/null +++ b/cores/arduino/mik32/shared/runtime/crt0.S @@ -0,0 +1,136 @@ + +#define EXCEPTION_STACK_SPACE 32*4 +#define EXCEPTION_SAVED_REGISTERS 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + +.globl _start, main +.weak SmallSystemInit, SystemInit + +.globl trap_entry +.globl trap_handler +.globl raw_trap_handler +.weak trap_handler, raw_trap_handler + +.altmacro +.macro memcpy src_beg, src_end, dst, tmp_reg + LOCAL memcpy_1, memcpy_2 + j memcpy_2 +memcpy_1: + lw \tmp_reg, (\src_beg) + sw \tmp_reg, (\dst) + add \src_beg, \src_beg, 4 + add \dst, \dst, 4 +memcpy_2: + bltu \src_beg, \src_end, memcpy_1 +.endm + +.macro memset dst_beg, dst_end, val_reg + LOCAL memset_1, memset_2 + j memset_2 +memset_1: + sw \val_reg, (\dst_beg) + add \dst_beg, \dst_beg, 4 +memset_2: + bltu \dst_beg, \dst_end, memset_1 +.endm + + +# la uses PC relative addressing (auipc instruction) +# Explicit absolut addressing with lui instruction is used +# to allow startup code to be executed from any PC address +# (la instruction equivalents are left in comments) + +.macro la_abs reg, address + .option push + .option norelax + lui \reg, %hi(\address) + addi \reg, \reg, %lo(\address) + .option pop +.endm + + +.macro jalr_abs return_reg, address + .option push + .option norelax + lui \return_reg, %hi(\address) + jalr \return_reg, %lo(\address)(\return_reg) + .option pop +.endm + + + +.text + +_start: + + # Init stack and global pointer + # + la_abs sp, __C_STACK_TOP__ + la_abs gp, _gp + + # Init data + # + la_abs a1, __DATA_IMAGE_START__ + la_abs a2, __DATA_IMAGE_END__ + la_abs a3, __DATA_START__ + memcpy a1, a2, a3, t0 + + # Clear bss + # + la_abs a1, __BSS_START__ + la_abs a2, __BSS_END__ + memset a1, a2, zero + + #ifdef MIK32V0 + # Enable pad_config clocking + # + li t0, (1 << 3) + li t1, 0x50014 + sw t0, (t1) + #endif + + jalr_abs ra, SmallSystemInit + jalr_abs ra, SystemInit + + jalr_abs ra, __libc_init_array + jalr_abs ra, main + jalr_abs ra, __libc_fini_array + +1: wfi + j 1b + + +// Actions before main: none by default +// (weak symbol here - may be redefined) +SmallSystemInit: +SystemInit: + ret + +.section .trap_text, "ax" +// .org should be consistent with +// default mtvec value (set in scr1_arch_description.svh) +//.org 0xC0 +trap_entry: + j raw_trap_handler + +raw_trap_handler: + // Save registers + addi sp, sp, -(EXCEPTION_STACK_SPACE) + .irp index, EXCEPTION_SAVED_REGISTERS + sw x\index, 4*index(sp) + .endr + + // Call handler + la ra, trap_handler + jalr ra + + // restore registers + .irp index, EXCEPTION_SAVED_REGISTERS + lw x\index, 4*index(sp) + .endr + addi sp, sp, EXCEPTION_STACK_SPACE + mret + +// Default handler: infinit loop +// (weak symbol here - may be redefined) +trap_handler: +1: j 1b diff --git a/cores/arduino/mik32/shared/syscalls.c b/cores/arduino/mik32/shared/syscalls.c new file mode 100644 index 0000000..7d8f28e --- /dev/null +++ b/cores/arduino/mik32/shared/syscalls.c @@ -0,0 +1,288 @@ +/* An extremely minimalist syscalls.c for newlib + * Based on riscv newlib libgloss/riscv/sys_*.c + * + * Copyright 2019 Clifford Wolf + * Copyright 2019 ETH Zürich and University of Bologna + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/**********************************************************************//** + * @file syscalls.c + * @brief Newlib system calls + * + * @warning UART0 (if available) is used to read/write console data (STDIN, STDOUT, STDERR, ...). + * + * @note Original source file: https://github.com/openhwgroup/cv32e40p/blob/master/example_tb/core/custom/syscalls.c + * @note Original license: SOLDERPAD HARDWARE LICENSE version 0.51 + * @note More information was derived from: https://interrupt.memfault.com/blog/boostrapping-libc-with-newlib#implementing-newlib + **************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#undef errno +extern int errno; + +// defined in sw/common/crt0.S +extern const volatile unsigned int __crt0_main_exit; + +/* It turns out that older newlib versions use different symbol names which goes + * against newlib recommendations. Anyway this is fixed in later version. + */ +#if __NEWLIB__ <= 2 && __NEWLIB_MINOR__ <= 5 +# define _sbrk sbrk +# define _write write +# define _close close +# define _lseek lseek +# define _read read +# define _fstat fstat +# define _isatty isatty +#endif + +// void unimplemented_syscall() +// { +// if (neorv32_uart0_available()) { +// neorv32_uart0_puts(" Unimplemented system call called!\n"); +// } +// } + +int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +{ + errno = ENOSYS; + return -1; +} + +int _access(const char *file, int mode) +{ + errno = ENOSYS; + return -1; +} + +int _chdir(const char *path) +{ + errno = ENOSYS; + return -1; +} + +int _chmod(const char *path, mode_t mode) +{ + errno = ENOSYS; + return -1; +} + +int _chown(const char *path, uid_t owner, gid_t group) +{ + errno = ENOSYS; + return -1; +} + +int _close(int file) +{ + return -1; +} + +int _execve(const char *name, char *const argv[], char *const env[]) +{ + errno = ENOMEM; + return -1; +} + +void _exit(int exit_status) +{ + // jump to crt0's shutdown code + //asm volatile ("la t0, __crt0_main_exit \n" + // "jr t0 \n"); + + while(1); // will never be reached +} + +int _faccessat(int dirfd, const char *file, int mode, int flags) +{ + errno = ENOSYS; + return -1; +} + +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +int _fstat(int file, struct stat *st) +{ + st->st_mode = S_IFCHR; // all files are "character special files" + return 0; +} + +int _fstatat(int dirfd, const char *file, struct stat *st, int flags) +{ + errno = ENOSYS; + return -1; +} + +int _ftime(struct timeb *tp) +{ + errno = ENOSYS; + return -1; +} + +char *_getcwd(char *buf, size_t size) +{ + errno = -ENOSYS; + return NULL; +} + +int _getpid() +{ + return 1; +} + +int _gettimeofday(struct timeval *tp, void *tzp) +{ + errno = -ENOSYS; + return -1; +} + +int _isatty(int file) +{ + return (file == STDOUT_FILENO); +} + +int _kill(int pid, int sig) +{ + errno = EINVAL; + return -1; +} + +int _link(const char *old_name, const char *new_name) +{ + errno = EMLINK; + return -1; +} + +off_t _lseek(int file, off_t ptr, int dir) +{ + return 0; +} + +int _lstat(const char *file, struct stat *st) +{ + errno = ENOSYS; + return -1; +} + +int _open(const char *name, int flags, int mode) +{ + return -1; +} + +int _openat(int dirfd, const char *name, int flags, int mode) +{ + errno = ENOSYS; + return -1; +} + +ssize_t _read(int file, void *ptr, size_t len) +{ + int read_cnt = 0; + + // read everything (STDIN, ...) from NEORV32.UART0 (if available) +// if (neorv32_uart0_available()) { +// char *char_ptr; +// char_ptr = (char *)ptr; +// while (len > 0) { +// *char_ptr++ = (char)neorv32_uart0_getc(); +// read_cnt++; +// len--; +// } +// } + + return read_cnt; +} + +int _stat(const char *file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; + // errno = ENOSYS; + // return -1; +} + +long _sysconf(int name) +{ + + return -1; +} + +clock_t _times(struct tms *buf) +{ + return -1; +} + +int _unlink(const char *name) +{ + errno = ENOENT; + return -1; +} + +int _utime(const char *path, const struct utimbuf *times) +{ + errno = ENOSYS; + return -1; +} + +int _wait(int *status) +{ + errno = ECHILD; + return -1; +} + + +__attribute__((weak)) +ssize_t _write(int file, const void *ptr, size_t len) +{ + + return len; +} + +extern char __heap_start[]; +extern char __heap_end[]; +static char *brk = &__heap_start[0]; + +int _brk(void *addr) +{ + brk = addr; + return 0; +} +uint32_t sbrk_counter = 0; +void *_sbrk(ptrdiff_t incr) +{ + char *old_brk = brk; + + if (&__heap_start[0] == &__heap_end[0]) { + return NULL; + } + sbrk_counter++; + if ((brk + incr) < &__heap_end[0]) { + brk += incr; + } else { + brk = &__heap_end[0]; + } + return old_brk; +} diff --git a/cores/arduino/trap_handler.c b/cores/arduino/trap_handler.c new file mode 100644 index 0000000..aefc54f --- /dev/null +++ b/cores/arduino/trap_handler.c @@ -0,0 +1,33 @@ +#include "mik32_hal_irq.h" + +// isr functions +extern void serial_handler_wrapper(void); +extern void gpio_interrupts_handler(void); +extern void tone_interrupt_handler(void); +void __attribute__((weak)) wire_handler_wrapper(void) +{ + // dummy function for case when wire library is not in use +} + +// ---------------------------------------------- // +void trap_handler(void) +{ + // tone timer interrupt + if (EPIC_CHECK_TIMER16_1()) + tone_interrupt_handler(); + + // uart interrupt + if (EPIC_CHECK_UART_0()) + serial_handler_wrapper(); + + // gpio interrupt + if (EPIC_CHECK_GPIO_IRQ()) + gpio_interrupts_handler(); + + // i2c interrupt + if (EPIC_CHECK_I2C_1()) + wire_handler_wrapper(); + + // reset all interrupts + HAL_EPIC_Clear(0xFFFFFFFF); +} diff --git a/cores/arduino/wiring.h b/cores/arduino/wiring.h new file mode 100644 index 0000000..9028335 --- /dev/null +++ b/cores/arduino/wiring.h @@ -0,0 +1,58 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + Copyright (c) 2013 by Paul Stoffregen (delayMicroseconds) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_H_ +#define _WIRING_H_ + +#include +#include +#include +#include +#include + +#include "avr/dtostrf.h" +#include "binary.h" +#include "itoa.h" + +#include "wiring_analog.h" +#include "wiring_constants.h" +#include "wiring_digital.h" +#include "wiring_shift.h" +#include "wiring_time.h" +#include "WInterrupts.h" + +#ifdef __cplusplus + #include "board.h" // for preinit + #include "wiring_pulse.h" + #include "Tone.h" + #include "WCharacter.h" + #include "WMath.h" + #include "HardwareSerial.h" + #include "WString.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" { +#endif +void ErrorMsgHandler(const char * msg); +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_H_ */ diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c new file mode 100644 index 0000000..75449a2 --- /dev/null +++ b/cores/arduino/wiring_analog.c @@ -0,0 +1,188 @@ +#include "Arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_adc.h" +#include "mik32_hal_gpio.h" +#include "mik32_hal_timer32.h" + +extern void ErrorMsgHandler(const char * msg); + +// -------------------------- Analog read -------------------------- // +// structure for ADC channel initialization. Only the channel number +// changes, everything else is the same +static ADC_HandleTypeDef hadc = +{ + .Instance = ANALOG_REG, + .Init.EXTClb = ADC_EXTCLB_ADCREF, + .Init.EXTRef = ADC_EXTREF_OFF, + .Init.Sel = 0 +}; + +// initialize the channel, run a single measurement, wait for the result +uint32_t analogRead(uint32_t PinNumber) +{ + uint32_t value = 0; + uint32_t adcChannel = analogInputToChannelNumber(PinNumber); + if (adcChannel != NC) + { + // if we use pin A5, we need to set SELA45 (1.15) to 1 to switch the output from A4 to A5 + if (PinNumber == A5) + { + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_15, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_15, GPIO_PIN_HIGH); + } + else if(PinNumber == A4) + { + // return the switch to A4 in case A5 was previously read + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_15, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_15, GPIO_PIN_LOW); + } + // init channel + hadc.Init.Sel = adcChannel; + HAL_ADC_Init(&hadc); + + // start the conversion twice in case another channel was polled before + HAL_ADC_SINGLE_AND_SET_CH(hadc.Instance, adcChannel); + value = HAL_ADC_WaitAndGetValue(&hadc); + HAL_ADC_Single(&hadc); + value = HAL_ADC_WaitAndGetValue(&hadc); + } + else + ErrorMsgHandler("analogRead(): invalid analog pin number"); + + return value; +} + + + +// -------------------------- Analog write -------------------------- // +#define PWM_RESOLUTION_DEFAULT 8 +#define WRITE_VAL_MAX_DEFAULT ((1<TimerInstance == TIMER32_0) + return HAL_ERROR; + + // gpio init removed from standard function + + timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]); + HAL_Timer32_Channel_PWM_Invert_Set(timerChannel, timerChannel->PWM_Invert); + HAL_Timer32_Channel_Mode_Set(timerChannel, timerChannel->Mode); + HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, timerChannel->CaptureEdge); + HAL_Timer32_Channel_OCR_Set(timerChannel, timerChannel->OCR); + HAL_Timer32_Channel_ICR_Clear(timerChannel); + HAL_Timer32_Channel_Noise_Set(timerChannel, timerChannel->Noise); + + return HAL_OK; +} + +/* +It is recommended to enable the timer in the following order: +- Set the required operating mode. In the INT_MASK register 0; +- Write 0xFFFFFFFF to the INT_CLEAR register; +- Set TIM_EN to 1; +- If you need interrupts from the timer, set the required interrupt mask in the INT_MASK register. +*/ +void analogWrite(uint32_t PinNumber, uint32_t writeVal) +{ + if (digitalPinHasPWM(PinNumber)) + { + if (writeVal > WriteValMax) writeVal = WriteValMax; + + // initialization of the required timer + htimer32.Instance = pwmPinToTimer(PinNumber); + htimer32.Top = pwmTopVal; + htimer32.State = TIMER32_STATE_DISABLE; + htimer32.Clock.Source = TIMER32_SOURCE_PRESCALER; + htimer32.Clock.Prescaler = 0; // Prescaler = 1 + htimer32.InterruptMask = 0; + htimer32.CountMode = TIMER32_COUNTMODE_FORWARD; + HAL_Timer32_Init(&htimer32); + + // gpio init as timer channel pin + HAL_GPIO_PinConfig(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber), + HAL_GPIO_MODE_TIMER_SERIAL, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + + htimer32_channel.TimerInstance = htimer32.Instance; + htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber); + htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM; + htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM; + htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING; + // cast to uint64_t to avoid overflow when multiplying + htimer32_channel.OCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax); + htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF; + Timer32_Channel_Init(&htimer32_channel); + // start timer with initialized channel + HAL_Timer32_Channel_Enable(&htimer32_channel); + HAL_Timer32_Value_Clear(&htimer32); + HAL_Timer32_Start(&htimer32); + pwmIsInited = true; // if at least one channel is working, say that the module is initialized + } + else if(PinNumber == 10) // pin d10 has pwm, but you cannot use it while spi is running + ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running"); + else + ErrorMsgHandler("analogWrite(): invalid pwm pin number"); +} + +// Set the resolution of analogWrite parameters +void analogWriteResolution(uint8_t resolution) +{ + if ((resolution > 0) && (resolution < 32)) + WriteValMax = (1 << resolution) - 1; + else if (resolution == 32) + WriteValMax = UINT32_MAX; + else + ErrorMsgHandler("analogWriteResolution(): invalid resolution"); +} + +// Set the frequency of analogWrite +void analogWriteFrequency(uint32_t freq) +{ + if ((freq >= 1) && (freq <= PWM_FREQUENCY_MAX)) + pwmTopVal = F_CPU/freq; + else + ErrorMsgHandler("analogWriteFrequency(): invalid frequency"); +} + +/* +It is recommended to turn off the timer in the following order: +- Write 0 to the INT_MASK register; +- Write 0 to the TIM_PRESCALE register; +- Write 0 to the INT_CLEAR register; +- Set TIM_EN to 0. +*/ +void analogWriteStop(uint32_t PinNumber) +{ + if (pwmIsInited) + { + // load the timer address and channel number corresponding to the specified pin + htimer32.Instance = pwmPinToTimer(PinNumber); + htimer32_channel.TimerInstance = htimer32.Instance; + htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber); + // in the initChannel function they do it inside, but in deinit they don't. We do it outside + htimer32_channel.Instance = (TIMER32_CHANNEL_TypeDef *)&(htimer32_channel.TimerInstance->CHANNELS[htimer32_channel.ChannelIndex]); + // и все чистим/отключаем + HAL_Timer32_InterruptMask_Clear(&htimer32, 0xFFFFFFFF); + HAL_Timer32_Prescaler_Set(&htimer32, 0); + HAL_Timer32_InterruptFlags_ClearMask(&htimer32, 0xFFFFFFFF); + HAL_Timer32_Channel_DeInit(&htimer32_channel); + HAL_Timer32_Stop(&htimer32); + pwmIsInited = false; + } +} + +#ifdef __cplusplus +} +#endif diff --git a/cores/arduino/wiring_analog.h b/cores/arduino/wiring_analog.h new file mode 100644 index 0000000..2e90d8d --- /dev/null +++ b/cores/arduino/wiring_analog.h @@ -0,0 +1,54 @@ +#ifndef _WIRING_ANALOG_ +#define _WIRING_ANALOG_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" + +/* + * \brief Reads the value from the specified analog pin. + * + * \param PinNumber + * + * \return Read value from selected pin, if no error. + */ +uint32_t analogRead(uint32_t PinNumber); + +/* + * \brief Writes an analog value (PWM wave) to a pin. + * + * \param PinNumber + * \param default writeVal is 0...255 + */ +void analogWrite(uint32_t PinNumber, uint32_t writeVal); + +/* + * \brief Set the resolution of analogWrite parameters. Default is 8 bits (range from 0 to 255). + * + * \param resolution 1...32 + */ +void analogWriteResolution(uint8_t resolution); + +/* + * \brief Set the frequency of analogWrite. Applying after calling analogWrite(). + * Default is PWM_FREQUENCY (1000) in Hertz. + * + * \param freq 1...1000000 Hz + */ +void analogWriteFrequency(uint32_t freq); + +/* + * \brief Stops timer and deinit pwm channel on pin PinNumber + * + * \param PinNumber + */ +void analogWriteStop(uint32_t PinNumber); + + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_ANALOG_ */ diff --git a/cores/arduino/wiring_constants.h b/cores/arduino/wiring_constants.h new file mode 100644 index 0000000..36535a7 --- /dev/null +++ b/cores/arduino/wiring_constants.h @@ -0,0 +1,98 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_CONSTANTS_ +#define _WIRING_CONSTANTS_ + +#include +#include + +#define HIGH 0x1 +#define LOW 0x0 +#define INPUT 0x0 +#define OUTPUT 0x1 +#define INPUT_PULLUP 0x2 +#define NC 0xFFFFFFFF // Not connected + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 +#define EULER 2.718281828459045235360287471352 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +enum BitOrder +{ + LSBFIRST = 0, + MSBFIRST = 1 +}; + +// interrupts mode +#define CHANGE 0x2 +#define FALLING 0x3 +#define RISING 0x4 + +#define DEFAULT 1 +#define EXTERNAL 0 +#define NOT_AN_INTERRUPT -1 + +// Math +#ifdef __cplusplus + #include + using std::min; + using std::max; +#else // C + #include + #ifndef abs + #define abs(x) ((x)>0?(x):-(x)) + #endif // abs + + #ifndef min + #define min(a,b) ((a)<(b)?(a):(b)) + #endif // min + + #ifndef max + #define max(a,b) ((a)>(b)?(a):(b)) + #endif // max + +#endif // __cplusplus +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +// Bits and Bytes +#define bit(b) (1UL << (b)) +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet((value), (bit)) : bitClear((value), (bit) )) + + +// typedefs for compatibility +typedef unsigned int word; +typedef bool boolean __attribute__((deprecated)); +typedef uint8_t byte ; + +#endif /* _WIRING_CONSTANTS_ */ diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c new file mode 100644 index 0000000..9f82c27 --- /dev/null +++ b/cores/arduino/wiring_digital.c @@ -0,0 +1,155 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Arduino.h" +#include "pins_arduino.h" +#include "mik32_hal_gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void ErrorMsgHandler(const char * msg); + +// initialization +void pinMode(uint32_t PinNumber, uint32_t PinMode) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + // if pin number is greater than pin list size - return + if ((PinNumber>=pinCommonQty())) + { + ErrorMsgHandler("pinMode(): pin number exceeds the total number of pins"); + return; + } + + if (digitalPinHasPWM(PinNumber)) + // if the pin can use PWM, disable PWM + analogWriteStop(PinNumber); + + // adjusting pins + if (PinNumber == BTN_BUILTIN) + { + // always set the button to input, otherwise the controller may burn out when pressed + GPIO_InitStruct.Pin = GPIO_PIN_6; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_2, &GPIO_InitStruct); + } + else // other pins + { + // determine the port and the pin number in the port + GPIO_TypeDef *GPIO_addr = digitalPinToPort(PinNumber); + GPIO_InitStruct.Pin = digitalPinToBitMask(PinNumber); + + // set up direction and pull up/down + switch (PinMode) + { + case INPUT: + GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + break; + case INPUT_PULLUP: + GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP; + break; + case OUTPUT: + GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_OUTPUT; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + break; + } + + // init pin + HAL_GPIO_Init(GPIO_addr, &GPIO_InitStruct); + + // if we use pin A5, we need to set SELA45 (1.15) to 1 to switch the output from A4 to A5 + if (PinNumber == A5) + { + GPIO_InitStruct.Pin = GPIO_PIN_15; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_OUTPUT; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_15, GPIO_PIN_HIGH); + } + else if(PinNumber == A4) + { + GPIO_InitStruct.Pin = GPIO_PIN_15; + GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_OUTPUT; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct); + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_15, GPIO_PIN_LOW); + } + } +} + +// write pin +void digitalWrite(uint32_t PinNumber, uint32_t Val) +{ + if ((PinNumber>=pinCommonQty())) + { + ErrorMsgHandler("digitalWrite(): pin number exceeds the total number of pins"); + return; + } + + if (digitalPinHasPWM(PinNumber)) + // if the pin can use PWM, disable PWM + analogWriteStop(PinNumber); + + // just in case let's move on to the hal library state terms + GPIO_PinState pinState = (Val == HIGH) ? GPIO_PIN_HIGH : GPIO_PIN_LOW; + + if (PinNumber != BTN_BUILTIN) // don't write anything to the button + HAL_GPIO_WritePin(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber), pinState); +} + +// read pin +int digitalRead(uint32_t PinNumber) +{ + if ((PinNumber>=pinCommonQty())) + { + ErrorMsgHandler("digitalRead(): pin number exceeds the total number of pins"); + return -1; + } + if (digitalPinHasPWM(PinNumber)) + // if the pin can use PWM, disable PWM + analogWriteStop(PinNumber); + + GPIO_PinState pinState = HAL_GPIO_ReadPin(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber)); + int state = (pinState == GPIO_PIN_LOW) ? LOW : HIGH; + return state; +} + +// toggle pin +void digitalToggle(uint32_t PinNumber) +{ + if ((PinNumber>=pinCommonQty())) + { + ErrorMsgHandler("digitalToggle(): pin number exceeds the total number of pins"); + return; + } + if (digitalPinHasPWM(PinNumber)) + // if the pin can use PWM, disable PWM + analogWriteStop(PinNumber); + + if (PinNumber != BTN_BUILTIN) // don't write anything to the button + HAL_GPIO_TogglePin(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber)); +} + +#ifdef __cplusplus +} +#endif diff --git a/cores/arduino/wiring_digital.h b/cores/arduino/wiring_digital.h new file mode 100644 index 0000000..ed5cb82 --- /dev/null +++ b/cores/arduino/wiring_digital.h @@ -0,0 +1,65 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_DIGITAL_ +#define _WIRING_DIGITAL_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Configures the specified pin to behave either as an input or an output. + * + * \param dwPin The number of the pin whose mode you wish to set + * \param dwMode Either INPUT, INPUT_PULLUP or OUTPUT + */ +void pinMode(uint32_t PinNumber, uint32_t PinMode); + +/** + * \brief Write a HIGH or a LOW value to a digital pin. + * + * If the pin has been configured as an OUTPUT with pinMode(), its voltage will be set to the + * corresponding value: 3.3V for HIGH, 0V (ground) for LOW. + * + * \param dwPin the pin number + * \param dwVal HIGH or LOW + */ +void digitalWrite(uint32_t PinNumber, uint32_t Val); + +/** + * \brief Reads the value from a specified digital pin, either HIGH or LOW. + * + * \param ulPin The number of the digital pin you want to read (int) + * + * \return HIGH or LOW + */ +int digitalRead(uint32_t PinNumber); + +/** + * \brief Toggle the value from a specified digital pin. + * + * \param ulPin The number of the digital pin you want to toggle (int) + */ +void digitalToggle(uint32_t PinNumber); + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_DIGITAL_ */ diff --git a/cores/arduino/wiring_pulse.cpp b/cores/arduino/wiring_pulse.cpp new file mode 100644 index 0000000..eefd0f9 --- /dev/null +++ b/cores/arduino/wiring_pulse.cpp @@ -0,0 +1,60 @@ +#include "Arduino.h" + +/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH + * or LOW, the type of pulse to measure. Works on pulses from 20-30 microseconds + * to 3 minutes in length, but must be called at least a few dozen microseconds + * before the start of the pulse. + */ +unsigned long pulseIn(int pin, int state, unsigned long timeout) +{ + // check the pin number + if ((pin>=pinCommonQty())) + { + ErrorMsgHandler("pulseIn(): pin number exceeds the total number of pins"); + return -1; + } + if (digitalPinHasPWM(pin)) + // pwm off + analogWriteStop(pin); + + // target state to hal terms + GPIO_PinState targetState = (state == LOW) ? GPIO_PIN_LOW : GPIO_PIN_HIGH; + // get port and pin number + GPIO_TypeDef* halPort = digitalPinToPort(pin); + HAL_PinsTypeDef halPin = digitalPinToBitMask(pin); + + // save initial state + GPIO_PinState iniState = HAL_GPIO_ReadPin(halPort, halPin); + + // wait for any previous pulse to end + uint32_t startMicros = micros(); + while (HAL_GPIO_ReadPin(halPort, halPin) == iniState) + { + if (micros() - startMicros > timeout) + return 0; + } + + // wait for the desired polarity pulse start + while (HAL_GPIO_ReadPin(halPort, halPin) != targetState) + { + if (micros() - startMicros > timeout) + return 0; + } + + // wait for the pulse to stop + uint32_t start = micros(); + while (HAL_GPIO_ReadPin(halPort, halPin) == targetState) + { + if (micros() - startMicros > timeout) + return 0; + } + return (micros() - start); +} + +/* + * For backward compatibility + */ +unsigned long pulseInLong(int pin, int state, unsigned long timeout) +{ + return pulseIn(pin, state, timeout); +} diff --git a/cores/arduino/wiring_pulse.h b/cores/arduino/wiring_pulse.h new file mode 100644 index 0000000..ea028be --- /dev/null +++ b/cores/arduino/wiring_pulse.h @@ -0,0 +1,34 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef _WIRING_PULSE_ +#define _WIRING_PULSE_ + +#include "stdint.h" +#define PULSE_TIMEOUT_DEFAULT 1000000L + +/* +* \brief +* Measures the length (in microseconds) of a pulse on the pin; state is HIGH +* or LOW, the type of pulse to measure. Works on pulses from 20-30 microseconds +* to 3 minutes in length, but must be called at least a few dozen microseconds +* before the start of the pulse. +*/ +unsigned long pulseIn(int pin, int state, unsigned long timeout = PULSE_TIMEOUT_DEFAULT); +unsigned long pulseInLong(int pin, int state, unsigned long timeout = PULSE_TIMEOUT_DEFAULT); + +#endif /* _WIRING_PULSE_ */ diff --git a/cores/arduino/wiring_shift.c b/cores/arduino/wiring_shift.c new file mode 100644 index 0000000..707ea8f --- /dev/null +++ b/cores/arduino/wiring_shift.c @@ -0,0 +1,57 @@ +/* + wiring_shift.c - shiftOut() function + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +#include "Arduino.h" + +uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) +{ + uint8_t value = 0; + + for (uint8_t i = 0; i < 8; ++i) + { + digitalWrite(clockPin, HIGH); + if (bitOrder == LSBFIRST) + value |= digitalRead(dataPin) << i; + else + value |= digitalRead(dataPin) << (7 - i); + digitalWrite(clockPin, LOW); + } + return value; +} + +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) +{ + for (uint8_t i = 0; i < 8; i++) + { + if (bitOrder == LSBFIRST) + { + digitalWrite(dataPin, val & 1); + val >>= 1; + } else + { + digitalWrite(dataPin, (val & 128) != 0); + val <<= 1; + } + digitalWrite(clockPin, HIGH); + digitalWrite(clockPin, LOW); + } +} diff --git a/cores/arduino/wiring_shift.h b/cores/arduino/wiring_shift.h new file mode 100644 index 0000000..825d047 --- /dev/null +++ b/cores/arduino/wiring_shift.h @@ -0,0 +1,37 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_SHIFT_ +#define _WIRING_SHIFT_ + +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); + +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); + + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_SHIFT_ */ diff --git a/cores/arduino/wiring_time.c b/cores/arduino/wiring_time.c new file mode 100644 index 0000000..19dde62 --- /dev/null +++ b/cores/arduino/wiring_time.c @@ -0,0 +1,93 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_scr1_timer.h" + +uint32_t start_del, current_del; + +// system timer initialization +SCR1_TIMER_HandleTypeDef hscr1_timer; + +#define TICKS_IN_SYSTIMER ((uint64_t)(hscr1_timer.Instance->MTIMEH)<<32 | hscr1_timer.Instance->MTIME) + +void SysTick_Init(void) +{ + hscr1_timer.Instance = SCR1_TIMER; + hscr1_timer.ClockSource = SCR1_TIMER_CLKSRC_INTERNAL; + hscr1_timer.Divider = 0; + HAL_SCR1_Timer_Init(&hscr1_timer); // Ticks are 32 MHz +} + +// number of microseconds since start of the program +uint32_t micros(void) +{ + // cast to uint32_t and assume that when HAL_SCR1_Timer_Get_Ticks() returns a number + // greater than 2^32/32, the variable will overflow itself + return (uint32_t)(TICKS_IN_SYSTIMER >> 5); +} + +// there may be a problem with the timer counter overflow, because by the time it +// overflows the number of milliseconds will not have time to reach the maximum, +// and when it overflows it will be reseted to 0 ahead of time - the delay will be +// incorrect. But 64 bits will take a very long time to fill, so we'll leave it like that +volatile uint32_t millis(void) +{ + return (uint32_t) (TICKS_IN_SYSTIMER / (uint64_t)(32000)); +} + +void delay(uint32_t ms) +{ + if (ms > 0) + { + start_del = millis(); + while (1) + { + current_del = millis(); + // Let's check if there was an overflow. + if (((current_del > start_del) ? (current_del - start_del) : (current_del + ~start_del + 1)) >= ms) + // exit if we got the required amount + break; + } + } +} + +void delayMicroseconds(uint16_t us) +{ + if (us > 0) + { + start_del = micros(); + while (1) + { + current_del = micros(); + // Let's check if there was an overflow. + if (((current_del > start_del) ? (current_del - start_del) : (current_del + ~start_del + 1)) >= us) + // exit if we got the required amount + break; + } + } +} + +#ifdef __cplusplus +} +#endif diff --git a/cores/arduino/wiring_time.h b/cores/arduino/wiring_time.h new file mode 100644 index 0000000..162fbc3 --- /dev/null +++ b/cores/arduino/wiring_time.h @@ -0,0 +1,73 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + Copyright (c) 2013 by Paul Stoffregen (delayMicroseconds) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_TIME_H_ +#define _WIRING_TIME_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initialize timer for creating delays + * + */ +void SysTick_Init(void); + + +/** + * \brief Returns the number of milliseconds since the Arduino board began running the current program. + * + * This number will overflow (go back to zero), after approximately 50 days. + * + * \return Number of milliseconds since the program started (uint32_t) + */ +uint32_t millis(void); + +/** + * \brief Returns the number of microseconds since the Arduino board began running the current program. + * + * This number will overflow (go back to zero), after approximately 70 minutes. + * + * \note There are 1,000 microseconds in a millisecond and 1,000,000 microseconds in a second. + */ +uint32_t micros(void); + +/** + * \brief Pauses the program for the amount of time (in milliseconds) specified as parameter. + * (There are 1000 milliseconds in a second.) + * + * \param ms the number of milliseconds to pause (uint32_t) + */ +void delay(uint32_t ms); + +/** + * \brief Pauses the program for the amount of time (in microseconds) specified as parameter. + * + * \param us the number of microseconds to pause (uint32_t) + */ + +void delayMicroseconds(uint16_t us); + + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_TIME_H_ */ diff --git a/libraries/SPI/examples/ADC_read_write_registers/ADC_read_write_registers.ino b/libraries/SPI/examples/ADC_read_write_registers/ADC_read_write_registers.ino new file mode 100644 index 0000000..00c931f --- /dev/null +++ b/libraries/SPI/examples/ADC_read_write_registers/ADC_read_write_registers.ino @@ -0,0 +1,79 @@ +/* + ADS1256 ADC is used for this test. Command for write + and read is taken from the datasheet. +*/ + +#include "SPI.h" + +#define CS_PIN 9 + +// address of register to read and write +const int reg_to_test = 0x03; +uint8_t readVal = 0; +uint8_t writeVal = 0; + +// read one register value +uint8_t ADC_read_register(uint8_t registerAddress) +{ + SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1)); + digitalWrite(CS_PIN, LOW); // CS must stay LOW during the entire sequence + SPI.transfer(0x10 | registerAddress); // 0x10 = 0001000 = RREG - OR together the two numbers (command + address) + SPI.transfer(0x00); // 2nd empty command byte to read one byte + delayMicroseconds(5); // see t6 in the datasheet + uint8_t readVal = SPI.transfer(0xFF); // read out the register value + digitalWrite(CS_PIN, HIGH); + SPI.endTransaction(); + return readVal; +} + +// write one register value +void ADC_write_register(uint8_t registerAddress, uint8_t registerValueToWrite) +{ + SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1)); + digitalWrite(CS_PIN, LOW); // CS must stay LOW during the entire sequence + delayMicroseconds(5); // see t6 in the datasheet + SPI.transfer(0x50 | registerAddress); // 0x50 = 01010000 = WREG + SPI.transfer(0x00); // 2nd empty command byte to write one byte + SPI.transfer(registerValueToWrite); // pass the value to the register + digitalWrite(CS_PIN, HIGH); + SPI.endTransaction(); +} + +// ----------------------------------------- // +void setup() +{ + Serial.begin(115200); + Serial.println("Start spi test"); + + // init chip select pin + pinMode(CS_PIN, OUTPUT); + digitalWrite(CS_PIN, HIGH); + + // init spi + SPI.begin(); + delay(100); + + // read initial register value + Serial.print("Initial register value: 0x"); + Serial.println(ADC_read_register(reg_to_test), HEX); +} + +void loop() +{ + // write new reg value + ADC_write_register(reg_to_test, writeVal); + Serial.print("Write val: 0x"); + Serial.println(writeVal, HEX); + + // read updated reg value + readVal = ADC_read_register(reg_to_test); + Serial.print("Read val: 0x"); + Serial.println(readVal, HEX); + + // increase write value + writeVal++; + Serial.println("-------------"); + + // wait + delay(2000); +} diff --git a/libraries/SPI/keywords.txt b/libraries/SPI/keywords.txt new file mode 100644 index 0000000..1906b7f --- /dev/null +++ b/libraries/SPI/keywords.txt @@ -0,0 +1,37 @@ +####################################### +# Syntax Coloring Map For SPI +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +SPI KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +beginTransaction KEYWORD2 +end KEYWORD2 +endTransaction KEYWORD2 +transfer KEYWORD2 +setBitOrder KEYWORD2 +setDataMode KEYWORD2 +setClockDivider KEYWORD2 + + +####################################### +# Constants (LITERAL1) +####################################### +SPI_CLOCK_DIV4 LITERAL1 +SPI_CLOCK_DIV8 LITERAL1 +SPI_CLOCK_DIV16 LITERAL1 +SPI_CLOCK_DIV32 LITERAL1 +SPI_CLOCK_DIV64 LITERAL1 +SPI_CLOCK_DIV128 LITERAL1 +SPI_CLOCK_DIV256 LITERAL1 +SPI_MODE0 LITERAL1 +SPI_MODE1 LITERAL1 +SPI_MODE2 LITERAL1 +SPI_MODE3 LITERAL1 \ No newline at end of file diff --git a/libraries/SPI/library.properties b/libraries/SPI/library.properties new file mode 100644 index 0000000..97f13eb --- /dev/null +++ b/libraries/SPI/library.properties @@ -0,0 +1,10 @@ +name=SPI +version=0.0.0 +author=Arduino +maintainer=Elron +sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. +paragraph=SPI is a synchronous serial data protocol used by microcontrollers for communicating with one or more peripheral devices quickly over short distances. It uses three lines common to all devices (MISO, MOSI and SCK) and one specific for each device. +category=Communication +url=http://www.arduino.cc/en/Reference/SPI +architectures=MIK32_Amur + diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp new file mode 100644 index 0000000..7a28066 --- /dev/null +++ b/libraries/SPI/src/SPI.cpp @@ -0,0 +1,339 @@ +#include "SPI.h" +#include "mik32_hal_spi.h" + +SPI_HandleTypeDef hspi; +bool newConfig = false; +bool isInited = false; +uint32_t currentSpeed = 0; +int8_t currentDataOrder = -1; +int8_t currentDataMode = -1; +static uint8_t reverse_bits(uint8_t byte); + +// ------------------------------------------------------------------ // + +void SPISettings::spiUpdateSettings(uint32_t speedMaximum, uint8_t dataOrder, uint8_t dataMode) +{ + // update config only if something has changed + if ((currentSpeed != speedMaximum) || (currentDataOrder != dataOrder) || + (currentDataMode != dataMode)) + { + // Find the fastest clock that is less than or equal to the + // given clock rate. If nothing is slow enough - use the slowest. + // mik32v2 has the set of deviders, that can be calculate as: + // div = 2 << (1...7). Value in braсkets is a value for config register + uint8_t divRegVal = 0; // start from minimal divider (maximum speed) + while(divRegVal < 7) + { + divRegVal++; // values from 1 to 7 + if ((F_CPU/(2 << divRegVal)) <= speedMaximum) + // find suitable divider + break; + } + // if break didn't call in cycle, it will be the greatest divRegVal (and divider) + + // update config + hspi.Instance = SPI_1; + hspi.Init.SPI_Mode = HAL_SPI_MODE_MASTER; // only master mode + hspi.Init.CLKPhase = dataMode & 0b00000001; + hspi.Init.CLKPolarity = (dataMode & 0b00000010)>>1; + hspi.Init.ThresholdTX = 4; + hspi.Init.BaudRateDiv = divRegVal; + hspi.Init.Decoder = SPI_DECODER_NONE; + hspi.Init.ManualCS = SPI_MANUALCS_ON; + hspi.Init.ChipSelect = SPI_CS_NONE; + + currentSpeed = speedMaximum; + currentDataOrder = dataOrder; + currentDataMode = dataMode; + newConfig = true; + } +} + +// ------------------------------------------------------------------ // +// pins shift in gpio register +#define PIN_1_3_GPIO_S 3 +#define PIN_1_4_GPIO_S 4 + +SPIClass SPI; +bool SPIClass::spiInUse = false; +uint8_t SPIClass::interruptMode = 0; +uint8_t SPIClass::interruptMask = 0; + +void SPIClass::begin() +{ + // there is a seller on pin 1.6 which replace D10 from spi NSS pin 1.3 to pin 1.4, + // because spi needs pin 1.3 for correct work + + // replace config from 1.3 to 1.4 + uint8_t config = ((PAD_CONFIG->PORT_1_CFG) & (0b11<<(2*PIN_1_3_GPIO_S))) >> (2*PIN_1_3_GPIO_S); + if (config == 0) // common gpio + { + // pin direction + uint8_t direction = ((GPIO_1->DIRECTION_IN) & (1<> PIN_1_3_GPIO_S; + if (direction == 1) // input + GPIO_1->DIRECTION_IN |= (1<DIRECTION_OUT |= (1<PORT_1_PUPD) & (0b11<<(2*PIN_1_3_GPIO_S))) >> (2*PIN_1_3_GPIO_S); + PAD_CONFIG ->PORT_1_PUPD &= (~(0b11<<(2*PIN_1_4_GPIO_S))); // clear + PAD_CONFIG ->PORT_1_PUPD |= ((pupd_1_3&0b11)<<(2*PIN_1_4_GPIO_S)); // set new + + //current state + uint8_t state1_3 = ((GPIO_1->OUTPUT_) & (1<> PIN_1_3_GPIO_S; + GPIO_1->OUTPUT_ &= (~(0b1<OUTPUT_ |= ((state1_3&0b1)<PORT_1_CFG &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // set config to 0 - common gpio mode + + // pin direction + uint8_t direction = ((GPIO_1->DIRECTION_IN) & (1<> PIN_1_4_GPIO_S; + if (direction == 1) // input + GPIO_1->DIRECTION_IN |= (1<DIRECTION_OUT |= (1<PORT_1_PUPD) & (0b11<<(2*PIN_1_4_GPIO_S))) >> (2*PIN_1_4_GPIO_S); + PAD_CONFIG ->PORT_1_PUPD &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // clear + PAD_CONFIG ->PORT_1_PUPD |= ((pupd_1_4&0b11)<<(2*PIN_1_3_GPIO_S)); // set new + + // current state + uint8_t state1_4 = ((GPIO_1->OUTPUT_) & (1<> PIN_1_4_GPIO_S; + GPIO_1->OUTPUT_ &= (~(0b1<OUTPUT_ |= ((state1_4&0b1)< 0)) + { + for (uint8_t i = 0; i < EXTERNAL_NUM_INTERRUPTS; i++) + { + if (interruptMask & (1 << i)) + // disable every interrupt by it's number + disableInterrupt(i); + } + } + + // initialize spi bus or update config + if(spiInUse && ((!isInited) || newConfig)) + { + // initialize spi with given settings + if (HAL_SPI_Init(&hspi) != HAL_OK) + ErrorMsgHandler("SPI.beginTransaction(): initialization error"); + else + isInited = true; + } +} + +uint8_t SPIClass::transfer(uint8_t data) +{ + uint8_t rxByte = 0; + + if (isInited) + { + // reverse bits if LSB mode needed + if (currentDataOrder == LSBFIRST) + data = reverse_bits(data); + + // send and recieve data + HAL_StatusTypeDef SPI_Status = HAL_SPI_Exchange(&hspi, &data, &rxByte, 1, SPI_TIMEOUT_DEFAULT*2); + if (SPI_Status != HAL_OK) + HAL_SPI_ClearError(&hspi); + + // reverse bits again if LSB mode needed + if (currentDataOrder == LSBFIRST) + rxByte = reverse_bits(rxByte); + } + return rxByte; +} + +uint16_t SPIClass::transfer16(uint16_t data) +{ + uint8_t buf[2]; + uint16_t rxVal = 0; + if (isInited) + { + // prepare data for send + if (currentDataOrder == LSBFIRST) + { + // least significant byte is forward and reverse bits inside each byte + buf[0] = reverse_bits(data&0xFF); + buf[1] = reverse_bits((data>>8)&0xFF); + } + else + { + // most significant byte is forward + buf[0] = (data>>8)&0xFF; + buf[1] = data&0xFF; + } + + // send and recieve data + HAL_StatusTypeDef SPI_Status = HAL_SPI_Exchange(&hspi, buf, buf, 2, SPI_TIMEOUT_DEFAULT*2); + if (SPI_Status != HAL_OK) + HAL_SPI_ClearError(&hspi); + + // process the received data + if (currentDataOrder == LSBFIRST) + // reverse bits for LSB mode + rxVal = ( ((uint16_t)reverse_bits(buf[1]) ) << 8) | reverse_bits(buf[0]); + else + rxVal = ( ((uint16_t)buf[0]) << 8) | buf[1]; + } + return rxVal; +} + +void SPIClass::transfer(void *buf, size_t count) +{ + if (count == 0) + return; + + if (isInited) + { + uint8_t *p = (uint8_t *)buf; + + // reverse bits in buffer if LSB mode needed + if (currentDataOrder == LSBFIRST) + { + for (uint32_t i = 0; i < count; i++) + *(p+i) = reverse_bits(*(p+i)); + } + + // send and recieve data using the same buffer + HAL_StatusTypeDef SPI_Status = HAL_SPI_Exchange(&hspi, (uint8_t*)buf, (uint8_t*)buf, count, SPI_TIMEOUT_DEFAULT*2); + if (SPI_Status != HAL_OK) + HAL_SPI_ClearError(&hspi); + + // reverse bits if LSB mode needed + if (currentDataOrder == LSBFIRST) + { + p = (uint8_t *)buf; // return to buf beginning + for (uint32_t i = 0; i < count; i++) + *(p+i) = reverse_bits(*(p+i)); + } + } +} + +void SPIClass::endTransaction(void) +{ + // enable interrupts in use + if (spiInUse && (interruptMode > 0)) + { + for (uint8_t i = 0; i < EXTERNAL_NUM_INTERRUPTS; i++) + { + if (interruptMask & (1 << i)) + // enable every interrupt in use by it's number + enableInterrupt(i); + } + } +} + +// ------------------------------------ // +void SPIClass::setBitOrder(uint8_t bitOrder) +{ + currentDataOrder = bitOrder; +} + +void SPIClass::setDataMode(uint8_t dataMode) +{ + uint32_t config = hspi.Instance->CONFIG; + HAL_SPI_Disable(&hspi); + hspi.Init.CLKPhase = dataMode & 0b00000001; + hspi.Init.CLKPolarity = (dataMode & 0b00000010)>>1; + config &= ~((1 << SPI_CONFIG_CLK_PH_S) | (1 << SPI_CONFIG_CLK_POL_S)); // clear + config |= ((hspi.Init.CLKPhase << SPI_CONFIG_CLK_PH_S) | + (hspi.Init.CLKPolarity << SPI_CONFIG_CLK_POL_S)); // set new + hspi.Instance->CONFIG = config; + HAL_SPI_Enable(&hspi); +} + +void SPIClass::setClockDivider(uint8_t clockDiv) +{ + // if divider is in valid range + if ((clockDiv >= SPI_CLOCK_DIV4) && (clockDiv <= SPI_CLOCK_DIV256)) + { + uint32_t config = hspi.Instance->CONFIG; + HAL_SPI_Disable(&hspi); + hspi.Init.BaudRateDiv = clockDiv; + config &= ~(0b111 << SPI_CONFIG_BAUD_RATE_DIV_S); // clear + config |= (hspi.Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S); // set new + hspi.Instance->CONFIG = config; + HAL_SPI_Enable(&hspi); + } +} + +static uint8_t reverse_bits(uint8_t byte) +{ + byte = (byte & 0xF0) >> 4 | (byte & 0x0F) << 4; + byte = (byte & 0xCC) >> 2 | (byte & 0x33) << 2; + byte = (byte & 0xAA) >> 1 | (byte & 0x55) << 1; + return byte; +} \ No newline at end of file diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h new file mode 100644 index 0000000..109c3b1 --- /dev/null +++ b/libraries/SPI/src/SPI.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2010 by Cristian Maglie + * Copyright (c) 2014 by Paul Stoffregen (Transaction API) + * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) + * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes) + * SPI Master library for arduino. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of either the GNU General Public License version 2 + * or the GNU Lesser General Public License version 2.1, both as + * published by the Free Software Foundation. + */ + +#ifndef _SPI_H_INCLUDED +#define _SPI_H_INCLUDED + +#include + +// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(), +// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode) +#define SPI_HAS_TRANSACTION 1 + +// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method +#define SPI_HAS_NOTUSINGINTERRUPT 1 + +// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version. +// This way when there is a bug fix you can check this define to alert users +// of your code if it uses better version of this library. +// This also implies everything that SPI_HAS_TRANSACTION as documented above is +// available too. +#define SPI_ATOMIC_VERSION 1 + +#define SPI_DEFAULT_SPEED 4000000 + +#ifndef LSBFIRST +#define LSBFIRST 0 +#endif +#ifndef MSBFIRST +#define MSBFIRST 1 +#endif + +// dividers for setClockDivider() +#define SPI_CLOCK_DIV4 0x01 // 8 MHz +#define SPI_CLOCK_DIV8 0x02 // 4 MHz +#define SPI_CLOCK_DIV16 0x03 // 2 MHz +#define SPI_CLOCK_DIV32 0x04 // 1 MHz +#define SPI_CLOCK_DIV64 0x05 // 500 kHz +#define SPI_CLOCK_DIV128 0x06 // 250 kHz +#define SPI_CLOCK_DIV256 0x07 // 125 kHz + +// mode[1] - polarity, mode[0] - phase +#define SPI_MODE0 0b00 +#define SPI_MODE1 0b01 +#define SPI_MODE2 0b10 +#define SPI_MODE3 0b11 + + +class SPISettings +{ +public: + SPISettings(uint32_t speedMaximum, uint8_t dataOrder, uint8_t dataMode) + { + spiUpdateSettings(speedMaximum, dataOrder, dataMode); + } + + SPISettings() + { + spiUpdateSettings(SPI_DEFAULT_SPEED, MSBFIRST, SPI_MODE0); + } + +private: + void spiUpdateSettings(uint32_t speedMaximum, uint8_t dataOrder, uint8_t dataMode); + + friend class SPIClass; +}; + + +class SPIClass +{ +private: + static bool spiInUse; + static uint8_t interruptMode; // 0=none, 1=mask + static uint8_t interruptMask; // which interrupts to mask + +public: + // Initialize the SPI library + static void begin(); + + // If SPI is used from within an interrupt, this function registers + // that interrupt with the SPI library, so beginTransaction() can + // prevent conflicts. The input interruptNumber is the number used + // with attachInterrupt. + static void usingInterrupt(uint8_t interruptNumber); + // And this does the opposite. + static void notUsingInterrupt(uint8_t interruptNumber); + // Note: the usingInterrupt and notUsingInterrupt functions should + // not to be called from ISR context or inside a transaction. + // For details see: + // https://github.com/arduino/Arduino/pull/2381 + // https://github.com/arduino/Arduino/pull/2449 + + // Before using SPI.transfer() or asserting chip select pins, + // this function is used to gain exclusive access to the SPI bus + // and configure the correct settings. + void beginTransaction(SPISettings settings); + + // Write to the SPI bus (MOSI pin) and also receive (MISO pin) + uint8_t transfer(uint8_t data); + uint16_t transfer16(uint16_t data); + void transfer(void *buf, size_t count); + + // After performing a group of transfers and releasing the chip select + // signal, this function allows others to access the SPI bus + void endTransaction(void); + + // Disable the SPI bus + static void end(); + + // This function is deprecated. New applications should use + // beginTransaction() to configure SPI settings. + void setBitOrder(uint8_t bitOrder); + + // This function is deprecated. New applications should use + // beginTransaction() to configure SPI settings. + void setDataMode(uint8_t dataMode); + // This function is deprecated. New applications should use + // beginTransaction() to configure SPI settings. + void setClockDivider(uint8_t clockDiv); +}; + +extern SPIClass SPI; + +#endif diff --git a/libraries/Wire/examples/ds1307/ds1307.ino b/libraries/Wire/examples/ds1307/ds1307.ino new file mode 100644 index 0000000..cf8bd32 --- /dev/null +++ b/libraries/Wire/examples/ds1307/ds1307.ino @@ -0,0 +1,122 @@ +#include "Wire.h" +#include "time.h" + +// 7-bit RTC address on the I2C bus, specified in the datasheet +#define RTC_ADDR 0x68 +#define RTC_DATA_SIZE 7 + +// Specify 1 to set a new time at initialization +#define RTC_SET_NEW_TIME 0 + +uint8_t rxBytes[15]; +struct tm newTime; +char str[32]; + +void setup() +{ + Serial.begin(115200); + Serial.println("Start I2C rtc"); + + // Initializing the device as a master on the I2C bus + Wire.begin(); + + // Set new time if necessary + if (RTC_SET_NEW_TIME) + writeTimeToRtc(); // setting time is written inside the function +} + +void loop() +{ + // Read and display the current time + readTimeFromRtc(); + delay(2000); +} + +// ------------------- rtc ------------------- // +// Function to write new time to rtc +void writeTimeToRtc(void) +{ + /* The data to be written is located in the common buffer. + First, the register address is specified - writing starts from register 0x00. + Next, the values ​​of seconds, minutes, etc. are listed in accordance with the + order of the corresponding registers, specified in the datasheet for ds1307. + The values ​​are pre-translated into binary-decimal format + */ + // sec min hour wday mday month year + uint8_t buf[] = {0x00, dec2bcd(00), dec2bcd(01), dec2bcd(12), dec2bcd(2), dec2bcd(1), dec2bcd(1), dec2bcd(24)}; + + Wire.beginTransmission(RTC_ADDR); // Start of transaction + Wire.write(buf, sizeof(buf)); // Writing data for a transaction + uint8_t result = Wire.endTransmission(); // Completing a transaction + + // Show results + if (result == 0) + Serial.println("New time successfully set"); + else + Serial.println("New time set failed"); +} + +// Function to read time from rtc +void readTimeFromRtc(void) +{ + /* Send a request to receive data from rtc. When reading from rtc, you must + first specify from which register to start reading. To do this, use the extended + version of the requestFrom() function. In the arguments specify: + - device address, + - the number of bytes we want to read, + - the address of the starting register, + - the size of the address of the starting register in bytes, + - 1 - generate a stop condition after the request, 0 - do not generate + */ + Wire.requestFrom(RTC_ADDR, RTC_DATA_SIZE, 0x00, 1, 1); + // Get data + uint8_t i = 0; + while(Wire.available()) + rxBytes[i++] = Wire.read(); + + // Show new time in the port upon successful reading + if (i == RTC_DATA_SIZE) + parseAndShowTime(); + else + Serial.println("New time read failed"); +} + +// Functions for converting binary-decimal code to decimal and back +uint8_t bcd2dec(uint8_t val) +{ + return (val >> 4) * 10 + (val & 0x0f); +} + +uint8_t dec2bcd(uint8_t val) +{ + return ((val / 10) << 4) + (val % 10); +} + +// Function for format and output the current time to the port +void parseAndShowTime(void) +{ + /* take the values ​​for time output from the received data buffer. + Convert the values ​​into decimal format and adjust them in accordance with + the datasheet for ds1307 + */ + newTime.tm_sec = bcd2dec(rxBytes[0] & 0x7f); + newTime.tm_min = bcd2dec(rxBytes[1]); + if (rxBytes[2] & (1 << 6)) + { + // RTC in 12 hour mode + newTime.tm_hour = bcd2dec(rxBytes[2] & 0x1f) - 1; + if (rxBytes[2] & (1 << 5)) + newTime.tm_hour += 12; + } + else + newTime.tm_hour = bcd2dec(rxBytes[2] & 0x3f); + newTime.tm_wday = bcd2dec(rxBytes[3])-1; + newTime.tm_mday = bcd2dec(rxBytes[4]); + newTime.tm_mon = bcd2dec(rxBytes[5])-1; + // Subtract 1900 so that the year is correctly displayed in the struct tm type structure + newTime.tm_year = bcd2dec(rxBytes[6])+2000-1900; + + // The received time is output to the port in the format Sun Aug 19 02:56:02 2012 + strftime(str, sizeof(str), "%c", &newTime); + Serial.println(str); +} diff --git a/libraries/Wire/examples/i2c_master/i2c_master.ino b/libraries/Wire/examples/i2c_master/i2c_master.ino new file mode 100644 index 0000000..ef358fc --- /dev/null +++ b/libraries/Wire/examples/i2c_master/i2c_master.ino @@ -0,0 +1,92 @@ +// I2C master +#include + +// Slave address +uint8_t SLAVE_ADDRESS = 0x33; + +// Buffers for sending and receiving +uint8_t masterTxData[3] = {0x30, 0x41, 0x51}; +uint8_t masterRxData[4] = {0}; + +// Function for sending data via I2C bus +uint8_t masterSendData(uint8_t* data, uint8_t dataLen) +{ + // Initiating work with the bus + Wire.beginTransmission(SLAVE_ADDRESS); + // Send data + Wire.write(data, dataLen); + // Finish working with the bus and return the result + return Wire.endTransmission(); +} + +// Function to receive a specified number of bytes from the I2C bus +uint8_t masterGetData(uint8_t *buf, uint8_t dataSize) +{ + // Request data + Wire.requestFrom(SLAVE_ADDRESS, dataSize); + // If there are bytes available for reading, read them in a loop + uint8_t n = 0; + while (Wire.available()) + { + // reading from the bus - from the slave device + buf[n] = Wire.read(); + // Increasing the number of received bytes + n++; + } + // Return the number of received bytes + return n; +} + + +// -------------------------------------------- // + +void setup() +{ + Serial.begin(115200); + while (!Serial); + Serial.println("I2C master start"); + + // Initialize the device on the I2C bus as a master + Wire.begin(); + Wire.setClock(400000); +} + +void loop() +{ + // Send data to slave + Serial.println("------------------------"); + Serial.println("Master | Sending 3 bytes"); + uint8_t result = masterSendData(masterTxData, sizeof(masterTxData)); + // Show result + if (result == 0) + Serial.println("Master | Bytes sended"); + else + { + Serial.print("Master | Send ERROR! Code: "); + Serial.println(result); + } + // Change the first byte for variety + masterTxData[0] += 1; + // Delay before requesting data + delay(2000); + + + // Request data from the slave + Serial.println("------------------------"); + Serial.println("Master | Receiving 4 bytes"); + uint8_t bytesQty = masterGetData(masterRxData, sizeof(masterRxData)); + // Show result + if (bytesQty == 0) + Serial.println("Master | Receive ERROR!"); + else + { + for (uint8_t i = 0; i < bytesQty; i++) + { + Serial.print("Master | Received byte: 0x"); + Serial.println(masterRxData[i], HEX); + } + } + // Delay before sending data + delay(2000); +} + diff --git a/libraries/Wire/examples/i2c_scanner/i2c_scanner.ino b/libraries/Wire/examples/i2c_scanner/i2c_scanner.ino new file mode 100644 index 0000000..54e3962 --- /dev/null +++ b/libraries/Wire/examples/i2c_scanner/i2c_scanner.ino @@ -0,0 +1,48 @@ +// i2c_scanner +#include + +void setup() +{ + Serial.begin(115200); + while (!Serial); + Serial.println("I2C scanner start"); + + Wire.begin(); +} + +void loop() +{ + int devicesQty = 0; + Serial.println("Scanning..."); + + for (byte address = 1; address < 127; address++) + { + // transmitting address to I2C bus + Wire.beginTransmission(address); + byte error = Wire.endTransmission(); + + // Wire.endTransmission() will return 0 only if an ACK is received + // from the subscriber with the current address + + if (error == 0) + { + Serial.print("Device found at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.println(address, HEX); + devicesQty++; + } + delayMicroseconds(1); + } + + if (devicesQty == 0) + Serial.println("No device found"); + else + { + Serial.print(devicesQty); + Serial.println(" devices found"); + } + + Serial.println(); + delay(5000); +} diff --git a/libraries/Wire/examples/i2c_slave/i2c_slave.ino b/libraries/Wire/examples/i2c_slave/i2c_slave.ino new file mode 100644 index 0000000..2b86bda --- /dev/null +++ b/libraries/Wire/examples/i2c_slave/i2c_slave.ino @@ -0,0 +1,91 @@ +// I2C slave +#include + +// The address on the I2C bus that we will assign to this device +constexpr int MY_ADDRESS = 0x33; + +// Buffers for sending and receiving +uint8_t slaveTxData[4] = {0x00, 0x10, 0x22, 0x84}; +uint8_t slaveRxData[8] = {0}; + +// Function for receiving data from the I2C bus +uint8_t slaveGetData(uint8_t *buf, uint8_t bufSize) +{ + // If there are bytes available for reading, read them in a loop + uint8_t n = 0; + while (Wire.available()) + { + // Read from the bus - from the master device + buf[n] = Wire.read(); + // If the entire buffer is filled, stop reading + if (++n == bufSize) + break; + } + // Return the number of received bytes + return n; +} + +// Function for sending data via I2C bus +uint8_t slaveSendData(uint8_t* data, uint8_t dataLen) +{ + return Wire.write(data, dataLen); +} + +// A function that will be called if the master requests data +void requestEvent() +{ + Serial.println("------------------------"); + Serial.println("Slave | Request event"); + + // Send data + uint8_t txBytesQty = slaveSendData(slaveTxData, sizeof(slaveTxData)); + // Show result + if (txBytesQty == sizeof(slaveTxData)) + Serial.print("Slave | Bytes quantity sent: "); + else + Serial.print("Slave | Send ERROR! Bytes quantity sent: "); + Serial.println(txBytesQty); + + slaveTxData[0] += 1; // Change the first byte for variety +} + +// Function that will be called if the master sends data +void receiveEvent(int bytesNum) +{ + Serial.println("------------------------"); + Serial.println("Slave | Receive event"); + + // Get new data + uint8_t rxBytesQty = slaveGetData(slaveRxData, sizeof(slaveRxData)); + // Show result + if (rxBytesQty == 0) + Serial.println("Slave | Receive ERROR!"); + else + { + for (uint8_t i = 0; i < rxBytesQty; i++) + { + Serial.print("Slave | Received byte: 0x"); + Serial.println(slaveRxData[i], HEX); + } + } +} + +// ----------------------------------------- // +void setup() +{ + Serial.begin(115200); + while (!Serial); + Serial.println("I2C slave start"); + + // Start working with I2C as a slave device with the address MY_ADDRESS + Wire.begin(MY_ADDRESS); + // Register an event handler that will be called when data is requested by the master device + Wire.onRequest(requestEvent); + // Register an event handler that will be called after receiving data from the master device + Wire.onReceive(receiveEvent); +} + +void loop() +{ + // Don't do anything in the loop, everything is implemented in the registered event handlers +} diff --git a/libraries/Wire/keywords.txt b/libraries/Wire/keywords.txt new file mode 100644 index 0000000..196e7ce --- /dev/null +++ b/libraries/Wire/keywords.txt @@ -0,0 +1,29 @@ +####################################### +# Syntax Coloring Map For Wire +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +setClock KEYWORD2 +beginTransmission KEYWORD2 +endTransmission KEYWORD2 +requestFrom KEYWORD2 +onReceive KEYWORD2 +onRequest KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +Wire KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/Wire/library.properties b/libraries/Wire/library.properties new file mode 100644 index 0000000..4b6e919 --- /dev/null +++ b/libraries/Wire/library.properties @@ -0,0 +1,9 @@ +name=Wire +version=0.0.0 +author=Arduino +maintainer=Elron +sentence=Allows the communication between devices or sensors connected via Two Wire (I2C) Interface Bus. +paragraph= +category=Communication +url=http://www.arduino.cc/en/Reference/Wire +architectures=MIK32_Amur diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp new file mode 100644 index 0000000..f5824d0 --- /dev/null +++ b/libraries/Wire/src/Wire.cpp @@ -0,0 +1,318 @@ + +extern "C" +{ +#include +#include +#include +#include "utility/twi.h" +} +#include "Wire.h" + +// Initialize Class Variables +uint8_t TwoWire::rxBuffer[BUFFER_LENGTH]; +uint8_t TwoWire::rxBufferIndex = 0; +uint8_t TwoWire::rxBufferLength = 0; + +uint8_t TwoWire::txAddress = 0; // 7 bits without shift +uint8_t TwoWire::txBuffer[BUFFER_LENGTH]; +uint8_t TwoWire::txBufferIndex = 0; +uint8_t TwoWire::txBufferLength = 0; + +uint8_t TwoWire::transmitting = 0; +uint8_t TwoWire::slaveAddress = 0; // 7 bits without shift in slave mode + +void (*TwoWire::user_onRequest)(void); +void (*TwoWire::user_onReceive)(int); + +// Constructors +TwoWire::TwoWire() +{ +} + +// --------------------------- Public Methods --------------------------- // +void TwoWire::begin(void) +{ + rxBufferIndex = 0; + rxBufferLength = 0; + txBufferIndex = 0; + txBufferLength = 0; + twi_init(slaveAddress); + + twi_attachSlaveTxEvent(onRequestService); // default callback must exist + twi_attachSlaveRxEvent(onReceiveService); // default callback must exist +} + +void TwoWire::begin(uint8_t address) +{ + slaveAddress = address; + begin(); +} + +void TwoWire::begin(int address) +{ + begin((uint8_t)address); +} + +void TwoWire::end(void) +{ + flush(); // wait for transmission complete + twi_deinit(); + slaveAddress = 0; +} + +void TwoWire::setClock(uint32_t clock) +{ + if (twi_setFrequency(clock, false) != I2C_OK) + ErrorMsgHandler("Wire.setClock(): invalid frequency or Wire was not begin"); +} + +// ----------------------------- request ----------------------------- // +uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) +{ + if (isize > 0) + { + // send internal register address if needed + beginTransmission(address); // save slave address + + // the maximum size of internal address is 3 bytes + if (isize > 3) isize = 3; + + // write internal register address - most significant byte first + while (isize-- > 0) + write((uint8_t)(iaddress >> (isize*8))); // write data to txBuf + + endTransmission(false); // transmit data without stop generation + } + // clamp to buffer length + if(quantity > BUFFER_LENGTH) + quantity = BUFFER_LENGTH; + + // perform blocking read into buffer + uint8_t read = twi_masterReadFrom(address, rxBuffer, quantity, sendStop); + + // set rx buffer iterator vars + rxBufferIndex = 0; + rxBufferLength = read; + + return read; +} + +uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint32_t)0, (uint8_t)0, (uint8_t)sendStop); +} + +uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); +} + +uint8_t TwoWire::requestFrom(int address, int quantity) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); +} + +uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop); +} + +// ----------------------------- Transmission ----------------------------- // +void TwoWire::beginTransmission(uint8_t address) +{ + // indicate that we are transmitting + transmitting = 1; + // set address of targeted slave whithout shift + txAddress = address; + // reset tx buffer iterator vars + txBufferIndex = 0; + txBufferLength = 0; +} + +void TwoWire::beginTransmission(int address) +{ + beginTransmission((uint8_t)address); +} + +// Calling endTransmission(false) allows a sketch to +// perform a repeated start. +// WARNING: Nothing in the library keeps track of whether +// the bus tenure has been properly ended with a STOP. It +// is very possible to leave the bus in a hung state if +// no call to endTransmission(true) is made. Some I2C +// devices will behave oddly if they do not see a STOP. +uint8_t TwoWire::endTransmission(uint8_t sendStop) +{ + uint8_t ret = I2C_ERROR; + if (transmitting) + { + // transmit buffer (blocking) + ret = twi_masterWriteTo(txAddress, txBuffer, txBufferLength, sendStop); + // reset tx buffer iterator vars + txBufferIndex = 0; + txBufferLength = 0; + // indicate that we are done transmitting + transmitting = 0; + } + return ret; +} + +// This provides backwards compatibility with the original +// definition, and expected behaviour, of endTransmission +uint8_t TwoWire::endTransmission(void) +{ + return endTransmission((uint8_t)true); +} + +// ----------------------------- Write ----------------------------- // +// must be called in: +// slave tx event callback +// or after beginTransmission(address) +size_t TwoWire::write(uint8_t data) +{ + size_t ret = 1; + if (transmitting) + { + // in master transmitter mode + // don't bother if buffer is full + if(txBufferLength >= BUFFER_LENGTH) + { + setWriteError(); + return 0; + } + // put byte in tx buffer + txBuffer[txBufferIndex] = data; + ++txBufferIndex; + // update amount in buffer + txBufferLength = txBufferIndex; + } + else + { + // in slave send mode - reply to master + if (twi_slaveWrite(&data, 1) != I2C_OK) + ret = 0; + } + return ret; +} + +/** + * @brief This function must be called in slave Tx event callback or after + * beginTransmission() and before endTransmission(). + * @param pdata: pointer to the buffer data + * @param quantity: number of bytes to write + * @retval number of bytes ready to write. + */ +size_t TwoWire::write(const uint8_t *data, size_t quantity) +{ + size_t ret = quantity; + + if (transmitting) + { + // in master transmitter mode + for(size_t i = 0; i < quantity; ++i) + write(data[i]); + } + else + { + // in slave send mode - reply to master + if (twi_slaveWrite((uint8_t *)data, quantity) != I2C_OK) + ret = 0; + } + return ret; +} + +// ----------------------------- Stream func ----------------------------- // +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::available(void) +{ + return rxBufferLength - rxBufferIndex; +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::read(void) +{ + int value = -1; + + // get each successive byte on each call + if (rxBufferIndex < rxBufferLength) + { + value = rxBuffer[rxBufferIndex]; + ++rxBufferIndex; + } + return value; +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::peek(void) +{ + int value = -1; + + if (rxBufferIndex < rxBufferLength) + value = rxBuffer[rxBufferIndex]; + + return value; +} + +void TwoWire::flush(void) +{ + // we use blocking transactions, so we won't get here until the reception/transmission is complete + rxBufferIndex = 0; + rxBufferLength = 0; + txBufferIndex = 0; + txBufferLength = 0; + txAddress = 0; +} + +// ----------------------------- Events ----------------------------- // +// behind the scenes function that is called when data is received +void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) +{ + // don't bother if user hasn't registered a callback + if(!user_onReceive) + return; + + // copy twi rx buffer into local read buffer + // this enables new reads to happen in parallel + memcpy(rxBuffer, inBytes, numBytes); + + // set rx iterator vars + rxBufferIndex = 0; + rxBufferLength = numBytes; + // alert user program + user_onReceive(numBytes); +} + +// behind the scenes function that is called when data is requested +void TwoWire::onRequestService(void) +{ + // don't bother if user hasn't registered a callback + if(user_onRequest) + user_onRequest(); // alert user program +} + +// sets function called on slave write +void TwoWire::onReceive( void (*function)(int) ) +{ + user_onReceive = function; +} + +// sets function called on slave read +void TwoWire::onRequest( void (*function)(void) ) +{ + user_onRequest = function; +} + +// С function for trap handler +extern "C" void wire_handler_wrapper(void) +{ + twi_interruptHandler(); +} + +// ----------------------------- Preinstantiate Objects ----------------------------- // +TwoWire Wire = TwoWire( ); diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h new file mode 100644 index 0000000..ba99bbf --- /dev/null +++ b/libraries/Wire/src/Wire.h @@ -0,0 +1,69 @@ + +#ifndef TwoWire_h +#define TwoWire_h + +#include "Stream.h" +#include "Arduino.h" + +#define BUFFER_LENGTH 32 + +// WIRE_HAS_END means Wire has end() +#define WIRE_HAS_END 1 + +class TwoWire : public Stream +{ + private: + static uint8_t rxBuffer[]; + static uint8_t rxBufferIndex; + static uint8_t rxBufferLength; + + static uint8_t txAddress; + static uint8_t txBuffer[]; + static uint8_t txBufferIndex; + static uint8_t txBufferLength; + + static uint8_t transmitting; + static uint8_t slaveAddress; + static void (*user_onRequest)(void); + static void (*user_onReceive)(int numBytes); + static void onRequestService(void); + static void onReceiveService(uint8_t* inBytes, int numBytes); + public: + TwoWire(); + void begin(); + void begin(uint8_t); + void begin(int); + void end(); + void setClock(uint32_t frequency); + + void beginTransmission(uint8_t address); + void beginTransmission(int address); + uint8_t endTransmission(void); + uint8_t endTransmission(uint8_t sendStop); + + uint8_t requestFrom(uint8_t address, uint8_t quantity); + uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop); + uint8_t requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop); + uint8_t requestFrom(int address, int quantity); + uint8_t requestFrom(int address, int quantity, int sendStop); + + virtual int available(void); + virtual int read(void); + virtual int peek(void); + virtual void flush(void); + + virtual size_t write(uint8_t data); + virtual size_t write(const uint8_t * data, size_t quantity); + inline size_t write(unsigned long n) { return write((uint8_t)n); } + inline size_t write(long n) { return write((uint8_t)n); } + inline size_t write(unsigned int n) { return write((uint8_t)n); } + inline size_t write(int n) { return write((uint8_t)n); } + using Print::write; + + void onReceive( void (*)(int) ); + void onRequest( void (*)(void) ); +}; + +extern TwoWire Wire; + +#endif diff --git a/libraries/Wire/src/utility/twi.c b/libraries/Wire/src/utility/twi.c new file mode 100644 index 0000000..2483806 --- /dev/null +++ b/libraries/Wire/src/utility/twi.c @@ -0,0 +1,384 @@ +#include +#include +#include "Arduino.h" +#include "twi.h" +#include "mik32_hal_i2c.h" +#include "mik32_hal_irq.h" + +#define TIMEOUT_TICKS 1000000 +#define TWI_FREQ_DEF WIRE_FREQ_100K // default is 100 kHz + +static void (*twi_onSlaveTransmit)(void); +static void (*twi_onSlaveReceive)(uint8_t*, int); + +static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_rxBufferIndex; + +I2C_HandleTypeDef hi2c; +static uint32_t CurrentFrequency = TWI_FREQ_DEF; +static bool twiIsOn = false; + +// ---------------------------------------------------------------- // + +/* + * Function twi_init + * Desc readys twi pins and sets twi bitrate + * Input slaveAddress - address of Arduino if working in slave mode + * Output none + */ +uint8_t twi_init(uint8_t slaveAddress) +{ + // Common settings + uint32_t EPICmask; + +#if I2C_NUM == 0 + hi2c.Instance = I2C_0; + EPICmask = HAL_EPIC_I2C_0_MASK; +#elif I2C_NUM == 1 + hi2c.Instance = I2C_1; + EPICmask = HAL_EPIC_I2C_1_MASK; +#else + #error "Unsupported I2C_NUM value in pins_arduino.h" +#endif + + hi2c.Init.DigitalFilter = I2C_DIGITALFILTER_2CLOCKCYCLES; + hi2c.Init.AnalogFilter = I2C_ANALOGFILTER_DISABLE; + if (slaveAddress == 0) // if there is no address - master mode + { + hi2c.Init.Mode = HAL_I2C_MODE_MASTER; + hi2c.Init.AutoEnd = I2C_AUTOEND_ENABLE; + } + else + { + // 7-bit address without any additional bits + hi2c.Init.Mode = HAL_I2C_MODE_SLAVE; + hi2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; // stretch is used + hi2c.Init.OwnAddress1 = slaveAddress; + } + + // set the frequency + if (hi2c.Init.Mode == HAL_I2C_MODE_MASTER) + twi_setFrequency(CurrentFrequency, true); + else + twi_setFrequency(0, true); + + if (HAL_I2C_Init(&hi2c) != HAL_OK) + return I2C_ERROR; + + // enable interrupts for slave mode + if (hi2c.Init.Mode == HAL_I2C_MODE_SLAVE) + { + // enable interrupts for addressing, byte reception and transfer completion + HAL_I2C_InterruptDisable(&hi2c, I2C_INTMASK); + HAL_I2C_InterruptEnable(&hi2c, I2C_CR1_ADDRIE_M | I2C_CR1_RXIE_M | I2C_CR1_STOPIE_M); + // enable interrupt from i2c + HAL_EPIC_MaskLevelSet(EPICmask); + } + twiIsOn = true; + return I2C_OK; +} + +/* + * Function twi_deinit + * Desc disables twi pins + * Input none + * Output none + */ +void twi_deinit(void) +{ + uint32_t EPICmask; + + HAL_I2C_Disable(&hi2c); + // disable clock +#if I2C_NUM == 0 + hi2c.Instance = I2C_0; + EPICmask = HAL_EPIC_I2C_0_MASK; + __HAL_PCC_I2C_0_CLK_DISABLE(); +#elif I2C_NUM == 1 + hi2c.Instance = I2C_1; + EPICmask = HAL_EPIC_I2C_1_MASK; + __HAL_PCC_I2C_1_CLK_DISABLE(); +#else + #error "Unsupported I2C_NUM value in pins_arduino.h" +#endif + + // for slave mode disable interrupts from i2c + if (hi2c.Init.Mode == HAL_I2C_MODE_SLAVE) + HAL_EPIC_MaskLevelClear(EPICmask); + + // reconfigure pins to z state + GPIO_InitTypeDef GPIO_InitStruct; + memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct)); + // SDA + GPIO_InitStruct.Pin = (HAL_PinsTypeDef)digitalPinToBitMask(PIN_WIRE_SDA); + GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT; + GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; + HAL_GPIO_Init(digitalPinToPort(PIN_WIRE_SDA), &GPIO_InitStruct); + // SCL + GPIO_InitStruct.Pin = (HAL_PinsTypeDef)digitalPinToBitMask(PIN_WIRE_SCL); + HAL_GPIO_Init(digitalPinToPort(PIN_WIRE_SCL), &GPIO_InitStruct); + + twiIsOn = false; +} + +/* + * Function twi_setClock + * Desc sets twi bit rate + * Input Clock Frequency - 100000 / 400000 / 1000000, + * onInit = true only if function is called from twi_init() + * Output I2C_OK - frequency changed, I2C_ERROR - frequency didn't change + */ +uint8_t twi_setFrequency(uint32_t frequency, bool onInit) +{ + uint8_t ret = I2C_OK; + + // change the frequency only during or after bus initialization + if (twiIsOn || onInit) + { + // You can change the frequency only when the interface is turned off + HAL_I2C_Disable(&hi2c); + + if (frequency == WIRE_FREQ_100K) // 100 kHz + { + hi2c.Clock.PRESC = 2; + hi2c.Clock.SCLDEL = 8; + hi2c.Clock.SDADEL = 2; + hi2c.Clock.SCLH = 49; + hi2c.Clock.SCLL = 49; + CurrentFrequency = WIRE_FREQ_100K; + } + else if (frequency == WIRE_FREQ_400K) // 400 kHz + { + hi2c.Clock.PRESC = 0; + hi2c.Clock.SCLDEL = 3; + hi2c.Clock.SDADEL = 2; + hi2c.Clock.SCLH = 30; + hi2c.Clock.SCLL = 30; + CurrentFrequency = WIRE_FREQ_400K; + } + else if (frequency == WIRE_FREQ_1000K)// 1000 kHz + { + hi2c.Clock.PRESC = 0; + hi2c.Clock.SCLDEL = 1; + hi2c.Clock.SDADEL = 2; + hi2c.Clock.SCLH = 6; + hi2c.Clock.SCLL = 6; + CurrentFrequency = WIRE_FREQ_1000K; + } + else if (frequency == 0) // slave mode + { + hi2c.Clock.PRESC = 0; + hi2c.Clock.SCLDEL = 0; + hi2c.Clock.SDADEL = 2; + hi2c.Clock.SCLH = 0; + hi2c.Clock.SCLL = 0; + } + else + // frequency does not change + ret = I2C_ERROR; + + // write the timings to the register if everything is OK + if (ret == I2C_OK) + HAL_I2C_SetClockSpeed(&hi2c); + + //turn the interface back only if initialization has already passed + if (twiIsOn) + HAL_I2C_Enable(&hi2c); + } + else + ret = I2C_ERROR; + + return ret; +} + +/* + * Function twi_masterReadFrom + * Desc attempts to become twi bus master and read a + * series of bytes from a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes to read into array + * sendStop: Boolean indicating whether to send a stop at the end + * Output number of bytes read + */ +uint8_t twi_masterReadFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) +{ + uint8_t ret = 0; + + // if there are errors left from previous transactions, you need to restart + // the interface for correct operation + if (hi2c.ErrorCode != I2C_ERROR_NONE) + HAL_I2C_Reset(&hi2c); + + if (sendStop) hi2c.Init.AutoEnd = 1; + else hi2c.Init.AutoEnd = 0; + + // put the data directly into the external buffer + if (HAL_I2C_Master_Receive(&hi2c, address, data, length, TIMEOUT_TICKS) == HAL_OK) + ret = length; + + return ret; +} + +/* + * Function twi_masterWriteTo + * Desc attempts to become twi bus master and write a + * series of bytes to a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes in array + * sendStop: boolean indicating whether or not to send a stop at the end + * Output 0 .. success + * 1 .. length to long for buffer + * 2 .. address send, NACK received + * 3 .. data send, NACK received + * 4 .. other twi error (lost bus arbitration, bus error, ..) + * 5 .. timeout + */ +uint8_t twi_masterWriteTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) +{ + uint8_t ret = I2C_OK; + + // if there are errors left from previous transactions, you need to restart + // the interface for correct operation + if (hi2c.ErrorCode != I2C_ERROR_NONE) + HAL_I2C_Reset(&hi2c); + + if (sendStop) hi2c.Init.AutoEnd = 1; + else hi2c.Init.AutoEnd = 0; + + // take data from an external buffer + HAL_I2C_Master_Transmit(&hi2c, address, data, length, TIMEOUT_TICKS); + + // parse errors + // check separately, because in hal libraries not all functions look at this + if (hi2c.Instance->ISR & I2C_ISR_NACKF_M) + hi2c.ErrorCode = I2C_ERROR_NACK; + if (hi2c.ErrorCode == (HAL_I2C_ErrorTypeDef)I2C_ERROR_TIMEOUT) ret = I2C_TIMEOUT; // timeout + else if (hi2c.ErrorCode == (HAL_I2C_ErrorTypeDef)I2C_ERROR_NACK) ret = I2C_NACK_DATA; // didn't receive ACK + else if (hi2c.ErrorCode != (HAL_I2C_ErrorTypeDef)I2C_OK) ret = I2C_ERROR; // any other error + + return ret; +} + +/* + * Function twi_slaveWrite + * Desc attempts to become twi bus slave and write a + * series of bytes to a master after it asks + * Input txData: pointer to byte array + * bytesNum: number of bytes in array + * Output 0 .. success + * 5 .. timeout + */ +i2c_status_e twi_slaveWrite(uint8_t *txData, uint8_t bytesNum) +{ + if ((hi2c.ErrorCode != I2C_ERROR_NONE)) + HAL_I2C_Reset(&hi2c); + + // отправка данных + HAL_StatusTypeDef error_code = HAL_OK; + + hi2c.Instance->CR2 &= ~I2C_CR2_RELOAD_M; + + if (!(hi2c.Instance->CR1 & I2C_CR1_NOSTRETCH_M)) // NOSTRETCH = 0 + hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents + + hi2c.Instance->TXDR = txData[0]; // The first recording is made in advance + + // Запись байта + for (uint32_t tx_count = 1; tx_count < bytesNum; tx_count++) + { + if ((error_code = HAL_I2C_Slave_WaitTXIS(&hi2c, TIMEOUT_TICKS)) != HAL_OK) + { + // неудачная запись + hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents + hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus + HAL_I2C_Reset(&hi2c); + return I2C_TIMEOUT; + } + hi2c.Instance->TXDR = txData[tx_count]; + } + + if ((error_code = HAL_I2C_WaitBusy(&hi2c, TIMEOUT_TICKS)) != HAL_OK) + { + // неудачное завершение транзакции + HAL_I2C_Reset(&hi2c); + return I2C_TIMEOUT; + } + + hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents + hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus + + return I2C_OK; +} + +/* + * Function twi_attachSlaveRxEvent + * Desc sets function called before a slave read operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) +{ + twi_onSlaveReceive = function; +} + +/* + * Function twi_attachSlaveTxEvent + * Desc sets function called before a slave write operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveTxEvent( void (*function)(void) ) +{ + twi_onSlaveTransmit = function; +} + + +/* + * Function twi_interruptHandler + * Desc handles an interrupts from twi + * Input none + * Output none + */ +void twi_interruptHandler(void) +{ + uint32_t int_mask = hi2c.Instance->CR1 & I2C_INTMASK; // interrupts allowed + uint32_t interrupt_status = hi2c.Instance->ISR; // current flags + + // master calls by address, device in slave mode + if ((interrupt_status & I2C_ISR_ADDR_M) && (int_mask & I2C_CR1_ADDRIE_M)) + { + // reset ADDR flag + hi2c.Instance->ICR |= I2C_ICR_ADDRCF_M; + + // look at the transmission direction and respond to the request + if (interrupt_status & I2C_ISR_DIR_M) // master reads, slave sends + // отправляем данные + twi_onSlaveTransmit(); + else // master writes, slave reads + { + twi_rxBufferIndex = 0; // write from the beginning of the buffer + hi2c.State = HAL_I2C_STATE_BUSY; + hi2c.Instance->CR2 &= ~I2C_CR2_RELOAD_M; + // wait for interrupts because of receiving a byte or a stop condition + } + } + + // new byte of data received + if ((interrupt_status & I2C_ISR_RXNE_M) && (int_mask & I2C_CR1_RXIE_M)) + { + // put new byte into buffer + twi_rxBuffer[twi_rxBufferIndex++] = (uint8_t)hi2c.Instance->RXDR; + } + + // master sent a STOP to the bus + if ((interrupt_status & I2C_ISR_STOPF_M) && (int_mask & I2C_CR1_STOPIE_M)) + { + hi2c.State = HAL_I2C_STATE_END; + hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents + hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus + // pass the received data to callback function + twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); + } +} \ No newline at end of file diff --git a/libraries/Wire/src/utility/twi.h b/libraries/Wire/src/utility/twi.h new file mode 100644 index 0000000..4d83a97 --- /dev/null +++ b/libraries/Wire/src/utility/twi.h @@ -0,0 +1,41 @@ +#ifndef __TWI_H__ +#define __TWI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TWI_BUFFER_LENGTH +#define TWI_BUFFER_LENGTH 32 +#endif + +// I2C state +typedef enum +{ + I2C_OK = 0, + I2C_DATA_TOO_LONG = 1, + I2C_NACK_ADDR = 2, + I2C_NACK_DATA = 3, + I2C_ERROR = 4, + I2C_TIMEOUT = 5, + I2C_BUSY = 6 +} i2c_status_e; + +uint8_t twi_init(uint8_t slaveAddress); +void twi_deinit(void); +uint8_t twi_setFrequency(uint32_t frequency, bool onInit); + +uint8_t twi_masterReadFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop); +uint8_t twi_masterWriteTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop); +i2c_status_e twi_slaveWrite(uint8_t *txData, uint8_t bytesNum); + +void twi_attachSlaveRxEvent(void (*function)(uint8_t*, int)); +void twi_attachSlaveTxEvent(void (*function)(void)); +void twi_interruptHandler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __TWI_H__ */ + diff --git a/platform.txt b/platform.txt new file mode 100644 index 0000000..1d06945 --- /dev/null +++ b/platform.txt @@ -0,0 +1,81 @@ +name=ELBEAR boards +version=1.0.0 + +# Compiler and tools +compiler.prefix=riscv-none-elf- +compiler.path={runtime.tools.riscv.path}/bin/ +compiler.c.cmd={compiler.prefix}gcc +compiler.cpp.cmd={compiler.prefix}g++ +compiler.S.cmd={compiler.prefix}gcc +compiler.c.elf.cmd={compiler.prefix}g++ +compiler.ar.cmd={compiler.prefix}gcc-ar +compiler.size.cmd={compiler.prefix}size +compiler.objcopy.cmd={compiler.prefix}objcopy +compiler.elf2hex.cmd={compiler.prefix}objcopy + +# Include directories and defines +compiler.MIK32_Amur.extra_include= "-I{build.core.path}\avr\" "-I{build.core.path}\mik32\shared\include\" "-I{build.core.path}\mik32\shared\periphery\" "-I{build.core.path}\mik32\shared\runtime\" "-I{build.core.path}\mik32\shared\libs\" "-I{build.core.path}\mik32\hal\core\Include\" "-I{build.core.path}\mik32\hal\peripherals\Include\" "-I{build.core.path}\mik32\hal\utilities\Include\" +compiler.define="-DMCU_{build.mcu}" "-DF_CPU={build.f_cpu}" "-DARDUINO={runtime.ide.version}" "-DARDUINO_{build.board}" "-DARDUINO_ARCH_{build.arch}" "-DMIK32V2" + +build.flags.optimize=-Os +build.ldscript=spifi_cpp.ld + +# Compiler flags +compiler.warning_flags=-Wunused -Wuninitialized +compiler.warning_flags.none=-w +compiler.warning_flags.default= +compiler.warning_flags.more=-Wall +compiler.warning_flags.all=-Wall -Wextra + +compiler.extra_flags = -march=rv32imc_zicsr_zifencei -mabi=ilp32 -mcmodel=medlow {build.flags.optimize} -g3 -Wall -fsigned-char -ffunction-sections +compiler.S.flags = {compiler.extra_flags} -x assembler-with-cpp {compiler.define} {compiler.warning_flags} {compiler.MIK32_Amur.extra_include} +compiler.c.flags = -c -std=gnu11 {compiler.extra_flags} {compiler.define} {compiler.warning_flags} {compiler.MIK32_Amur.extra_include} +compiler.cpp.flags = -c -std=gnu++17 -fabi-version=0 -fno-exceptions -fno-rtti -fno-use-cxa-atexit -fno-threadsafe-statics {compiler.extra_flags} {compiler.define} {compiler.warning_flags} {compiler.MIK32_Amur.extra_include} +compiler.c.elf.flags = -march=rv32imc_zicsr_zifencei -mabi=ilp32 -mcmodel=medlow -nostartfiles -Xlinker +compiler.ar.flags=rc +compiler.elf2bin.flags=-O binary +compiler.elf2hex.flags=-O ihex + +# Compiler recipes +recipe.c.o.pattern= "{compiler.path}{compiler.c.cmd}" {compiler.c.flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" +recipe.S.o.pattern= "{compiler.path}{compiler.S.cmd}" {compiler.S.flags} {build.extra_flags} {includes} "{source_file}" -c -o "{object_file}" + +# Archiving +archive_file_path={build.path}/{archive_file} +recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{archive_file_path}" "{object_file}" + +# Combine gc-sections, archives, and objects +recipe.c.combine.pattern= "{compiler.path}{compiler.c.elf.cmd}" -o "{build.path}/{build.project_name}.elf" -T "{build.core.path}/mik32/shared/ldscripts/{build.ldscript}" {compiler.c.elf.flags} -Map={build.path}/{build.project_name}.map -Wl,--gc-sections "-L{build.path}" -Wl,--start-group {object_files} -Wl,--whole-archive "{archive_file_path}" -Wl,--no-whole-archive -lc -Wl,--end-group + +# Create output (.bin file) +recipe.objcopy.bin.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.elf2bin.flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" + +# Create output (.hex file) +recipe.objcopy.hex.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.elf2hex.flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" + +# Size calculation +recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" +recipe.size.regex= ^(?:\.text|\.data|\.rodata)\s+([0-9]+).* +recipe.size.regex.data= ^(?:\.data|\.bss|\.noinit)\s+([0-9]+).* + +# Uploader tool +tools.elbear_uploader.cmd=elbear_uploader +tools.elbear_uploader.cmd.windows=elbear_uploader.exe +tools.elbear_uploader.path={runtime.tools.elbear_uploader.path} +tools.elbear_uploader.upload.pattern={path}/{cmd} {build.path}/{build.project_name}.hex --com={serial.port} + +# Set elbear_uploader as programmer +programmers.elbear_uploader.name=Elbear Uploader +programmers.elbear_uploader.program.tool=elbear_uploader + +#Bootloader tool +tools.mik32_upload.cmd=mik32_upload +tools.mik32_upload.cmd.windows=mik32_upload.exe +tools.mik32_upload.path={runtime.tools.mik32_upload.path} +#bootloader can not be burnt if there is no erase command, even if it's empty +tools.mik32_upload.erase.pattern= +#for Tools > Burn Bootloader +tools.mik32_upload.bootloader.pattern={path}/{cmd} {runtime.platform.path}/bootloaders/{bootloader.file} --run-openocd --openocd-exec={runtime.tools.openocd.path}/bin/openocd.exe --openocd-interface={path}/openocd-scripts/interface/ftdi/mikron-link.cfg --openocd-target={path}/openocd-scripts/target/mik32.cfg +#for Sketch > Upload Using Programmer +tools.mik32_upload.program.pattern={path}/{cmd} {build.path}/{build.project_name}.hex --run-openocd --openocd-exec={runtime.tools.openocd.path}/bin/openocd.exe --openocd-interface={path}/openocd-scripts/interface/ftdi/mikron-link.cfg --openocd-target={path}/openocd-scripts/target/mik32.cfg diff --git a/programmers.txt b/programmers.txt new file mode 100644 index 0000000..0b507bb --- /dev/null +++ b/programmers.txt @@ -0,0 +1,6 @@ +# for Sketch > Upload Using Programmer and Tools > Burn Bootloader +mik32_upload.name=mik32 uploader +mik32_upload.protocol=mik32_upload +mik32_upload.program.tool=mik32_upload +mik32_upload.program.protocol=mik32_upload +mik32_upload.program.extra_params= diff --git a/variants/standart/pins_arduino.h b/variants/standart/pins_arduino.h new file mode 100644 index 0000000..52624fc --- /dev/null +++ b/variants/standart/pins_arduino.h @@ -0,0 +1,125 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_gpio.h" +#include "mik32_hal_timer32.h" +#include "wiring_constants.h" + +extern bool spiNssPinIsBlocked; + +// analog pins +#define PIN_A0 (14) +#define PIN_A1 (15) +#define PIN_A2 (16) +#define PIN_A3 (17) +// there are D18 and D19 between them +#define PIN_A4 (20) +#define PIN_A5 (21) +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; + + +// digital pins +// D0...D13, D18, D19 + +// User led and button +#define LED_BUILTIN (22) +#define BTN_BUILTIN (23) + +// determines the address of the port by the board pin number to which this pin belongs on the MCU +GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber); +// determines the pin address inside the port by the board pin number +HAL_PinsTypeDef digitalPinToBitMask(uint32_t digPinNumber); +// оtotal number of pins available for initialization +uint16_t pinCommonQty(void); + +// ADC +// determines the ADC channel number by the board pin number +uint32_t analogInputToChannelNumber(uint32_t PinNumber); + +// PWM +bool digitalPinHasPWM(uint8_t p); +// determines which timer the pin belongs to +TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber); +// determines which timer channel the pin belongs to +HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber); + +// SPI +#define PIN_SPI_SS (10) +#define PIN_SPI_MOSI (11) +#define PIN_SPI_MISO (12) +#define PIN_SPI_SCK (13) +static const uint8_t SS = PIN_SPI_SS; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; +// config SEL_NSS1 to replace D10 to different controller pin, +// because pin 1.3 which is D10 by default is needed to spi +inline void blockSpiPin(void) +{ + spiNssPinIsBlocked = true; +} +inline void unblockSpiPin(void) +{ + spiNssPinIsBlocked = false; +} + +// I2C +#define PIN_WIRE_SDA (18) +#define PIN_WIRE_SCL (19) +#define I2C_NUM (1) // i2c number 0 or 1 +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; +// available frequencies +#define WIRE_FREQ_100K 100000 +#define WIRE_FREQ_400K 400000 +#define WIRE_FREQ_1000K 1000000 + +// interrupts +#define EXTERNAL_NUM_INTERRUPTS 7 +// determines the board pin number by interrupt number +uint32_t interruptToDigitalPin(uint8_t interruptNum); +// determines interrupt number by the board pin number +int8_t digitalPinToInterrupt(uint32_t digPinNumber); +// determines gpio interrupt line by interrupt number +uint32_t interruptToGpioIntLine(uint8_t interruptNum); +// determines interrupt number by the gpio interrupt line +int8_t gpioIntLineToInterrupt(uint32_t gpioIntLine); +// determines gpio interrupt mux by interrupt number +uint32_t interruptToGpioIntMux(uint8_t interruptNum); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/variants/standart/variant.c b/variants/standart/variant.c new file mode 100644 index 0000000..6b9fe62 --- /dev/null +++ b/variants/standart/variant.c @@ -0,0 +1,211 @@ +/** + ******************************************************************************* + * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. + * All rights reserved. + * + * This software component is licensed by WCH under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +#include "pins_arduino.h" +#include "mik32_hal_adc.h" + +#ifdef __cplusplus +extern "C" { +#endif +void ErrorMsgHandler(const char * msg); +#ifdef __cplusplus +} +#endif + +bool spiNssPinIsBlocked = false; + +// list of pin numbers from both ports with pins inside the port +const HAL_PinsTypeDef digitalPinToGpioPinArray[] = +{ + GPIO_PIN_5, // D0 + GPIO_PIN_6, // D1 + GPIO_PIN_10,// D2 + GPIO_PIN_0, // D3 + GPIO_PIN_8, // D4 + GPIO_PIN_1, // D5 + GPIO_PIN_2, // D6 + GPIO_PIN_8, // D7 + GPIO_PIN_9, // D8 + GPIO_PIN_3, // D9 + GPIO_PIN_3, // D10 + GPIO_PIN_1, // D11 + GPIO_PIN_0, // D12 + GPIO_PIN_2, // D13 + GPIO_PIN_5, // D14/A0 + GPIO_PIN_7, // D15/A1 + GPIO_PIN_4, // D16/A2 + GPIO_PIN_7, // D17/A3 + GPIO_PIN_12,// D18 + GPIO_PIN_13,// D19 + GPIO_PIN_9, // A4 (board pin 20) + GPIO_PIN_9, // A5 (board pin 21) + GPIO_PIN_7, // LED(pin 22) + GPIO_PIN_6 // BTN(pin 23) +}; + +// etermines the address of the port by the board pin number to which this pin belongs on the MCU +GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber) +{ + GPIO_TypeDef* gpioNum = 0; + // port 0 - board pins 0...6, 9, 16(A2), 17(A3), 20(A4), 21(A5) + if ((digPinNumber >= 0 && digPinNumber <= 6) || digPinNumber == 9 || digPinNumber == 16 + || digPinNumber == 17 || digPinNumber == 20 || digPinNumber == 21) // 12 pieces + gpioNum = GPIO_0; + // port 1 - board pins 7, 8, 10...13, 14(А0), 15(А1), 18,19 + else if (digPinNumber == 7 || digPinNumber == 8 || (digPinNumber >= 10 && digPinNumber <= 15) + || digPinNumber == 18 || digPinNumber == 19) // 10 pieces + gpioNum = GPIO_1; + // port 2 - led and button + else if (digPinNumber == LED_BUILTIN || digPinNumber == BTN_BUILTIN) + gpioNum = GPIO_2; + + return gpioNum; +} + +// determines the pin address inside the port by the board pin number +HAL_PinsTypeDef digitalPinToBitMask(uint32_t digPinNumber) +{ + if (digPinNumber < pinCommonQty()) + { + HAL_PinsTypeDef mask; + // if spi is on default pin 1.3 is needed for spi, D10 is replaced to pin 1.4 + if (spiNssPinIsBlocked && (digPinNumber == 10)) + mask = GPIO_PIN_4; + else + mask = digitalPinToGpioPinArray[digPinNumber]; + return mask; + } + else + return NC; +} + +uint16_t pinCommonQty(void) +{ + return (uint16_t)(sizeof(digitalPinToGpioPinArray)/sizeof(digitalPinToGpioPinArray[0])); +} + +// ---------------------- АЦП ---------------------- // +// determines the ADC channel number by the board pin number +uint32_t analogInputToChannelNumber(uint32_t PinNumber) +{ + uint32_t adcChannel = 0; + switch (PinNumber) + { + case PIN_A0: + adcChannel = ADC_CHANNEL0; + break; + case PIN_A1: + adcChannel = ADC_CHANNEL1; + break; + case PIN_A2: + adcChannel = ADC_CHANNEL3; + break; + case PIN_A3: + adcChannel = ADC_CHANNEL4; + break; + case PIN_A4: + case PIN_A5: + adcChannel = ADC_CHANNEL5; + break; + default: + adcChannel = NC; + } + return adcChannel; +} + +// ---------------------- PWM ---------------------- // +bool digitalPinHasPWM(uint8_t p) +{ + bool ret = false; + // if spi is in use D10 cannot work as pwm + if (spiNssPinIsBlocked && (p == 10)) + ret = false; + else if ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11) + ret = true; + return ret; +} + +// function is used only if digitalPinHasPWM() is true +TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber) +{ + TIMER32_TypeDef* timerNum = NULL; + + // timer 1 + if (digPinNumber == 3 || digPinNumber == 5 || digPinNumber == 6 || digPinNumber == 9) + timerNum = TIMER32_1; + // timer 2 + else if (digPinNumber == 10 || digPinNumber == 11) + timerNum = TIMER32_2; + + return timerNum; +} + +// function is used only if digitalPinHasPWM() is true +HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber) +{ + HAL_TIMER32_CHANNEL_IndexTypeDef channel = 0; + if (digPinNumber == 3) channel = TIMER32_CHANNEL_0; + else if (digPinNumber == 5 || digPinNumber == 11) channel = TIMER32_CHANNEL_1; + else if (digPinNumber == 6) channel = TIMER32_CHANNEL_2; + else if (digPinNumber == 9 || digPinNumber == 10) channel = TIMER32_CHANNEL_3; + return channel; +} + +// ---------------------- interrupts ---------------------- // +// interrupt table +// index = interrupt number. In each row {digitalPinNumber, IntLineValue, IntMuxValue} +const uint8_t interruptInfo[EXTERNAL_NUM_INTERRUPTS][3] = +{ + { 2, GPIO_LINE_2, GPIO_MUX_LINE_2_PORT0_10}, // INT0 + { 3, GPIO_LINE_0, GPIO_MUX_LINE_0_PORT0_0}, // INT1 + { 4, GPIO_LINE_4, GPIO_MUX_LINE_4_PORT0_8}, // INT2 + { 5, GPIO_LINE_1, GPIO_MUX_LINE_1_PORT0_1}, // INT3 + { 8, GPIO_LINE_5, GPIO_MUX_LINE_5_PORT1_9}, // INT4 + { 9, GPIO_LINE_3, GPIO_MUX_LINE_3_PORT0_3}, // INT5 + {BTN_BUILTIN, GPIO_LINE_6, GPIO_MUX_LINE_6_PORT2_6}, // INT6 (button) +}; + +uint32_t interruptToDigitalPin(uint8_t interruptNum) +{ + return interruptInfo[interruptNum][0]; +} + +uint32_t interruptToGpioIntLine(uint8_t interruptNum) +{ + return (uint32_t)interruptInfo[interruptNum][1]; +} + +uint32_t interruptToGpioIntMux(uint8_t interruptNum) +{ + return (uint32_t)interruptInfo[interruptNum][2]; +} + +int8_t gpioIntLineToInterrupt(uint32_t gpioIntLine) +{ + for (uint8_t i = 0; i < EXTERNAL_NUM_INTERRUPTS; i++) + { + if (interruptInfo[i][1] == gpioIntLine) + return i; + } + return NOT_AN_INTERRUPT; +} + +int8_t digitalPinToInterrupt(uint32_t digPinNumber) +{ + for (uint8_t i = 0; i < EXTERNAL_NUM_INTERRUPTS; i++) + { + if (interruptInfo[i][0] == digPinNumber) + return i; + } + return NOT_AN_INTERRUPT; +} \ No newline at end of file