From 61e63ebeb749db95dd02adf4dda1823e620f4738 Mon Sep 17 00:00:00 2001 From: Katya Date: Wed, 8 Nov 2023 17:01:16 +0300 Subject: [PATCH] a --- .gitignore | 19 + 3xThermo1xHT/FirmwareConverter/Crc32.NET.dll | Bin 0 -> 7680 bytes .../idiBusFmwPrepTool.deps.json | 98 ++++ .../FirmwareConverter/idiBusFmwPrepTool.dll | Bin 0 -> 15872 bytes .../FirmwareConverter/idiBusFmwPrepTool.exe | Bin 0 -> 174592 bytes .../FirmwareConverter/idiBusFmwPrepTool.pdb | Bin 0 -> 13904 bytes .../idiBusFmwPrepTool.runtimeconfig.dev.json | 8 + .../idiBusFmwPrepTool.runtimeconfig.json | 9 + 3xThermo1xHT/README.md | 7 + 3xThermo1xHT/bootloaderFiles/AES progress.txt | 31 + 3xThermo1xHT/bootloaderFiles/FmwInfo.txt | 13 + 3xThermo1xHT/bootloaderFiles/README.md | 1 + .../idiBUS_bootloader/BootVersion.h | 7 + .../CustomHWDefines/m2560_defs.h | 17 + .../CustomHWDefines/m328pb_defs.h | 19 + .../idiBUS_bootloader/SysCommon/AES.c | 249 ++++++++ .../idiBUS_bootloader/SysCommon/AES.h | 36 ++ .../idiBUS_bootloader/SysCommon/CRCs.c | 109 ++++ .../idiBUS_bootloader/SysCommon/CRCs.h | 19 + .../idiBUS_bootloader/SysCommon/System.c | 13 + .../idiBUS_bootloader/SysCommon/System.h | 27 + .../idiBUS_bootloader/bootloader/boot.h | 29 + .../bootloader/bootFunctions.c | 242 ++++++++ .../bootloader/bootFunctions.h | 31 + .../idiBUS_bootloader_2560.componentinfo.xml | 86 +++ .../idiBUS_bootloader_2560.cproj | 373 ++++++++++++ .../idiBUS_bootloader_328.componentinfo.xml | 86 +++ .../idiBUS_bootloader_328.cproj | 385 ++++++++++++ .../idiBus/Common/IDIBUS_DEFS.h | 456 +++++++++++++++ .../idiBUS_bootloader/idiBus/Common/MEMORY.h | 33 ++ .../idiBus/IDIBUS_BOOTLOADER_DEFS.h | 34 ++ .../idiBUS_bootloader/idiBus/IDIBUS_IMPL.c | 120 ++++ .../idiBUS_bootloader/idiBus/IDIBUS_IMPL.h | 40 ++ .../idiBUS_bootloader/idiBus/RSLink.c | 116 ++++ .../idiBUS_bootloader/idiBus/RSLink.h | 40 ++ .../idiBUS_bootloader/idiBus/USART1.c | 108 ++++ .../idiBUS_bootloader/idiBus/USART1.h | 56 ++ .../idiBUS_bootloader/idiBus/USART_COM.h | 41 ++ .../bootloaderFiles/idiBUS_bootloader/main.c | 79 +++ .../idiBUS_bootloader_2560.atsln | 25 + .../idiBUS_bootloader_328.atsln | 25 + .../idiBusCoreFiles/CommonHW/EEPROM_Fast.c | 68 +++ .../idiBusCoreFiles/CommonHW/EEPROM_Fast.h | 16 + .../idiBusCoreFiles/CommonHW/SYSTEM.c | 35 ++ .../idiBusCoreFiles/CommonHW/SYSTEM.h | 30 + .../idiBusCoreFiles/CommonHW/SYSTEMCustom.c | 32 + .../idiBusCoreFiles/CommonHW/SYSTEMCustom.h | 15 + .../idiBusCoreFiles/CommonHW/USART0.c | 135 +++++ .../idiBusCoreFiles/CommonHW/USART0.h | 35 ++ .../idiBusCoreFiles/CommonHW/USART1.c | 163 ++++++ .../idiBusCoreFiles/CommonHW/USART1.h | 39 ++ .../idiBusCoreFiles/CommonHW/USART_COM.h | 71 +++ .../idiBusCoreFiles/CommonHW/m2560_defs.h | 17 + .../idiBusCoreFiles/CommonHW/m328pb_defs.h | 19 + .../IdiBus/Common/IDIBUS_DEFS.h | 456 +++++++++++++++ .../idiBusCoreFiles/IdiBus/Common/MEMORY.h | 33 ++ .../idiBusCoreFiles/IdiBus/IDIBUS_IMPL.c | 435 ++++++++++++++ .../idiBusCoreFiles/IdiBus/IDIBUS_IMPL.h | 98 ++++ .../idiBusCoreFiles/IdiBus/MODBUS_CRC.c | 71 +++ .../idiBusCoreFiles/IdiBus/MODBUS_CRC.h | 14 + 3xThermo1xHT/idiBusCoreFiles/IdiBus/RSLink.c | 329 +++++++++++ 3xThermo1xHT/idiBusCoreFiles/IdiBus/RSLink.h | 43 ++ .../idiBusCoreFiles/IdiCommon_2560.atsln | 22 + .../IdiCommon_2560.componentinfo.xml | 86 +++ .../idiBusCoreFiles/IdiCommon_2560.cproj | 216 +++++++ .../idiBusCoreFiles/IdiCommon_328pb.atsln | 22 + .../IdiCommon_328pb.componentinfo.xml | 86 +++ .../idiBusCoreFiles/IdiCommon_328pb.cproj | 235 ++++++++ 3xThermo1xHT/idiBusCoreFiles/README.md | 1 + 3xThermo1xHT/idiBusFiles/IDIBUS_IMPL_Custom.c | 118 ++++ 3xThermo1xHT/idiBusFiles/IDIBUS_IMPL_Custom.h | 35 ++ 3xThermo1xHT/idiBusFiles/RSLinkCustom.c | 76 +++ 3xThermo1xHT/idiBusFiles/RSLinkCustom.h | 32 + 3xThermo1xHT/idiBus_Ext.atsln | 28 + .../idiBus_Ext_3xThermo1HT.componentinfo.xml | 86 +++ 3xThermo1xHT/idiBus_Ext_3xThermo1HT.cproj | 277 +++++++++ 3xThermo1xHT/main.c | 86 +++ 3xThermo1xHT/moduleFiles/EEMEM.h | 18 + 3xThermo1xHT/moduleFiles/MaxHandler.c | 62 ++ 3xThermo1xHT/moduleFiles/MaxHandler.h | 36 ++ 3xThermo1xHT/moduleFiles/SPI.c | 29 + 3xThermo1xHT/moduleFiles/SPI.h | 26 + 3xThermo1xHT/moduleFiles/USART0Custom.c | 33 ++ 3xThermo1xHT/moduleFiles/USART0Custom.h | 25 + 3xThermo1xHT/moduleFiles/software_SPI.c | 59 ++ 3xThermo1xHT/moduleFiles/software_SPI.h | 31 + 3xThermo1xHT/personalizationFiles/config.h | 67 +++ 3xThermo1xHT/personalizationFiles/device.cfg | 9 + 3xThermo1xHT/personalizationFiles/keys.h | 7 + .../.vs/GccApplication1/v14/.atsuo | Bin 0 -> 64512 bytes GccApplication1/GccApplication1.atsln | 22 + .../GccApplication1/Debug/GccApplication1.eep | 1 + .../GccApplication1/Debug/GccApplication1.elf | Bin 0 -> 14984 bytes .../GccApplication1/Debug/GccApplication1.hex | 36 ++ .../GccApplication1/Debug/GccApplication1.lss | 385 ++++++++++++ .../GccApplication1/Debug/GccApplication1.map | 549 ++++++++++++++++++ .../Debug/GccApplication1.srec | 37 ++ .../GccApplication1/Debug/Makefile | 163 ++++++ GccApplication1/GccApplication1/Debug/delay.d | 39 ++ GccApplication1/GccApplication1/Debug/delay.o | Bin 0 -> 5980 bytes GccApplication1/GccApplication1/Debug/main.d | 65 +++ GccApplication1/GccApplication1/Debug/main.o | Bin 0 -> 6832 bytes .../GccApplication1/Debug/makedep.mk | 12 + GccApplication1/GccApplication1/Debug/spi.d | 65 +++ GccApplication1/GccApplication1/Debug/spi.o | Bin 0 -> 4444 bytes .../GccApplication1/Debug/usart0.d | 65 +++ .../GccApplication1/Debug/usart0.o | Bin 0 -> 4524 bytes .../GccApplication1.componentinfo.xml | 86 +++ .../GccApplication1/GccApplication1.cproj | 177 ++++++ GccApplication1/GccApplication1/delay.c | 80 +++ GccApplication1/GccApplication1/delay.h | 14 + GccApplication1/GccApplication1/main.c | 83 +++ GccApplication1/GccApplication1/main.h | 23 + GccApplication1/GccApplication1/spi.c | 32 + GccApplication1/GccApplication1/spi.h | 21 + GccApplication1/GccApplication1/usart0.c | 33 ++ GccApplication1/GccApplication1/usart0.h | 19 + 117 files changed, 9056 insertions(+) create mode 100644 .gitignore create mode 100644 3xThermo1xHT/FirmwareConverter/Crc32.NET.dll create mode 100644 3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.deps.json create mode 100644 3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.dll create mode 100644 3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.exe create mode 100644 3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.pdb create mode 100644 3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.runtimeconfig.dev.json create mode 100644 3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.runtimeconfig.json create mode 100644 3xThermo1xHT/README.md create mode 100644 3xThermo1xHT/bootloaderFiles/AES progress.txt create mode 100644 3xThermo1xHT/bootloaderFiles/FmwInfo.txt create mode 100644 3xThermo1xHT/bootloaderFiles/README.md create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/BootVersion.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/CustomHWDefines/m2560_defs.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/CustomHWDefines/m328pb_defs.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/AES.c create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/AES.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/CRCs.c create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/CRCs.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/System.c create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/System.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/boot.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/bootFunctions.c create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/bootFunctions.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_2560.componentinfo.xml create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_2560.cproj create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_328.componentinfo.xml create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_328.cproj create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/Common/IDIBUS_DEFS.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/Common/MEMORY.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_BOOTLOADER_DEFS.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_IMPL.c create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_IMPL.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/RSLink.c create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/RSLink.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/USART1.c create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/USART1.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/USART_COM.h create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/main.c create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader_2560.atsln create mode 100644 3xThermo1xHT/bootloaderFiles/idiBUS_bootloader_328.atsln create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/EEPROM_Fast.c create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/EEPROM_Fast.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEM.c create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEM.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEMCustom.c create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEMCustom.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/USART0.c create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/USART0.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/USART1.c create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/USART1.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/USART_COM.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/m2560_defs.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/CommonHW/m328pb_defs.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiBus/Common/IDIBUS_DEFS.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiBus/Common/MEMORY.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiBus/IDIBUS_IMPL.c create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiBus/IDIBUS_IMPL.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiBus/MODBUS_CRC.c create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiBus/MODBUS_CRC.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiBus/RSLink.c create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiBus/RSLink.h create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.atsln create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.componentinfo.xml create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.cproj create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.atsln create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.componentinfo.xml create mode 100644 3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.cproj create mode 100644 3xThermo1xHT/idiBusCoreFiles/README.md create mode 100644 3xThermo1xHT/idiBusFiles/IDIBUS_IMPL_Custom.c create mode 100644 3xThermo1xHT/idiBusFiles/IDIBUS_IMPL_Custom.h create mode 100644 3xThermo1xHT/idiBusFiles/RSLinkCustom.c create mode 100644 3xThermo1xHT/idiBusFiles/RSLinkCustom.h create mode 100644 3xThermo1xHT/idiBus_Ext.atsln create mode 100644 3xThermo1xHT/idiBus_Ext_3xThermo1HT.componentinfo.xml create mode 100644 3xThermo1xHT/idiBus_Ext_3xThermo1HT.cproj create mode 100644 3xThermo1xHT/main.c create mode 100644 3xThermo1xHT/moduleFiles/EEMEM.h create mode 100644 3xThermo1xHT/moduleFiles/MaxHandler.c create mode 100644 3xThermo1xHT/moduleFiles/MaxHandler.h create mode 100644 3xThermo1xHT/moduleFiles/SPI.c create mode 100644 3xThermo1xHT/moduleFiles/SPI.h create mode 100644 3xThermo1xHT/moduleFiles/USART0Custom.c create mode 100644 3xThermo1xHT/moduleFiles/USART0Custom.h create mode 100644 3xThermo1xHT/moduleFiles/software_SPI.c create mode 100644 3xThermo1xHT/moduleFiles/software_SPI.h create mode 100644 3xThermo1xHT/personalizationFiles/config.h create mode 100644 3xThermo1xHT/personalizationFiles/device.cfg create mode 100644 3xThermo1xHT/personalizationFiles/keys.h create mode 100644 GccApplication1/.vs/GccApplication1/v14/.atsuo create mode 100644 GccApplication1/GccApplication1.atsln create mode 100644 GccApplication1/GccApplication1/Debug/GccApplication1.eep create mode 100644 GccApplication1/GccApplication1/Debug/GccApplication1.elf create mode 100644 GccApplication1/GccApplication1/Debug/GccApplication1.hex create mode 100644 GccApplication1/GccApplication1/Debug/GccApplication1.lss create mode 100644 GccApplication1/GccApplication1/Debug/GccApplication1.map create mode 100644 GccApplication1/GccApplication1/Debug/GccApplication1.srec create mode 100644 GccApplication1/GccApplication1/Debug/Makefile create mode 100644 GccApplication1/GccApplication1/Debug/delay.d create mode 100644 GccApplication1/GccApplication1/Debug/delay.o create mode 100644 GccApplication1/GccApplication1/Debug/main.d create mode 100644 GccApplication1/GccApplication1/Debug/main.o create mode 100644 GccApplication1/GccApplication1/Debug/makedep.mk create mode 100644 GccApplication1/GccApplication1/Debug/spi.d create mode 100644 GccApplication1/GccApplication1/Debug/spi.o create mode 100644 GccApplication1/GccApplication1/Debug/usart0.d create mode 100644 GccApplication1/GccApplication1/Debug/usart0.o create mode 100644 GccApplication1/GccApplication1/GccApplication1.componentinfo.xml create mode 100644 GccApplication1/GccApplication1/GccApplication1.cproj create mode 100644 GccApplication1/GccApplication1/delay.c create mode 100644 GccApplication1/GccApplication1/delay.h create mode 100644 GccApplication1/GccApplication1/main.c create mode 100644 GccApplication1/GccApplication1/main.h create mode 100644 GccApplication1/GccApplication1/spi.c create mode 100644 GccApplication1/GccApplication1/spi.h create mode 100644 GccApplication1/GccApplication1/usart0.c create mode 100644 GccApplication1/GccApplication1/usart0.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0677ca1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +3xThermo1xHT/bootloaderFiles/.vs +3xThermo1xHT/bootloaderFiles/Release +3xThermo1xHT/bootloaderFiles/Debug +3xThermo1xHT/bootloaderFiles/Cutter_Debug +3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/\[Build\] Release_2560 +3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/\[Build\] Release_328pb +3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/\[Build\] Debug_2560 +3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/\[Build\] Debug_328pb +3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/\[Build\] Cutter_2560 +3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/\[Build\] Cutter_328pb +3xThermo1xHT/idiBusCoreFiles/bin +3xThermo1xHT/idiBusCoreFiles/.vs +3xThermo1xHT/idiBusCoreFiles/\[Build\] Debug_328pb +3xThermo1xHT/idiBusCoreFiles/\[Build\] Debug_2560 +3xThermo1xHT/idiBusCoreFiles/\[Build\] Release_328pb +3xThermo1xHT/idiBusCoreFiles/\[Build\] Release_2560 +3xThermo1xHT/\[Build\] Release +3xThermo1xHT/\[Build\] Debug +3xThermo1xHT/.vs \ No newline at end of file diff --git a/3xThermo1xHT/FirmwareConverter/Crc32.NET.dll b/3xThermo1xHT/FirmwareConverter/Crc32.NET.dll new file mode 100644 index 0000000000000000000000000000000000000000..21213edf7850f963fef91b505282f632168fc46c GIT binary patch literal 7680 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 literal 0 HcmV?d00001 diff --git a/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.deps.json b/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.deps.json new file mode 100644 index 0000000..144a114 --- /dev/null +++ b/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.deps.json @@ -0,0 +1,98 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v3.1", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v3.1": { + "idiBusFmwPrepTool/1.0.0": { + "dependencies": { + "Crc32.NET": "1.2.0", + "System.Text.RegularExpressions": "4.3.1" + }, + "runtime": { + "idiBusFmwPrepTool.dll": {} + } + }, + "Crc32.NET/1.2.0": { + "dependencies": { + "NETStandard.Library": "2.0.0" + }, + "runtime": { + "lib/netstandard2.0/Crc32.NET.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.2.0.5" + } + } + }, + "Microsoft.NETCore.Platforms/1.1.1": {}, + "Microsoft.NETCore.Targets/1.1.3": {}, + "NETStandard.Library/2.0.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1" + } + }, + "System.Runtime/4.3.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3" + } + }, + "System.Text.RegularExpressions/4.3.1": { + "dependencies": { + "System.Runtime": "4.3.1" + } + } + } + }, + "libraries": { + "idiBusFmwPrepTool/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Crc32.NET/1.2.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-wNW/huzolu8MNKUnwCVKxjfAlCFpeI8AZVfF46iAWJ1+P6bTU1AZct7VAkDDEjgeeTJCVTkGZaD6jSd/fOiUkA==", + "path": "crc32.net/1.2.0", + "hashPath": "crc32.net.1.2.0.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/1.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-TMBuzAHpTenGbGgk0SMTwyEkyijY/Eae4ZGsFNYJvAr/LDn1ku3Etp3FPxChmDp5HHF3kzJuoaa08N0xjqAJfQ==", + "path": "microsoft.netcore.platforms/1.1.1", + "hashPath": "microsoft.netcore.platforms.1.1.1.nupkg.sha512" + }, + "Microsoft.NETCore.Targets/1.1.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==", + "path": "microsoft.netcore.targets/1.1.3", + "hashPath": "microsoft.netcore.targets.1.1.3.nupkg.sha512" + }, + "NETStandard.Library/2.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-7jnbRU+L08FXKMxqUflxEXtVymWvNOrS8yHgu9s6EM8Anr6T/wIX4nZ08j/u3Asz+tCufp3YVwFSEvFTPYmBPA==", + "path": "netstandard.library/2.0.0", + "hashPath": "netstandard.library.2.0.0.nupkg.sha512" + }, + "System.Runtime/4.3.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-abhfv1dTK6NXOmu4bgHIONxHyEqFjW8HwXPmpY9gmll+ix9UNo4XDcmzJn6oLooftxNssVHdJC1pGT9jkSynQg==", + "path": "system.runtime/4.3.1", + "hashPath": "system.runtime.4.3.1.nupkg.sha512" + }, + "System.Text.RegularExpressions/4.3.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-N0kNRrWe4+nXOWlpLT4LAY5brb8caNFlUuIRpraCVMDLYutKkol1aV079rQjLuSxKMJT2SpBQsYX9xbcTMmzwg==", + "path": "system.text.regularexpressions/4.3.1", + "hashPath": "system.text.regularexpressions.4.3.1.nupkg.sha512" + } + } +} \ No newline at end of file diff --git a/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.dll b/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.dll new file mode 100644 index 0000000000000000000000000000000000000000..103a293c844761afb6254f689312290112c2018e GIT binary patch literal 15872 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 literal 0 HcmV?d00001 diff --git a/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.exe b/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.exe new file mode 100644 index 0000000000000000000000000000000000000000..819d725bc4f5b99193c1949d97bd6cb1e4591573 GIT binary patch literal 174592 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
  • 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 literal 0 HcmV?d00001 diff --git a/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.pdb b/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.pdb new file mode 100644 index 0000000000000000000000000000000000000000..3b69feea8ad19d83a90d1f0fc9da360a2360357e GIT binary patch literal 13904 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 Qc${hu@y8D{`w@`;58H{kD*ylh literal 0 HcmV?d00001 diff --git a/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.runtimeconfig.dev.json b/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.runtimeconfig.dev.json new file mode 100644 index 0000000..0200e19 --- /dev/null +++ b/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.runtimeconfig.dev.json @@ -0,0 +1,8 @@ +{ + "runtimeOptions": { + "additionalProbingPaths": [ + "C:\\Users\\Stanislav\\.dotnet\\store\\|arch|\\|tfm|", + "C:\\Users\\Stanislav\\.nuget\\packages" + ] + } +} \ No newline at end of file diff --git a/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.runtimeconfig.json b/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.runtimeconfig.json new file mode 100644 index 0000000..bc456d7 --- /dev/null +++ b/3xThermo1xHT/FirmwareConverter/idiBusFmwPrepTool.runtimeconfig.json @@ -0,0 +1,9 @@ +{ + "runtimeOptions": { + "tfm": "netcoreapp3.1", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "3.1.0" + } + } +} \ No newline at end of file diff --git a/3xThermo1xHT/README.md b/3xThermo1xHT/README.md new file mode 100644 index 0000000..0c033e6 --- /dev/null +++ b/3xThermo1xHT/README.md @@ -0,0 +1,7 @@ +This is template repo. + +Auto generated description: + +idiBus_3xThermo1xHT + +idiBus_3xThermo1xHT \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/AES progress.txt b/3xThermo1xHT/bootloaderFiles/AES progress.txt new file mode 100644 index 0000000..81b817b --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/AES progress.txt @@ -0,0 +1,31 @@ +Initial (~4100 byte): +10В 065,94 Вµs 16 byte +~256 000 256 byte +0.256 s + +First pass optimization (~1kb 3004 byte): +10В 401,88 Вµs 16 byte + +Second pass optimization (134b 2870 byte): +12В 469,19 Вµs 16 byte + +Third pass (34b 2836 byte) +>14 000,00 Вµs 16 byte + +Fourth pass (100b 2736 byte) +14В 429,19 Вµs 16 byte + +Removeing other keylength excepth 256 (104b 2632byte) +14В 159,63 Вµs 16 byte + +Removeing other keylength excepth 256 (80b 2552byte) +14В 088,69 Вµs 16 byte + +AES_INV_SBOX single dimension (36b 2516 byte) +9В 543,06 Вµs 16 byte (WTF???) + +More work with scissors(88b 2428 byte) +~9В 971,44 Вµs 16 byte + +AES Key expansion to uint8_t (194b 2234 byte) +9В 463,94 Вµs 16 byte \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/FmwInfo.txt b/3xThermo1xHT/bootloaderFiles/FmwInfo.txt new file mode 100644 index 0000000..3509a9f --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/FmwInfo.txt @@ -0,0 +1,13 @@ +FmwInfo + +[Block 1] +FmwHash: 4 +FmwSizeInPages: 2 +ModuleType: 3 +HWRevision: 2 +Dummy: 5 + +[Block 2] +SWVersion: 2 +Dummy: 10 +InfoHash: 4 \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/README.md b/3xThermo1xHT/bootloaderFiles/README.md new file mode 100644 index 0000000..f361325 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/README.md @@ -0,0 +1 @@ +Do not use this repository separetly from idiBusSlaveTemplate!!! \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/BootVersion.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/BootVersion.h new file mode 100644 index 0000000..45c0b53 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/BootVersion.h @@ -0,0 +1,7 @@ +#ifndef BOOTVERSION_H_ +#define BOOTVERSION_H_ + +#define BOOT_VERSION_MAJOR 0 +#define BOOT_VERSION_MINOR 2 + +#endif /* BOOTVERSION_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/CustomHWDefines/m2560_defs.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/CustomHWDefines/m2560_defs.h new file mode 100644 index 0000000..7dd1406 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/CustomHWDefines/m2560_defs.h @@ -0,0 +1,17 @@ + // USARTCUSTOM (FOR 2560) + #define USART1_TX_DDR DDRD + #define USART1_TX_PORT PORTD + #define USART1_TX_BIT 3 + #define USART1_RX_DDR DDRD + #define USART1_RX_PORT PORTD + #define USART1_RX_BIT 2 + #define USART1_DRE_DDR DDRD + #define USART1_DRE_PORT PORTD + #define USART1_DRE_BIT 4 + // USARTCUSTOM (FOR 2560) + #define USART0_TX_DDR DDRE + #define USART0_TX_PORT PORTE + #define USART0_TX_BIT 1 + #define USART0_RX_DDR DDRE + #define USART0_RX_PORT PORTE + #define USART0_RX_BIT 0 \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/CustomHWDefines/m328pb_defs.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/CustomHWDefines/m328pb_defs.h new file mode 100644 index 0000000..9cf6a51 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/CustomHWDefines/m328pb_defs.h @@ -0,0 +1,19 @@ + //USART CUSTOM (FOR 328pb) + #define USART0_TX_DDR DDRD + #define USART0_TX_PORT PORTD + #define USART0_TX_BIT 1 + #define USART0_RX_DDR DDRD + #define USART0_RX_PORT PORTD + #define USART0_RX_BIT 0 + + //USART CUSTOM (FOR 328pb) + #define USART1_TX_DDR DDRB + #define USART1_TX_PORT PORTB + #define USART1_TX_BIT 3 + #define USART1_RX_DDR DDRB + #define USART1_RX_PORT PORTB + #define USART1_RX_BIT 4 + #define USART1_DRE_DDR DDRB + #define USART1_DRE_PORT PORTB + #define USART1_DRE_BIT 5 + diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/AES.c b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/AES.c new file mode 100644 index 0000000..793afa7 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/AES.c @@ -0,0 +1,249 @@ +//############################################################################################################################################################################################################# +#include "AES.h" +//============================================================================================================================================================================================================= +const uint8_t AES_INV_SBOX[256] PROGMEM= { + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB , + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB , + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E , + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25 , + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92 , + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84 , + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06 , + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B , + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73 , + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E , + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B , + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4 , + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F , + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF , + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61 , + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +//Static functions + +inline uint8_t AES_RotWord(uint8_t *Word); +uint8_t AES_SubWord (uint8_t Word); +inline void AES_KeyExpansion(uint8_t *AES_KEY, uint8_t *w); + +//uint8_t AES_xTime(uint8_t Value); +void AES_AddRoundKey (uint8_t *State, uint8_t *Key); + +void AES_InvSubBytes(uint8_t *state); +void AES_InvShiftRows(uint8_t *state); +inline void AES_InvMixColumns(uint8_t *state); + +//void AES_ApplyIV(uint8_t *state, uint8_t *IV); +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +inline uint8_t AES_RotWord(uint8_t *Word){ + Word[0+4] = Word[1]; + Word[1+4] = Word[2]; + Word[2+4] = Word[3]; + Word[3+4] = Word[0]; + return Word[1]; +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t AES_SubWord (uint8_t Word) +{ + //for (uint8_t i = 0; i < 256; i++){ //FIND BETTER SOLUTION (with out using precomputed values) + // if (flash_read_byte((AES_INV_SBOX),i) == Word) + // return i; + //} + //return 0; + uint8_t j,i = 0; + do { + if (flash_read_byte((AES_INV_SBOX),i) == Word) + j = i; + i++; + } while (i != 0); + return j; +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +const uint8_t Rcon[7] PROGMEM= { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40};//, 0x80};//, 0x1B, 0x36 }; + +inline void AES_KeyExpansion(uint8_t *AES_KEY, uint8_t *w) +{ + uint8_t KeyTmp; + uint8_t I; + + //for (I = 0; I < AES_NK_256BIT*4; I++) + //{ + // w[I] = pgm_read_byte(&(AES_KEY[I])); + //} + _memcopy(AES_KEY,w,AES_NK_256BIT*4); + + for (I = AES_NK_256BIT*4; I < (uint8_t)(AES_NB*(uint8_t)(AES_NR_256BIT+1U)*4); I++) + { + KeyTmp = w[I-4]; + + if ((I & 0b11100) == 0 ) { + if ((I & 0b11) == 0 ) { + KeyTmp = AES_RotWord(&w[I-4]); + KeyTmp = AES_SubWord(KeyTmp); + //KeyTmp = KeyTmp ^ (1<<(I>>5)); + KeyTmp = KeyTmp ^ flash_read_byte((Rcon),(I>>5)-1); + } else + KeyTmp = AES_SubWord(w[I]); + } + else if ( (I & 0b11100) == 16 ) + KeyTmp = AES_SubWord(w[I-4]); + + w[I] = w[I-(AES_NK_256BIT*4)] ^ KeyTmp; + } +} +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +//uint8_t AES_xTime(uint8_t Value) { return ( (Value & 0x80) ? ((uint8_t)(Value<<1)^0x1B) : (uint8_t)(Value<<1) ); } +// +//#define AES_MULTIPLY_02(X) AES_xTime((X)) +//#define AES_MULTIPLY_03(X) ( (X) ^ AES_xTime((X)) ) +//#define AES_MULTIPLY_09(X) ( (X) ^ AES_xTime(AES_xTime(AES_xTime((X)))) ) +//#define AES_MULTIPLY_0B(X) ( (X) ^ AES_xTime((X)) ^ AES_xTime(AES_xTime(AES_xTime((X)))) ) +//#define AES_MULTIPLY_0E(X) ( AES_xTime((X)) ^ AES_xTime(AES_xTime((X))) ^ AES_xTime(AES_xTime(AES_xTime((X)))) ) +//#define AES_MULTIPLY_0D(X) ( (X) ^ AES_xTime(AES_xTime((X))) ^ AES_xTime(AES_xTime(AES_xTime((X)))) ) +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//static uint8_t rstate[4*AES_NB]; + +#define GF28_MUL2(a) { asm ("lsl %0 \n brcc .+2 \n eor %0, %1 \n" : "=r" (a) : "r" (c0x1b), "0" (a)); } +//#define GF28_MUL2(a) { if (a&0x80) { a = (a<<1) ^ 0x1b; } else { a <<= 1; } } +//#define GF28_MUL2(a) {a=AES_xTime(a);} + +inline void AES_InvMixColumns(uint8_t *state) +{ + //for (uint8_t i = 0; i<16; i++) + // rstate[i]=state[i]; + //_memcopy(state,rstate,16); + + const uint8_t c0x1b = 0x1b; + uint8_t i, a0, a1, a2, a3, sum, b, c, d, e; + uint8_t* ptr = state; + for(i = 0; i < 16; i+=4) //https://github.com/kildom/AVR-AES/blob/master/aes.c I don't fully understand this, but it works really fast + { + a0 = ptr[0]; + a1 = ptr[1]; + a2 = ptr[2]; + a3 = ptr[3]; + sum = a0 ^ a1 ^ a2 ^ a3; + c = sum; GF28_MUL2(c); + d = c ^ a0 ^ a2; GF28_MUL2(d); GF28_MUL2(d); + d ^= sum; + e = c ^ a1 ^ a3; GF28_MUL2(e); GF28_MUL2(e); + e ^= sum; + b = a0^a1; GF28_MUL2(b); + *ptr++ = d ^ a0 ^ b; + b = a1^a2; GF28_MUL2(b); + *ptr++ = e ^ a1 ^ b; + b = a2^a3; GF28_MUL2(b); + *ptr++ = d ^ a2 ^ b; + b = a3^a0; GF28_MUL2(b); + *ptr++ = e ^ a3 ^ b; + } + + //for (uint8_t i = 0; i < 16; i++){ + // state[i] = AES_MULTIPLY_0E(rstate[(i&0xFC)+((i+0)&0b11)]) + // ^ AES_MULTIPLY_0B(rstate[(i&0xFC)+((i+1)&0b11)]) + // ^ AES_MULTIPLY_0D(rstate[(i&0xFC)+((i+2)&0b11)]) + // ^ AES_MULTIPLY_09(rstate[(i&0xFC)+((i+3)&0b11)]); + //} +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void AES_AddRoundKey (uint8_t *State, uint8_t *_key) +{ + for (uint8_t i = 0; i < 16; i++) + State[i] ^= (_key[i]); +} +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +void AES_InvShiftRows(uint8_t *state) +{ + uint8_t ByteTmp1; + uint8_t ByteTmp2; + + //Do not loop!!! Otherwise bad performance + ByteTmp1 = state[13]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = state[1]; + state[1] = ByteTmp1; + + ByteTmp1 = state[14]; + ByteTmp2 = state[10]; + state[14] = state[6]; + state[10] = state[2]; + state[6] = ByteTmp1; + state[2] = ByteTmp2; + + ByteTmp1 = state[3]; + state[3] = state[7]; + state[7] = state[11]; + state[11] = state[15]; + state[15] = ByteTmp1; +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void AES_InvSubBytes(uint8_t *state) +{ + for (uint8_t i = 0; i < 16; i++) + state[i] = flash_read_byte((AES_INV_SBOX),state[i]); +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +static uint8_t NextIV[16]; + +void AES_InvCipher(uint8_t *IN, uint8_t *w, uint8_t *IV) +{ + uint8_t *state = IN; + + _memcopy(IN,NextIV,16); + + AES_AddRoundKey(state, &w[AES_NR_256BIT*AES_NB*4]); + for (uint8_t I = (uint8_t)(AES_NR_256BIT-1); I > 0; I--) + { + AES_InvShiftRows(state); + AES_InvSubBytes(state); + AES_AddRoundKey(state, &w[I<<4]); + AES_InvMixColumns(state); + } + AES_InvShiftRows(state); + AES_InvSubBytes(state); + AES_AddRoundKey(state, &w[0]); + + AES_AddRoundKey(state, IV); //XOR output with IV + + _memcopy(NextIV,IV,16); +} +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +uint8_t w[(uint8_t)(AES_NB * (uint8_t)(AES_NR_256BIT+1U))*4]; + +uint8_t IVstored[16]; + +void AES_Decrypt(uint8_t *InpData, uint16_t InpDataLength) +{ + //if (KeyLength != AES_256) return; //Only AES CBC 256 is supported + if ( (InpDataLength & 0b1111) != 0 ) { return; } + + uint16_t DataPos = 0; + while ( InpDataLength > 0 ) + { + AES_InvCipher(&InpData[DataPos], w, IVstored); + DataPos = (uint16_t)(DataPos + AES_BLOCK_SIZE); + InpDataLength = (uint16_t)(InpDataLength - AES_BLOCK_SIZE); + } +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void AES_PrepareKeys(uint8_t *Key, uint8_t *IV){ + AES_KeyExpansion(Key, w); + //AES_Copy(IV,IVstored); + //for (uint8_t i = 0; i < 16; i++){ + // IVstored[i] = pgm_read_byte(&(IV[i])); + //} + _memcopy(IV,IVstored,16); +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/AES.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/AES.h new file mode 100644 index 0000000..4b909f0 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/AES.h @@ -0,0 +1,36 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_AES_H_ +#define _INC_AES_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include +//#include +//#include +#include "SYSTEM.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define AES_NB 4U + +#define AES_NK_256BIT 8U + +#define AES_NR_256BIT 14U +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define AES_KEY_AES256_SIZE 32U + +#define AES_BLOCK_SIZE 16U +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +/* +enum AES_CIPHER_KEY_LENGTH { + AES_128 = 0x00, + AES_192, //UNSUPPORTED + AES_256 + }; +*/ +//ONLY AES256 SUPPORTED!!! +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void AES_InvCipher(uint8_t *IN, uint8_t *w, uint8_t *IV); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void AES_Decrypt(uint8_t *InpData, uint16_t InpDataLength); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void AES_PrepareKeys(uint8_t *Key, uint8_t *IV); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif //_INC_AES_H_ +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/CRCs.c b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/CRCs.c new file mode 100644 index 0000000..a249319 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/CRCs.c @@ -0,0 +1,109 @@ +#include "CRCs.h" + +uint16_t CRC16(uint8_t *data, uint16_t length) +{ + uint16_t crc=0xFFFF; + + for (uint16_t Mp=0; Mp>=1; + if (tmp != 0) crc^=0xA001; + } + } + return crc; +} + +#ifdef _FAT_CRC_ + +const uint32_t crc32Lookup[256] PROGMEM = +{ 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3, + 0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91, + 0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7, + 0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5, + 0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B, + 0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59, + 0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F, + 0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D, + 0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433, + 0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01, + 0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457, + 0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65, + 0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB, + 0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9, + 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F, + 0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD, + 0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683, + 0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1, + 0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7, + 0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5, + 0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B, + 0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79, + 0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F, + 0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D, + 0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,0x72076785,0x05005713, + 0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21, + 0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777, + 0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45, + 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB, + 0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9, + 0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF, + 0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D +}; + +#ifdef _LONG_ADDR_SPACE_ +uint32_t CRC32(uint8_t* data, uint32_t length) +#else +//uint32_t CRC32(uint8_t* data, uint16_t length) +#endif +{ + uint32_t crc = (~(0)); + + #ifdef _LONG_ADDR_SPACE_ + uint32_t flashAddr = 0; + #else + //uint16_t flashAddr = 0; + #endif + + uint8_t offset; + + while (length--) + { + if (data != NULL) offset = ((uint8_t)crc) ^ *data++; + else offset = ((uint8_t)crc) ^ pgm_read_byte_far(flashAddr++); + + crc = (crc >> 8) ^ pgm_read_dword_far(pgm_get_far_address(crc32Lookup) + ((uint16_t)offset<<2)); + } + + return ~crc; // same as crc ^ 0xFFFFFFFF +} + + +#else + +uint32_t CRC32(uint8_t* data, uint16_t length) +{ + #define Polynomial 0xEDB88320 + uint32_t crc = 0xFFFFFFFF; // same as previousCrc32 ^ 0xFFFFFFFF + uint16_t flashAddr = 0; + + while (length--) + { + if (data != NULL) crc ^= *data++; //Check data pointer + else crc ^= pgm_read_byte(flashAddr++); //Check flash memory + + for (uint8_t j = 0; j < 8; j++) + { + uint8_t lowestBit = crc & 1; + crc >>= 1; + if (lowestBit) crc ^= Polynomial; + } + } + + return ~crc; // same as crc ^ 0xFFFFFFFF +} + +#endif diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/CRCs.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/CRCs.h new file mode 100644 index 0000000..0a420f1 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/CRCs.h @@ -0,0 +1,19 @@ +#ifndef CRCS_H_ +#define CRCS_H_ + +#include "config.h" + +#include +#include + +#include + +uint16_t CRC16(uint8_t *data, uint16_t length); + +#ifdef _LONG_ADDR_SPACE_ +uint32_t CRC32(uint8_t* data, uint32_t length); +#else +uint32_t CRC32(uint8_t* data, uint16_t length); +#endif + +#endif /* CRCS_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/System.c b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/System.c new file mode 100644 index 0000000..74c382a --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/System.c @@ -0,0 +1,13 @@ +#include "System.h" + +void _memcopy(volatile uint8_t *src,volatile uint8_t *dest, uint16_t size) { + for (uint16_t pos = 0; pos < size; pos++){ + dest[pos] = src[pos]; + } +} + +void System_SWReboot(){ + cli(); + wdt_enable(WDTO_15MS); + while(1); //Dumb reset +} diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/System.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/System.h new file mode 100644 index 0000000..0df9500 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/SysCommon/System.h @@ -0,0 +1,27 @@ +#ifndef SYSTEM_H_ +#define SYSTEM_H_ + +#include +#include "config.h" +#include +#include +#include +#include + +#ifdef _LONG_ADDR_SPACE_ + #define flash_read_byte(x,y) pgm_read_byte_far(pgm_get_far_address(x)+y) + #define flash_read_word(x,y) pgm_read_word_far(pgm_get_far_address(x)+y) + #define flash_read_dword(x,y) pgm_read_dword_far(pgm_get_far_address(x)+y) +#else + #define flash_read_byte(x,y) pgm_read_byte((uint16_t)(&x)+y) + #define flash_read_word(x,y) pgm_read_word((uint16_t)(&x)+y) + #define flash_read_dword(x,y) pgm_read_dword((uint16_t)(&x)+y) +#endif + +//#define NULL 0 + +void _memcopy(volatile uint8_t *src,volatile uint8_t *dest, uint16_t size); +void System_SWReboot(); + + +#endif /* SYSTEM_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/boot.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/boot.h new file mode 100644 index 0000000..93d78e8 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/boot.h @@ -0,0 +1,29 @@ +#ifndef BOOT_H_ +#define BOOT_H_ + +typedef struct { + uint8_t Status; + uint8_t Reason; + int16_t BlockNumber; + } BOOTLOADER_INFO; + +#define FMW_INFO_SIZE 32 + +typedef struct { + //[BLOCK 1] + uint16_t FmwHash[2]; //CRC32 + uint16_t FmwSizeInPages; + uint8_t ModuleType[3]; + uint8_t HwRevision[2]; + uint8_t Reserved1[5]; + //[BLOCK 2] + uint16_t SwVersion; //uint8_t[2] + uint8_t Reserved2[10]; + uint32_t InfoHash; + } FMW_INFO; + +volatile uint8_t AES_DISABLED; //Bootloader AES Decription disabled flag (if non-zero AES is disabled) +BOOTLOADER_INFO BootloaderInfo;// = {.Status = 0, .Reason = 0, .BlockNumber = -1}; +FMW_INFO FmwInfo; + +#endif /* BOOT_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/bootFunctions.c b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/bootFunctions.c new file mode 100644 index 0000000..7b49af0 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/bootFunctions.c @@ -0,0 +1,242 @@ +#include "bootFunctions.h" + +#include "Common/MEMORY.h" +#include "EEMEM.h" +#include "keys.h" + +uint8_t CheckFirmware(){ + boot_rww_enable_safe(); + uint32_t crcRead = flash_read_dword(STATIC_DATA_APP.AppCRC,0); + uint32_t crcCalc = CRC32(NULL,locationInApp<<1); + if (crcRead != crcCalc) return IDIFMW_REASON_NoFmwDetected; + return 0; +} + +uint8_t CheckEEPROMFlag(){ + eeprom_busy_wait(); + uint8_t flag = eeprom_read_byte(&(EEBLOCK.BOOTFLAG)); + if (flag != 0xFF) return IDIFMW_REASON_EnterFromApplication; + return 0; +} + +inline uint8_t CheckADDR(){ + if (RS_Address == IDIBUS_DEVELOPER_ADDR_3) return IDIFMW_REASON_EnterForced; + return 0; +} + +inline void DisableAES(){ + AES_DISABLED = 1; +} + +#ifdef _LONG_ADDR_SPACE_ +uint32_t baseAddr; +#else +uint16_t baseAddr; +#endif + +void BootloaderDataHandler(){ + wdt_reset(); + boot_spm_busy_wait(); + if (BootloaderInfo.BlockNumber == -1) { + + if (AES_DISABLED == 0) { + AES_PrepareKeys(key,IV); + AES_Decrypt(BootloaderData,FMW_INFO_SIZE); + } + + _memcopy(BootloaderData,&FmwInfo,FMW_INFO_SIZE); + uint32_t calculatedCRC = CRC32(&FmwInfo,FMW_INFO_SIZE-CRC32_SIZE); + + uint8_t Check = 1; + + if (calculatedCRC != FmwInfo.InfoHash) { + Check = 0; + } + + if (FmwInfo.FmwSizeInPages >= PAGE_COUNT) { + Check = 0; + } + + for (uint8_t i = 0; i < IDISN_FIXP_MODULE_TYPE_Length; i++) + { + if (flash_read_byte(STATIC_DATA_BL.ModuleType,i) != FmwInfo.ModuleType[i]) Check = 0; + } + + for (uint8_t i = 0; i < IDISN_FIXP_HW_REV_Length; i++) + { + if (flash_read_byte(STATIC_DATA_BL.HW_revision,i) != FmwInfo.HwRevision[i]) Check = 0; + } + + if (Check == 0) { + BootloaderInfo.Status = IDIFMW_STATUS_IncompatibleFmw; + return; + } + + for (uint16_t page = 0; page < PAGE_COUNT; page++){ + boot_spm_busy_wait(); + #ifdef _LONG_ADDR_SPACE_ + boot_page_erase(((uint32_t)page)<>8), "M" (RAMEND&0xFF), "M" (RAMEND>>8)); + + while(1); +} + +void FindBootloaderEnterReason(){ + BootloaderInfo.Reason = 0; + BootloaderInfo.Reason |= CheckFirmware(); + BootloaderInfo.Reason |= CheckEEPROMFlag(); + BootloaderInfo.Reason |= CheckADDR(); +} + +void GetBootloaderInfo(volatile uint8_t *dst){ + for (uint8_t i = IDISN_FIXP_MODULE_TYPE_Pos; i < IDISN_FIXP_MAC_Pos; i++){ + *dst++ = flash_read_byte(STATIC_DATA_BL,i); + } + *dst++ = flash_read_byte(STATIC_DATA_BL,IDISN_FIXP_SW_REV_Pos); + *dst++ = flash_read_byte(STATIC_DATA_BL,IDISN_FIXP_SW_REV_Pos+1); + + *dst++ = BootloaderInfo.Reason; + *dst = AES_DISABLED; +} + +uint16_t GetNextBlockSize(){ + if (BootloaderInfo.Status < IDIFMW_STATUS_Busy){ + if (BootloaderInfo.BlockNumber != -1) { + return PAGE_SIZE; + } else { + return FMW_INFO_SIZE; + } + } + return 0; +} + +void GetBootloaderStatus(volatile uint8_t *dst){ + *dst++ = BootloaderInfo.Status; + uint16_t BlockSize = GetNextBlockSize(); + *dst++ = (uint8_t)(BlockSize>>8); + *dst++ = (uint8_t)BlockSize; + *dst++ = (uint8_t)(BootloaderInfo.BlockNumber>>8); + *dst = (uint8_t)BootloaderInfo.BlockNumber; +} diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/bootFunctions.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/bootFunctions.h new file mode 100644 index 0000000..a8c2975 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/bootloader/bootFunctions.h @@ -0,0 +1,31 @@ +#ifndef BOOTFUNCTIONS_H_ +#define BOOTFUNCTIONS_H_ + +#include + +#include "config.h" +#include "boot.h" +#include "IDIBUS_BOOTLOADER_DEFS.h" +#include +#include +#include +#include +#include +#include "System.h" +#include "RSLink.h" +#include "AES.h" + +void FindBootloaderEnterReason(); + +uint8_t BootloaderData[PAGE_SIZE]; + +void BootloaderDataHandler(); + +void LaunchApplication(); + +void GetBootloaderInfo(volatile uint8_t *dst); +void GetBootloaderStatus(volatile uint8_t *dst); +uint16_t GetNextBlockSize(); +void DisableAES(); + +#endif /* BOOTFUNCTIONS_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_2560.componentinfo.xml b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_2560.componentinfo.xml new file mode 100644 index 0000000..9b7fc37 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_2560.componentinfo.xml @@ -0,0 +1,86 @@ +п»ї + + + + + + Device + Startup + + + Atmel + 1.7.0 + C:/Program Files (x86)\Atmel\Studio\7.0\Packs + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\include\ + + include + C + + + include/ + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\include\avr\iom2560.h + + header + C + MkwPezikXVtYA90mpLpFfA== + + include/avr/iom2560.h + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\templates\main.c + template + source + C Exe + KjvOcFWd++tbnsEMfVPd/w== + + templates/main.c + Main file (.c) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\templates\main.cpp + template + source + C Exe + mkKaE95TOoATsuBGv6jmxg== + + templates/main.cpp + Main file (.cpp) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega2560 + + libraryPrefix + GCC + + + gcc/dev/atmega2560 + + + + + ATmega_DFP + C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/1.7.374/Atmel.ATmega_DFP.pdsc + 1.7.374 + true + ATmega2560 + + + + Resolved + Latest + true + + + \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_2560.cproj b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_2560.cproj new file mode 100644 index 0000000..882d45b --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_2560.cproj @@ -0,0 +1,373 @@ +п»ї + + + 2.0 + 7.0 + com.Atmel.AVRGCC8.C + dce6c7e3-ee26-4d79-826b-08594b9ad897 + ATmega2560 + none + Executable + C + $(MSBuildProjectName) + .elf + $(MSBuildProjectDirectory)\$(Configuration) + idiBUS_bootloader + idiBUS_bootloader_2560 + idiBUS_bootloader + Native + true + false + true + true + 0x20000000 + + true + exception_table + 2 + 0 + 0 + + com.atmel.avrdbg.tool.atmelice + J41800094359 + 0x1E9801 + + + + 200000 + 125000 + + ISP + + com.atmel.avrdbg.tool.atmelice + J41800094359 + Atmel-ICE + + ISP + 200000 + + + + + + + + com.atmel.avrdbg.tool.simulator + + + Simulator + + + + + 125000 + + ISP + + com.atmel.avrdbg.tool.stk500 + + + STK500 + + + + + + + + + custom + + + Custom Programming Tool + + + + + + -mmcu=atmega2560 -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega2560" + True + True + True + True + True + False + True + True + + + _CPU_ATMEGA2560_ + _BOOTLOADER_ + NDEBUG + + + + + ../SysCommon + ../idiBus + ../CustomHWDefines + ../bootloader + .. + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + ../../../personalizationFiles + ../../../moduleFiles + + + Optimize for size (-Os) + True + True + True + False + False + False + + + libm + + + + + .text=0x1F000 + .locationInBoot=0x1FF80 + .locationInApp=0x1EF80 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + + + + + + + -mmcu=atmega2560 -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega2560" + True + True + True + True + True + True + True + True + + + _CPU_ATMEGA2560_ + _BOOTLOADER_ + DEBUG + _CPU_ATMEGA328PB_D + + + + + ../SysCommon + ../idiBus + ../CustomHWDefines + ../bootloader + .. + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + ../../../personalizationFiles + ../../../moduleFiles + + + Optimize for size (-Os) + True + True + True + True + True + True + + + libm + + + + + .text=0x1F000 + .locationInBoot=0x1FF80 + .locationInApp=0x1EF80 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + Maximum (-g3) + Default (-Wa,-g) + + + + + + + -mmcu=atmega2560 -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega2560" + True + True + True + True + True + True + True + True + + + _CPU_ATMEGA2560_ + _BOOTLOADER_ + DEBUG + _CPU_ATMEGA328PB_D + + + + + ../SysCommon + ../idiBus + ../CustomHWDefines + ../bootloader + .. + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + ../../../personalizationFiles + ../../../moduleFiles + + + Optimize for size (-Os) + True + True + True + True + True + True + + + libm + + + + + .text=0x1F000 + .locationInBoot=0x1FF80 + .locationInApp=0x1EF80 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + Maximum (-g3) + Default (-Wa,-g) + + + bin\Cutter_Debug\ + + + start "ahk" "$(CUTTER)\cutterStart.ahk" +start "cutter_cmd" /B "$(CUTTER)\cutter.exe" "$(OutputDirectory)\$(OutputFileName).elf" + + + + compile + SysCommon\EEMEM.h + + + compile + CustomHWDefines\RSLinkCustom.c + + + compile + CustomHWDefines\RSLinkCustom.h + + + compile + config.h + + + compile + keys.h + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + idiBus\IDIBUS_DEFS.h + + + compile + idiBus\MEMORY.h + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + + + + + + + + + compile + device.cfg + + + + \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_328.componentinfo.xml b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_328.componentinfo.xml new file mode 100644 index 0000000..8beb52e --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_328.componentinfo.xml @@ -0,0 +1,86 @@ +п»ї + + + + + + Device + Startup + + + Atmel + 1.7.0 + C:/Program Files (x86)\Atmel\Studio\7.0\Packs + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\include\ + + include + C + + + include/ + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\include\avr\iom328pb.h + + header + C + TU9y07FA4IWGxznrvGv9rQ== + + include/avr/iom328pb.h + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\templates\main.c + template + source + C Exe + KjvOcFWd++tbnsEMfVPd/w== + + templates/main.c + Main file (.c) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\templates\main.cpp + template + source + C Exe + mkKaE95TOoATsuBGv6jmxg== + + templates/main.cpp + Main file (.cpp) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb + + libraryPrefix + GCC + + + gcc/dev/atmega328pb + + + + + ATmega_DFP + C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/1.7.374/Atmel.ATmega_DFP.pdsc + 1.7.374 + true + ATmega328PB + + + + Resolved + Fixed + true + + + \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_328.cproj b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_328.cproj new file mode 100644 index 0000000..be3552e --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBUS_bootloader_328.cproj @@ -0,0 +1,385 @@ +п»ї + + + 2.0 + 7.0 + com.Atmel.AVRGCC8.C + dce6c7e3-ee26-4d79-826b-08594b9ad899 + ATmega328PB + none + Executable + C + $(MSBuildProjectName) + .elf + $(MSBuildProjectDirectory)\$(Configuration) + idiBUS_bootloader + idiBUS_bootloader_2560 + idiBUS_bootloader + Native + true + false + true + true + 0x20000000 + + true + exception_table + 2 + 0 + 0 + + com.atmel.avrdbg.tool.atmelice + J41800094359 + 0x1E9516 + + + + 1609087 + 125000 + + ISP + + com.atmel.avrdbg.tool.atmelice + J41800094359 + Atmel-ICE + + ISP + 125000 + + + + + + + + com.atmel.avrdbg.tool.simulator + + + Simulator + + + + + 0 + + ISP + + com.atmel.avrdbg.tool.stk500 + + + STK500 + + + + + + + + + custom + + + Custom Programming Tool + + + + + + + + + + + + + + + + + + -mmcu=atmega328pb -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb" + True + True + True + True + True + False + True + True + + + _CPU_ATMEGA328PB_ + _BOOTLOADER_ + NDEBUG + + + + + ../SysCommon + ../idiBus + ../CustomHWDefines + ../bootloader + .. + ../../../personalizationFiles + ../../../moduleFiles + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + Optimize for size (-Os) + True + True + True + False + False + False + + + libm + + + + + .text=0x3800 + .locationInBoot=0x3FE8 + .locationInApp=0x37C0 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + + + + + + + -mmcu=atmega328pb -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb" + True + True + True + True + True + True + True + True + + + _CPU_ATMEGA328PB_ + _BOOTLOADER_ + DEBUG + _CPU_ATMEGA328PB_D + + + + + ../SysCommon + ../idiBus + ../CustomHWDefines + ../bootloader + .. + ../../../personalizationFiles + ../../../moduleFiles + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + Optimize for size (-Os) + True + True + True + True + True + True + + + libm + + + + + .text=0x3800 + .locationInBoot=0x3FE8 + .locationInApp=0x37C0 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + Maximum (-g3) + Default (-Wa,-g) + + + + + + + -mmcu=atmega328pb -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb" + True + True + True + True + True + True + True + True + + + _CPU_ATMEGA328PB_ + _BOOTLOADER_ + DEBUG + _CPU_ATMEGA328PB_D + + + + + ../SysCommon + ../idiBus + ../CustomHWDefines + ../bootloader + .. + ../../../personalizationFiles + ../../../moduleFiles + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + Optimize for size (-Os) + True + True + True + True + True + True + + + libm + + + + + .text=0x3800 + .locationInBoot=0x3FE8 + .locationInApp=0x37C0 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + Maximum (-g3) + Default (-Wa,-g) + + + bin\Cutter_Debug\ + + + start "ahk" "$(CUTTER)\cutterStart.ahk" +start "cutter_cmd" /B "$(CUTTER)\cutter.exe" "$(OutputDirectory)\$(OutputFileName).elf" + + + + compile + SysCommon\EEMEM.h + + + compile + CustomHWDefines\RSLinkCustom.c + + + compile + CustomHWDefines\RSLinkCustom.h + + + compile + config.h + + + compile + keys.h + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + idiBus\IDIBUS_DEFS.h + + + compile + idiBus\MEMORY.h + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + + + + + + + + + compile + device.cfg + + + + \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/Common/IDIBUS_DEFS.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/Common/IDIBUS_DEFS.h new file mode 100644 index 0000000..058b70b --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/Common/IDIBUS_DEFS.h @@ -0,0 +1,456 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_IDIBUS_DEFS_H_ +#define _INC_IDIBUS_DEFS_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include + +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define F_CPU 16000000UL +#define MODBUS_CRC16_SIZE 2 +#define CRC32_SIZE 4 +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define IDIBUS_BAUDRATE_DSW_CODE_19200B 0x00 +#define IDIBUS_BAUDRATE_DSW_CODE_500K 0x01 +#define IDIBUS_BAUDRATE_DSW_CODE_2400B 0x02 +#define IDIBUS_BAUDRATE_DSW_CODE_9600B 0x03 +#define IDIBUS_BAUDRATE_DSW_CODE_115200B 0x04 +#define IDIBUS_BAUDRATE_DSW_CODE_250K 0x05 +#define IDIBUS_BAUDRATE_DSW_CODE_1M 0x06 +#define IDIBUS_BAUDRATE_DSW_CODE_10M 0x07 + +// Full timeout will be (InterframeTimeout + ResponseTimeout) for request(Write + Read) or InterframeTimeout for write(Write only) +#define IDIBUS_2400B_INTERFRAME_TIMEOUT_US 16042ULL //11 * 3.5 / Baudrate +#define IDIBUS_9600B_INTERFRAME_TIMEOUT_US 4011ULL +#define IDIBUS_19200B_INTERFRAME_TIMEOUT_US 2006ULL +#define IDIBUS_115200B_INTERFRAME_TIMEOUT_US 1750ULL +#define IDIBUS_250K_INTERFRAME_TIMEOUT_US 1750ULL +#define IDIBUS_500K_INTERFRAME_TIMEOUT_US 1750ULL +#define IDIBUS_1M_INTERFRAME_TIMEOUT_US 1750ULL +#define IDIBUS_10M_INTERFRAME_TIMEOUT_US 1750ULL + +#define IDIBUS_2400B_ALARM_TIMEOUT_US 34375ULL //11 * 3.5 / Baudrate +#define IDIBUS_9600B_ALARM_TIMEOUT_US 8594ULL +#define IDIBUS_19200B_ALARM_TIMEOUT_US 4297ULL +#define IDIBUS_115200B_ALARM_TIMEOUT_US 1750ULL +#define IDIBUS_250K_ALARM_TIMEOUT_US 1750ULL +#define IDIBUS_500K_ALARM_TIMEOUT_US 1750ULL +#define IDIBUS_1M_ALARM_TIMEOUT_US 1750ULL +#define IDIBUS_10M_ALARM_TIMEOUT_US 1750ULL + +#define IDIBUS_2400B_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_2400B_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_9600B_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_9600B_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_19200B_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_19200B_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_115200B_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_115200B_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_250K_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_250K_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_500K_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_500K_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_1M_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_1M_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_10M_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_10M_INTERFRAME_TIMEOUT_US * 3 / 2 ) + +#define IDIBUS_2400B_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_2400B_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_9600B_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_9600B_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_19200B_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_19200B_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_115200B_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_115200B_INTERFRAME_TIMEOUT_US) +#define IDIBUS_250K_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_250K_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_500K_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_500K_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_1M_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_1M_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_10M_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_10M_INTERFRAME_TIMEOUT_US ) + + +enum IDIBUS_SERIAL_BAUDRATE { + IDIBUS_BAUDRATE_2400 = IDIBUS_BAUDRATE_DSW_CODE_2400B, + IDIBUS_BAUDRATE_9600 = IDIBUS_BAUDRATE_DSW_CODE_9600B, + IDIBUS_BAUDRATE_19200 = IDIBUS_BAUDRATE_DSW_CODE_19200B, + IDIBUS_BAUDRATE_115200 = IDIBUS_BAUDRATE_DSW_CODE_115200B, + IDIBUS_BAUDRATE_250K = IDIBUS_BAUDRATE_DSW_CODE_250K, + IDIBUS_BAUDRATE_500K = IDIBUS_BAUDRATE_DSW_CODE_500K, + IDIBUS_BAUDRATE_1M = IDIBUS_BAUDRATE_DSW_CODE_1M, + IDIBUS_BAUDRATE_10M = IDIBUS_BAUDRATE_DSW_CODE_10M + }; + +#define IDIBUS_LINK_LED_NO_MMES_TIMEOUT_0_SEC 60U +#define IDIBUS_LINK_LED_NO_MMES_TIMEOUT_0_MS ( IDIBUS_LINK_LED_NO_MMES_TIMEOUT_0_SEC * 1000U ) +#define IDIBUS_LINK_LED_NO_MMES_TIMEOUT_1_SEC 15U +#define IDIBUS_LINK_LED_NO_MMES_TIMEOUT_1_MS ( IDIBUS_LINK_LED_NO_MMES_TIMEOUT_1_SEC * 1000U ) + +enum IDIBUS_RXTIMER_TIMEOUT_MODE { + IDIBUS_TIMER_MODE_RX_TIMEOUT = 0x00, + IDIBUS_TIMER_MODE_ALARM_TIMEOUT, + IDIBUS_TIMER_MODE_RESPONSE_TIMEOUT +}; +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDISN_FIXP_Pos 1U //Internal padding +#define IDISN_FIXP_GS1_COUNTRY_Pos ( IDISN_FIXP_Pos + 0U) +#define IDISN_FIXP_GS1_COUNTRY_Length 3 +#define IDISN_FIXP_GS1_COMPANY_Pos ( IDISN_FIXP_GS1_COUNTRY_Pos + IDISN_FIXP_GS1_COUNTRY_Length ) +#define IDISN_FIXP_GS1_COMPANY_Length 6 +#define IDISN_FIXP_MODULE_TYPE_Pos ( IDISN_FIXP_GS1_COMPANY_Pos + IDISN_FIXP_GS1_COMPANY_Length ) +#define IDISN_FIXP_MODULE_TYPE_Length 3 +#define IDISN_FIXP_HW_REV_Pos ( IDISN_FIXP_MODULE_TYPE_Pos + IDISN_FIXP_MODULE_TYPE_Length ) +#define IDISN_FIXP_HW_REV_Length 2 +#define IDISN_FIXP_SERIAL_Pos ( IDISN_FIXP_HW_REV_Pos + IDISN_FIXP_HW_REV_Length ) +#define IDISN_FIXP_SERIAL_Length 7 +#define IDISN_FIXP_MAC_Pos ( IDISN_FIXP_SERIAL_Pos + IDISN_FIXP_SERIAL_Length ) +#define IDISN_FIXP_MAC_Length 6 +#define IDISN_FIXP_SW_REV_Pos ( IDISN_FIXP_MAC_Pos + IDISN_FIXP_MAC_Length ) +#define IDISN_FIXP_SW_REV_Length 2 +#define IDISN_FIXP_LENGTH ( IDISN_FIXP_GS1_COUNTRY_Length + IDISN_FIXP_GS1_COMPANY_Length + IDISN_FIXP_MODULE_TYPE_Length + \ + IDISN_FIXP_HW_REV_Length + IDISN_FIXP_SERIAL_Length + IDISN_FIXP_MAC_Length + IDISN_FIXP_SW_REV_Length ) + +#define IDISN_VARP_Pos 0 //IDISN_FIXP_LENGTH +#define IDISN_VARP_VERIF_DATE_Pos ( IDISN_VARP_Pos ) +#define IDISN_VARP_VERIF_DATE_Length 4U +#define IDISN_VARP_EXPIR_DATE_Pos ( IDISN_VARP_VERIF_DATE_Pos + IDISN_VARP_VERIF_DATE_Length ) +#define IDISN_VARP_EXPIR_DATE_Length 4U +#define IDISN_VARP_IPv4_Pos ( IDISN_VARP_EXPIR_DATE_Pos + IDISN_VARP_EXPIR_DATE_Length ) +#define IDISN_VARP_IPv4_Length 4U +#define IDISN_VARP_IPv6_Pos ( IDISN_VARP_IPv4_Pos + IDISN_VARP_IPv4_Length ) +#define IDISN_VARP_IPv6_Length 16U +#define IDISN_VARP_AES256_Pos ( IDISN_VARP_IPv6_Pos + IDISN_VARP_IPv6_Length ) +#define IDISN_VARP_AES256_Length 32U +#define IDISN_VARP_LENGTH ( IDISN_VARP_VERIF_DATE_Length + IDISN_VARP_EXPIR_DATE_Length + \ + IDISN_VARP_IPv4_Length + IDISN_VARP_IPv6_Length + IDISN_VARP_AES256_Length ) + +#define IDISN_FULL_LENGTH ( IDISN_FIXP_LENGTH + IDISN_VARP_LENGTH ) +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define ISIBUS_MASTER_MAIN_ADDR 255U +#define ISIBUS_MASTER_SPARE_ADDR 254U +#define IDIBUS_SLAVE_ADDR_MIN 1U +#define IDIBUS_SLAVE_ADDR_MAX 229U +#define IDIBUS_DEVELOPER_ADDR_0 250U +#define IDIBUS_DEVELOPER_ADDR_1 251U +#define IDIBUS_DEVELOPER_ADDR_2 252U +#define IDIBUS_DEVELOPER_ADDR_3 253U +#define IDIBUS_GROUP_0_ADDR 230U +#define IDIBUS_GROUP_1_ADDR 231U +#define IDIBUS_GROUP_2_ADDR 232U +#define IDIBUS_GROUP_3_ADDR 233U +#define IDIBUS_GROUP_4_ADDR 234U +#define IDIBUS_GROUP_5_ADDR 235U +#define IDIBUS_GROUP_6_ADDR 236U +#define IDIBUS_GROUP_7_ADDR 237U +#define IDIBUS_GROUP_8_ADDR 238U +#define IDIBUS_GROUP_9_ADDR 239U +#define IDIBUS_GROUP_10_ADDR 240U +#define IDIBUS_GROUP_11_ADDR 241U +#define IDIBUS_GROUP_12_ADDR 242U +#define IDIBUS_GROUP_13_ADDR 243U +#define IDIBUS_GROUP_14_ADDR 244U +#define IDIBUS_GROUP_15_ADDR 245U + +#define IDIBUS_GROUPS_NUMBER 16U +#define IDIBUS_GROUP_FIRST_NUMBER 0U +#define IDIBUS_GROUP_LAST_NUMBER 15U +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDIMMES_ADDR_Pos 00U +#define IDIMMES_MMPS_Pos 01U +#define IDIMMES_MMPS_LONG_MES_Pos 0U +#define IDIMMES_MMPS_LONG_MES_Msk 0x01U +#define IDIMMES_MMPS_MES_TYPE_Pos 1U +#define IDIMMES_MMPS_MES_TYPE_Msk 0x02U +#define IDIMMES_MMPS_MES_TYPE_MMES 0x00U +#define IDIMMES_MMPS_MES_TYPE_MMESG 0x01U +#define IDIMMES_MMPS_FAST_FUNC_Pos 2U +#define IDIMMES_MMPS_FAST_FUNC_Msk 0x3CU +#define IDIMMES_MMPS_ALARM_FRAME_Pos 6U +#define IDIMMES_MMPS_ALARM_FRAME_Msk 0x40U +#define IDIMMES_MMPS_ENCRYPTED_AES_Pos 7U +#define IDIMMES_MMPS_ENCRYPTED_AES_Msk 0x80U +#define IDIMMES_DEV_Pos 02U +#define IDIMMES_DEV_NUM_Pos 0U +#define IDIMMES_DEV_NUM_Msk 0x1FU +#define IDIMMES_DEV_ALLCH_Pos 5U +#define IDIMMES_DEV_ALLCH_Msk 0x20U +#define IDIMMES_CHNL_Pos 03U +#define IDIMMES_CHNL_NUM_Pos 0U +#define IDIMMES_CHNL_NUM_Msk 0x7FU +#define IDIMMES_CHNL_ALLSAME_Pos 7U +#define IDIMMES_CHNL_ALLSAME_Msk 0x80U +#define IDIMMES_DATA_FUNC_COM_DATA_Pos 04U +#define IDIMMES_MAX_HEADER_LENGTH (IDIMMES_DATA_FUNC_COM_DATA_Pos + 1) +#define IDIMMES_MAX_DATA_SIZE 256U +#define IDIMMES_MAX_MES_SIZE (IDIMMES_MAX_DATA_SIZE + IDIMMES_MAX_HEADER_LENGTH + MODBUS_CRC16_SIZE) +#define IDIMMES_MIN_MES_SIZE (IDIMMES_DATA_FUNC_COM_DATA_Pos + MODBUS_CRC16_SIZE) + +#define IDIMMESG_DATA_COM_FUNC_Pos 02U +#define IDIMMESG_MAX_HEADER_LENGTH (IDIMMESG_DATA_COM_FUNC_Pos + 1) +#define IDIMMESG_MAX_DATA_SIZE IDIMMES_MAX_DATA_SIZE +#define IDIMMESG_MAX_MES_SIZE (IDIMMESG_MAX_DATA_SIZE + IDIMMESG_MAX_HEADER_LENGTH + MODBUS_CRC16_SIZE) +#define IDIMMESG_MODULE_MIN_MES_SIZE (IDIMMESG_DATA_COM_FUNC_Pos + 1 + MODBUS_CRC16_SIZE) +#define IDIMMESG_GROUP_MIN_MES_SIZE (IDIMMESG_DATA_COM_FUNC_Pos + MODBUS_CRC16_SIZE) + +#define IDIMMES_LMES_MSIZE_Pos 0U +#define IDIMMES_LMES_BSIZE_Pos (IDIMMES_LMES_MSIZE_Pos + 4U) +#define IDIMMES_LMES_IDENTIFIER_LENGTH (IDIMMES_LMES_BSIZE_Pos + 1U) +#define IDIMMES_LMES_BSIZE_256B 0U +#define IDIMMES_LMES_BSIZE_1K 1U +#define IDIMMES_LMES_BSIZE_4K 2U +#define IDIMMES_LMES_BSIZE_8K 3U +#define IDIMMES_LMES_BSIZE_16K 4U +#define IDIMMES_LMES_BSIZE_32K 5U +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDISMES_ADDR_Pos 00U +#define IDISMES_SMPS_Pos 01U +#define IDISMES_SMPS_ERROR_BIT_Pos 0U +#define IDISMES_SMPS_LONG_MES_Pos 1U +#define IDISMES_SMPS_LONG_OP_Pos 2U +#define IDISMES_ERROR_Pos 02U +#define IDISMES_DATA_Pos 03U +#define IDISMES_MAX_DATA_SIZE 256U +#define IDISMES_MIN_MES_SIZE (IDISMES_DATA_Pos + MODBUS_CRC16_SIZE) +#define IDISMES_MAX_MES_SIZE (IDISMES_DATA_Pos + IDISMES_MAX_DATA_SIZE + MODBUS_CRC16_SIZE) +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDILONGOP_STATE_COMPLETE_NO_ERR 0x00U +#define IDILONGOP_STATE_IN_PROC 0x01U +#define IDILONGOP_STATE_COMPLETE_WITH_ERR 0x02U +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define IDILONGOP_MES_DATA_LENGTH 5U +#define IDILONGOP_STATE_Pos 0U +#define IDILONGOP_REMAIN_TIME_Pos 1U +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDISTATUS_B0S_Pos 00U +#define IDISTATUS_B0S_ST_ERROR_Pos 0U +#define IDISTATUS_B0S_ST_STATE_Pos 1U +#define IDISTATUS_B0S_ST_STATE_Msk 0x07U +#define IDISTATUS_B0S_ST_STATE_StNoInit 0x00U +#define IDISTATUS_B0S_ST_STATE_StOperate 0x01U +#define IDISTATUS_B0S_ST_STATE_StFreeze 0x02U +#define IDISTATUS_B0S_ST_STATE_StVirtual 0x03U +#define IDISTATUS_B0S_ST_STATE_StFirmwareUpd 0x04U +#define IDISTATUS_B0S_ST_STATE_StReservedMaster 0x05U +#define IDISTATUS_B0S_ST_STATE_StBroken 0x06U +#define IDISTATUS_B0S_ST_STATE_StReserved0 0x07U +#define IDISTATUS_B0S_AES_SUPPORTED_Pos 4U +#define IDISTATUS_B0S_AES_INSTALLED_Pos 5U +#define IDISTATUS_B0S_SEND_ALARM_L0_Pos 6U +#define IDISTATUS_B0S_SEND_ALARM_L1_Pos 7U + +#define IDISTATUS_B1S_Pos 01U +#define IDISTATUS_B1S_MODULE_TYPE_Pos 0U +#define IDISTATUS_B1S_MODULE_TYPE_Msk 0x03U +#define IDISTATUS_B1S_MODULE_TYPE_Master 0x00U +#define IDISTATUS_B1S_MODULE_TYPE_SpareMaster 0x01U +#define IDISTATUS_B1S_MODULE_TYPE_Slave 0x02U +#define IDISTATUS_B1S_MODULE_TYPE_Bridge 0x03U +#define IDISTATUS_B1S_BRIDGE_CONNECTED_Pos 2U +#define IDISTATUS_B1S_SELF_INIT_Pos 3U +#define IDISTATUS_B1S_TIMEOUT_LED_Pos 4U +#define IDISTATUS_B1S_NO_MMES_TIMEOUT_Pos 5U +#define IDISTATUS_B1S_CATCH_ALARM_L0_Pos 6U +#define IDISTATUS_B1S_CATCH_ALARM_L1_Pos 7U + +#define IDISTATUS_SN_Pos 02U +#define IDISTATUS_LENGTH ( IDISTATUS_SN_Pos + IDISN_FULL_LENGTH ) +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDIMMES_NOT_FAST_FUNC 0U +#define IDIMMES_MAX_FAST_FUNC_NUM 15U +#define IDIMMES_COM_START_NUM 220U +#define IDIMMES_COM_C_Init 220U +#define IDIMMES_COM_C_ShtDown 221U +#define IDIMMES_COM_C_Freeze 222U +#define IDIMMES_COM_C_Resume 223U +#define IDIMMES_COM_C_Dummy 224U +#define IDIMMES_COM_C_AssignGroup 225U +#define IDIMMES_COM_C_SetAlarmL12 226U +#define IDIMMES_COM_C_SetAlarmL 227U +#define IDIMMES_COM_C_Virtual 228U +#define IDIMMES_COM_C_SyncReadChnl 229U +#define IDIMMES_COM_C_SyncRead 230U +#define IDIMMES_COM_C_SyncDoChnl 231U +#define IDIMMES_COM_C_SyncDo 232U +#define IDIMMES_COM_C_SyncClear 233U +#define IDIMMES_COM_C_BurstReadCnt 234U +#define IDIMMES_COM_C_BurstReadTime 235U +#define IDIMMES_COM_C_SendTimeDate 236U +#define IDIMMES_COM_C_MkTimedMaster 237U +#define IDIMMES_COM_C_EnterBootloader 238U //OUT OF SPEC !!! +//#define IDIMMES_COM_C_EndFmwUpd 239U +//#define IDIMMES_COM_C_FmwWrite 240U +#define IDIMMES_COM_C_ReadDevFullSN_MS 241U +#define IDIMMES_COM_C_WriteSnIPv4IPv6 242U +#define IDIMMES_COM_C_WriteSnVerifyDates 243U +#define IDIMMES_COM_C_WriteSnAES256 244U +#define IDIMMES_COM_C_SendLongMessage 245U +#define IDIMMES_COM_C_GetLondMessage 246U +#define IDIMMES_COM_C_DummyModule 247U +#define IDIMMES_COM_C_CheckModuleLongOp 248U +#define IDIMMES_COM_C_CheckChannelLongOp 249U +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDIER_MODBUS_NUM_START 1U +#define IDIER_MODBUS_NUM_END 9U +#define IDIER_MODULE_MASTER_NUM_START 10U +#define IDIER_MODULE_MASTER_NUM_END 32U +#define IDIER_MODULE_SLAVE_NUM_START 33U +#define IDIER_MODULE_SLAVE_NUM_END 71U +#define IDIER_MODULE_NUM_START IDIER_MODULE_MASTER_NUM_START +#define IDIER_MODULE_NUM_END IDIER_MODULE_SLAVE_NUM_END +#define IDIER_DEVICE_NUM_START 72U +#define IDIER_DEVICE_NUM_END 89U + +#define IDIER_NOPE 0U +#define MODBUSER_WRONGFUNC 1U +#define MODBUSER_WRONGADDR 2U +#define MODBUSER_WRONGDATA 3U +#define MODBUSER_BROKE 4U +#define MODBUSER_LONGCOMMAND 5U +#define MODBUSER_BUSY 6U +#define MODBUSER_CANTDOFUNC 7U +#define MODBUSER_EXTMEMORYERROR 8U +#define MODBUSER_RESERVED 9U +#define IDIERMST_INVALID_ADDR_NUM 10U +#define IDIERMST_INVALID_DEV_NUM 11U +#define IDIERMST_INVALID_CHN_NUM 12U +#define IDIERMST_INVALID_FUNC_NUM 13U +#define IDIERMST_INVALID_TX_REQUEST_FORMAT 14U +#define IDIERMST_INVALID_TX_PARAM 15U +#define IDIERMST_TX_MES 16U +#define IDIERMST_RCV_TIMEOUT 17U +#define IDIERMST_MES_RX_INTEGRITY 18U +#define IDIERMST_CRC 19U +#define IDIERMST_MULTIPLE_CRC 20U +#define IDIERMST_INVALID_RX_REQUEST_FORMAT 21U +#define IDIERMST_INVALID_RX_PARAM 22U +#define IDIERMST_RESEVED_23 23U +#define IDIERMST_RESEVED_24 24U +#define IDIERMST_RESEVED_25 25U +#define IDIERMST_RESEVED_26 26U +#define IDIERMST_RESEVED_27 27U +#define IDIERMST_EXTRA_28 28U +#define IDIERMST_EXTRA_29 29U +#define IDIERMST_EXTRA_30 30U +#define IDIERMST_EXTRA_31 31U +#define IDIERMST_EXTRA_32 32U +#define IDIERSLV_RESEVED_33 33U +#define IDIERSLV_ENCRYPTION_NOT_SUPPORTED 34U +#define IDIERSLV_ENCRYPTION_NOT_INSTALLED 35U +#define IDIERSLV_JUMBO_NOT_SUPPORTED 36U +#define IDIERSLV_UNSUPPORTED_FUNC_NUM 37U +#define IDIERSLV_INVALID_RX_REQUEST_FORMAT 38U +#define IDIERSLV_INVALID_RX_PARAM 39U +#define IDIERSLV_IN_FREEZE 40U +#define IDIERSLV_RESERVED_41 41U +#define IDIERSLV_RESERVED_42 42U +#define IDIERSLV_RESERVED_43 43U +#define IDIERSLV_RESERVED_44 44U +#define IDIERSLV_RESERVED_45 45U +#define IDIERSLV_EXTRA_46 46U +#define IDIERSLV_EXTRA_47 47U +#define IDIERSLV_EXTRA_48 48U +#define IDIERSLV_EXTRA_49 49U +#define IDIERSLV_EXTRA_50 50U +#define IDIERSLV_BROKE 51U +#define IDIERSLV_NO_FIRMWARE 52U +#define IDIERSLV_NO_INIT 53U +#define IDIERSLV_OVERHEAT 54U +#define IDIERSLV_INP_VOLTAGE 55U +#define IDIERSLV_BRIDGE_OVERFLOW 56U +#define IDIERSLV_BRIDGE_NOT_CONF 57U +#define IDIERSLV_VERIF_DATE 58U +#define IDIERSLV_RTC 59U +#define IDIERSLV_LONG_OP_IN_PROC 60U +#define IDIERSLV_RESERVED_61 61U +#define IDIERSLV_RESERVED_62 62U +#define IDIERSLV_RESERVED_63 63U +#define IDIERSLV_RESERVED_64 64U +#define IDIERSLV_RESERVED_65 65U +#define IDIERSLV_RESERVED_66 66U +#define IDIERSLV_EXTRA_67 67U +#define IDIERSLV_EXTRA_68 68U +#define IDIERSLV_EXTRA_69 69U +#define IDIERSLV_EXTRA_70 70U +#define IDIERSLV_EXTRA_71 71U +#define IDIERDEV_INVALID_DEV_NUM 72U +#define IDIERDEV_INVALID_CHN_NUM 73U +#define IDIERDEV_INVALID_FUNC_NUM 74U +#define IDIERDEV_LONG_OP_IN_PROC 75U +#define IDIERDEV_RESERVED_76 76U +#define IDIERDEV_PARAM_LOW_ST_TIMEOUT 77U +#define IDIERDEV_PARAM_HIGH_ST_TIMEOUT 78U +#define IDIERDEV_PARAM_NOT_CHANGE_TIMEOUT 79U +#define IDIERDEV_RESERVED_80 80U +#define IDIERDEV_RESERVED_81 81U +#define IDIERDEV_RESERVED_82 82U +#define IDIERDEV_RESERVED_83 83U +#define IDIERDEV_RESERVED_84 84U +#define IDIERDEV_RESERVED_85 85U +#define IDIERDEV_RESERVED_86 86U +#define IDIERDEV_RESERVED_87 87U +#define IDIERDEV_RESERVED_88 88U +#define IDIERDEV_RESERVED_89 89U + +#define IDIER_MULTIPLE_CRC_AVRBUF_SIZE 16U +#define IDIER_MULTIPLE_CRC_AVRBUF_THR 5U +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDIDATE_FORMAT_DAY_Pos 0U +#define IDIDATE_FORMAT_MONTH_Pos 1U +#define IDIDATE_FORMAT_CENTURY_Pos 2U +#define IDIDATE_FORMAT_YEAR99_Pos 3U +#define IDIDATE_FORMAT_LENGTH 4U + +#define IDITIME_FORMAT_SECONDS_Pos 0U +#define IDITIME_FORMAT_MINUTES_Pos 1U +#define IDITIME_FORMAT_HOURS_Pos 2U +#define IDITIME_FORMAT_TIMEZONE_Pos 3U +#define IDITIME_FORMAT_LENGTH 4U + +#define IDITIME_FORMAT_TIMEZONE_MIN (-12) +#define IDITIME_FORMAT_TIMEZONE_MAX 14 + +#define IDIMMES_C_DATETIME_TIME_Pos 0 +#define IDIMMES_C_DATETIME_DATE_Pos (IDIMMES_C_DATETIME_TIME_Pos + IDIDATE_FORMAT_LENGTH) +#define IDIMMES_C_DATETIME_LENGTH (IDIDATE_FORMAT_LENGTH + IDITIME_FORMAT_LENGTH) +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +typedef struct { + struct { + uint8_t StError : 1; + uint8_t StState : 3; + uint8_t AesSupported : 1; + uint8_t AesInstalled : 1; + uint8_t SendAlarmL0 : 1; + uint8_t SendAlarmL1 : 1; + } B0S; + struct { + uint8_t ModuleType : 2; + uint8_t BridgeConnected : 1; + uint8_t SelfInit : 1; + uint8_t TimeoutLed : 1; + uint8_t NoMMESTimeout : 1; + uint8_t CatchAlarmL0 : 1; + uint8_t CatchAlarmL1 : 1; + } B1S; + } IDISTATUS_STATE_TYPE; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct { + IDISTATUS_STATE_TYPE STATE; + #ifdef _LONG_ADDR_SPACE_ + volatile uint_farptr_t SNfix; + #else + volatile uint8_t *SNfix; + #endif + volatile uint8_t *SNvar; + //uint8_t SN[IDISN_FULL_LENGTH]; +} IDISTATUS_SLAVE_TYPE; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif //_INC_IDIBUS_DEFS_H_ +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/Common/MEMORY.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/Common/MEMORY.h new file mode 100644 index 0000000..c00e6c2 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/Common/MEMORY.h @@ -0,0 +1,33 @@ +#ifndef MEMORY_H_ +#define MEMORY_H_ +volatile typedef struct{ + volatile uint8_t Padding; + volatile uint8_t GS1_country[IDISN_FIXP_GS1_COUNTRY_Length]; + volatile uint8_t GS1_company[IDISN_FIXP_GS1_COMPANY_Length]; + volatile uint8_t ModuleType[IDISN_FIXP_MODULE_TYPE_Length]; + volatile uint8_t HW_revision[IDISN_FIXP_HW_REV_Length]; + volatile uint8_t SN[IDISN_FIXP_SERIAL_Length]; + volatile uint8_t MAC[IDISN_FIXP_MAC_Length]; + volatile uint8_t SW[IDISN_FIXP_SW_REV_Length]; //SW Version (Bootloader/App) + volatile uint32_t AppCRC; //Only in APP +} FLASH_DATABLOCK; +//Universal data block + +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#ifdef _BOOTLOADER_ +#include "BootVersion.h" +const volatile FLASH_DATABLOCK STATIC_DATA_BL __attribute__((section (".locationInBoot"))) = { + //STATIC PART + #include "device.cfg" + .SW = {BOOT_VERSION_MAJOR, BOOT_VERSION_MINOR} //Botloader version +}; +#endif +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define APP_VERSION +const volatile FLASH_DATABLOCK STATIC_DATA_APP __attribute__((section (".locationInApp"))) = { + //.AppCRC = 0x8d173a8c //CRC32 for empty flash + #include "device.cfg" + }; +#undef APP_VERSION +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif /* MEMORY_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_BOOTLOADER_DEFS.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_BOOTLOADER_DEFS.h new file mode 100644 index 0000000..05dd42a --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_BOOTLOADER_DEFS.h @@ -0,0 +1,34 @@ +#ifndef IDIBUS_BOOTLOADER_DEFS_H_ +#define IDIBUS_BOOTLOADER_DEFS_H_ + +#include + +#include "Common/IDIBUS_DEFS.h" +//#include "config.h" + +#define IDIMMES_COM_C_FmwBootloaderInfo 255U +//[Module Type][Module HW Revision][Module SN][Module BL Revision][Reason for bootloader enter][Custom FMW loading enabled] +#define IDIMMES_COM_C_FmwBootloaderInfo_Length (IDISN_FIXP_MODULE_TYPE_Length+IDISN_FIXP_HW_REV_Length+\ + IDISN_FIXP_SERIAL_Length+IDISN_FIXP_SW_REV_Length+1+1) +#define IDIMMES_COM_C_FmwBootloaderStatus 254U +//[Module Status][Block Size Hi][Block Size Lo] +#define IDIMMES_COM_C_FmwBootloaderWrite 253U +//[FMW DATA (in expected size)] + +//FLAG FIELD +#define IDIFMW_REASON_NoReason 0 +#define IDIFMW_REASON_EnterFromApplication 1 //EEPROM FLAG +#define IDIFMW_REASON_EnterForced 2 //Address detection +#define IDIFMW_REASON_NoFmwDetected 4 + +//Maybe move to common idi error list??? +#define IDIFMW_STATUS_ReadyToGetBlock 0 +#define IDIFMW_STATUS_ErrorPacketCRC 1 +//NO BLOCK ACCEPT +#define IDIFMW_STATUS_Busy 2 +#define IDIFMW_STATUS_IncompatibleFmw 3 +#define IDIFMW_STATUS_FmwUploadCRCError 4 //Final Check +#define IDIFMW_STATUS_FmwUploadComplete 5 +#define IDIFMW_STATUS_Reboot 10 + +#endif /* IDIBUS_BOOTLOADER_DEFS_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_IMPL.c b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_IMPL.c new file mode 100644 index 0000000..8cd33a6 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_IMPL.c @@ -0,0 +1,120 @@ +//############################################################################################################################################################################################################# +#include "IDIBUS_IMPL.h" +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +void IDIBUS_ModuleBackgroundHandler(void) +{ + if (BootloaderInfo.Status == IDIFMW_STATUS_Busy){ + BootloaderDataHandler(); + } else if (BootloaderInfo.Status >= IDIFMW_STATUS_Reboot) { + uint8_t TimeOut = 200; //ms + while(USART1STR.TxComplete == 0 && TimeOut != 0) {_delay_ms(1);TimeOut--;} + if ((BootloaderInfo.Reason & IDIFMW_REASON_NoFmwDetected) == 0){ + LaunchApplication(); + } else { + System_SWReboot(); + } + } +} +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +void IDIBUS_ModuleCommandHandler() +{ + if (FARG.ComFunc == IDIMMES_COM_C_Init) { + BootloaderInfo.Status += IDIFMW_STATUS_Reboot; + IDIBUS_ResponseProtectedWrite(NULL,0,IDIER_NOPE); + } else if (FARG.ComFunc == IDIMMES_COM_C_FmwBootloaderWrite) { + uint16_t BlockSize = GetNextBlockSize(); + if (FARG.InpDataLength != BlockSize || FARG.InpDataLength == 0) {IDIBUS_ResponseProtectedWrite(NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT);} + else { + if (BootloaderInfo.Status < IDIFMW_STATUS_Busy){ + BootloaderInfo.Status = IDIFMW_STATUS_Busy; + _memcopy(&RxMesageBuf[3],BootloaderData,BlockSize); + } + //volatile uint8_t Response[3]; + //GetBootloaderStatus(Response); + IDIBUS_ResponseProtectedWrite(NULL,0,IDIER_NOPE); + } + } else if (FARG.ComFunc == IDIMMES_COM_C_FmwBootloaderStatus) { + if (FARG.InpDataLength != 0) {IDIBUS_ResponseProtectedWrite(NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT);} + else{ + uint8_t Response[5]; + GetBootloaderStatus(Response); + IDIBUS_ResponseProtectedWrite(Response,5,IDIER_NOPE); + } + } else if (FARG.ComFunc == IDIMMES_COM_C_FmwBootloaderInfo) { + if (FARG.InpDataLength != 0 && FARG.InpDataLength != 1) {IDIBUS_ResponseProtectedWrite(NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT);} + else{ + uint8_t Response[IDIMMES_COM_C_FmwBootloaderInfo_Length]; + if (FARG.InpDataLength == 1) DisableAES(); //Disable AES if we get something + GetBootloaderInfo(Response); + IDIBUS_ResponseProtectedWrite(Response,IDIMMES_COM_C_FmwBootloaderInfo_Length,IDIER_NOPE); + } + } else { IDIBUS_ResponseProtectedWrite(NULL, 0, IDIERSLV_NO_FIRMWARE); } //TODO!!! + /* + switch ( FARG.ComFunc ) + { + case (IDIMMES_COM_C_Init) : { + BootloaderInfo.Status += IDIFMW_STATUS_Reboot; + IDIBUS_ResponseProtectedWrite(NULL,0,IDIER_NOPE); + break; + } + case (IDIMMES_COM_C_FmwBootloaderWrite) : { + uint16_t BlockSize = GetNextBlockSize(); + if (FARG.InpDataLength != BlockSize || FARG.InpDataLength == 0) {IDIBUS_ResponseProtectedWrite(NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT);} + else { + if (BootloaderInfo.Status < IDIFMW_STATUS_Busy){ + BootloaderInfo.Status = IDIFMW_STATUS_Busy; + _memcopy(&RxMesageBuf[3],BootloaderData,BlockSize); + } + //volatile uint8_t Response[3]; + //GetBootloaderStatus(Response); + IDIBUS_ResponseProtectedWrite(NULL,0,IDIER_NOPE); + } + break; + } + case (IDIMMES_COM_C_FmwBootloaderStatus) : { + if (FARG.InpDataLength != 0) {IDIBUS_ResponseProtectedWrite(NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT);} + else{ + uint8_t Response[5]; + GetBootloaderStatus(Response); + IDIBUS_ResponseProtectedWrite(Response,5,IDIER_NOPE); + } + break; + } + case (IDIMMES_COM_C_FmwBootloaderInfo) : { + if (FARG.InpDataLength != 0) {IDIBUS_ResponseProtectedWrite(NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT);} + else{ + uint8_t Response[IDIMMES_COM_C_FmwBootloaderInfo_Length]; + GetBootloaderInfo(Response); + IDIBUS_ResponseProtectedWrite(Response,IDIMMES_COM_C_FmwBootloaderInfo_Length,IDIER_NOPE); + } + break; + } + default : { IDIBUS_ResponseProtectedWrite(NULL, 0, IDIERSLV_NO_FIRMWARE); } //TODO!!! + } +*/ +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +void IDIBUS_ResponseProtectedWrite(uint8_t *Data, uint16_t DataLength, uint8_t ErrorCode) +{ + //TODO!!!!! + if ( ErrorCode != IDIER_NOPE ) { FARG.SMPS |= 1; } + else { FARG.SMPS &= ~(1); } + FARG.OutData[IDISMES_ERROR_Pos] = ErrorCode; + FARG.OutDataLength = (uint16_t)(FARG.OutDataLength + 1); + + if (Data != NULL) + { + _memcopy(Data, &FARG.OutData[IDISMES_ERROR_Pos+1], DataLength); + FARG.OutDataLength = (uint16_t)(FARG.OutDataLength + DataLength); + } +} +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_IMPL.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_IMPL.h new file mode 100644 index 0000000..8354f4a --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/IDIBUS_IMPL.h @@ -0,0 +1,40 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_IDIBUS_IMPL_H_ +#define _INC_IDIBUS_IMPL_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include +#include "IDIBUS_BOOTLOADER_DEFS.h" +#include +#include +#include "System.h" +#include "bootFunctions.h" +//#include "MODBUS_CRC.h" +#include +#include "USART_COM.h" +#include "RSLink.h" +#include "CRCs.h" +//#include "EEPROM_Fast.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct { + uint8_t ComFunc; + uint16_t InpDataLength; + volatile uint8_t *OutData; + uint16_t OutDataLength; + uint8_t SMPS; + //uint8_t ErrorState; + //uint8_t LongOpState; +} IDIBUS_FARG_TYPE; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +IDIBUS_FARG_TYPE FARG; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define IDIBUS_SYSTEM_SW_VERSION 0x3133U +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void IDIBUS_ModuleCommandHandler(); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void IDIBUS_ResponseProtectedWrite(uint8_t *Data, uint16_t DataLength, uint8_t ErrorCode); +void IDIBUS_ModuleBackgroundHandler(void); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif // #ifndef _INC_IDIBUS_IMPL_H_ +//############################################################################################################################################################################################################# + diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/RSLink.c b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/RSLink.c new file mode 100644 index 0000000..ce594fa --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/RSLink.c @@ -0,0 +1,116 @@ +//############################################################################################################################################################################################################# +#include "RSLink.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_Init(/*USART_INTERFACE_TYPE *USART_INTERFACE, USART_IDIBUS_ROUTINE_TYPE *USART_ID_INTERFACE*/) +{ + //RS_USI=USART_INTERFACE; // USART POINTER INIT + //RS_USIID=USART_ID_INTERFACE; + RS_NeedSpeedChangeFlag=0; + + //RS_LastMMES_TimeInstance=System_GetTimeInstance(); + FARG.OutData = USART1_getTxBuf(); //set RX addr + + RSLink_StatusLedInit(); // Init LEDs + RSLink_DipsInit(); // + RSLink_SpeedCheckAndUpdate(); // Set speed + USART1_SetIdiBusBoudrate(RS_SpeedCode); // Set speed usart + RSLink_AddressCheckAndUpdate(); // Set adr + USART1_RxTransferRestart(); // Restart RX +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t RSLink_SpeedCheckAndUpdate(void) +{ + uint8_t SpeedDSW_Code = RSLink_SpeedDecode(); + if (RS_SpeedCode != SpeedDSW_Code) { RS_SpeedCode = SpeedDSW_Code; return 1; } + return 0; +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_AddressCheckAndUpdate(void) +{ + RS_Address = RSLink_AddrDecode(); +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +void RSLink_Handler(void) +{ + // Address and Speed Change Check Routine ======================================= + if ( (RS_NeedSpeedChangeFlag == 1) || RSLink_SpeedCheckAndUpdate() ) + { + if ( USART1_IsTxActive() ) { RS_NeedSpeedChangeFlag = 1; } + else { USART1_SetIdiBusBoudrate(RS_SpeedCode); RS_NeedSpeedChangeFlag = 0; } + } + RSLink_AddressCheckAndUpdate(); + + IDIBUS_ModuleBackgroundHandler(); + + if ( USART1_IsNewRxMessage() == 0 ) { return; } + + if ( USART1_IsRxError() == 1) { + USART1_RxTransferRestart(); + return; + } + + static uint16_t RxMessageSize; + + // Check normal Message ---------------------------------------------------------> + + // Check Message size + uint8_t RcvAddress; + RxMessageSize = USART1_getRxBufSize(); + if ( (RxMessageSize < (MODBUS_CRC16_SIZE+1) ) || (RxMessageSize > IDIMMES_MAX_MES_SIZE) ) { USART1_RxTransferRestart(); return; } + else + { + USART1_copyRxBuf( &RxMesageBuf[IDIMMES_ADDR_Pos], IDIMMES_ADDR_Pos, RxMessageSize ); // Need for CRC + USART1_RxTransferRestart(); + RcvAddress = RxMesageBuf[IDIMMES_ADDR_Pos]; + } + + // MMESG(Module) or MMES -------------> + if ( RcvAddress == RS_Address ) + { + // Check CRC, copy RxBuf and Restart Transfer + //USART1_copyRxBuf( &RxMesageBuf[IDIMMES_MMPS_Pos], IDIMMES_MMPS_Pos, (uint16_t)(RxMessageSize-1) ); + uint16_t CalculatedCRC = CRC16( RxMesageBuf, (uint16_t)(RxMessageSize-2) ); + uint16_t ReceivedCRC = (uint16_t)( ((uint16_t)RxMesageBuf[RxMessageSize-2] << 8) | RxMesageBuf[RxMessageSize-1] ); + if ( CalculatedCRC != ReceivedCRC ) { BootloaderInfo.Status=IDIFMW_STATUS_ErrorPacketCRC; return; } + + FARG.OutDataLength = IDISMES_ERROR_Pos; //Set length 2 (adr+cmd) + + uint8_t MMPS = RxMesageBuf[IDIMMES_MMPS_Pos]; + + if ( (MMPS != (IDIMMES_MMPS_MES_TYPE_Msk)) || (RxMessageSize < IDIMMESG_MODULE_MIN_MES_SIZE)) { + //IDIBUS_ResponseProtectedWrite(NULL,0,IDIERSLV_NO_FIRMWARE); + IDIBUS_ResponseProtectedWrite(NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); + } + else + { + FARG.ComFunc = RxMesageBuf[IDIMMESG_DATA_COM_FUNC_Pos]; + //FARG.InpData = &RxMesageBuf[IDIMMESG_DATA_COM_FUNC_Pos + 1]; + FARG.InpDataLength = (uint16_t)(RxMessageSize - (IDIMMESG_DATA_COM_FUNC_Pos + 1) - MODBUS_CRC16_SIZE); + IDIBUS_ModuleCommandHandler(); + } + + RSLink_SendSMES(); + } //if ( (RcvAddress == RS_Address) && (RxMessageSize >= IDIMMES_MIN_MES_SIZE) ) + + + // MMESG -------------> + // NO RESPONSE!!! +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_SendSMES() +{ + if ( /*(USART1STR->ResponseTimeoutComplete == 0) &&*/ (FARG.OutDataLength > IDISMES_ERROR_Pos) ) + { + FARG.OutData[IDISMES_ADDR_Pos] = RS_Address; + FARG.OutData[IDISMES_SMPS_Pos] = FARG.SMPS; + //if ( FARG.ErrorState != 0 ) { FARG.OutData[IDISMES_SMPS_Pos] |= (1U << IDISMES_SMPS_ERROR_BIT_Pos); } + //if ( FARG.OutLongMesState != 0 ) { FARG.OutData[IDISMES_SMPS_Pos] |= (1U << IDISMES_SMPS_LONG_MES_Pos); } + //if ( FARG.LongOpState != 0 ) { FARG.OutData[IDISMES_SMPS_Pos] |= (1U << IDISMES_SMPS_LONG_OP_Pos); } + uint16_t crc16 = CRC16(&FARG.OutData[0], FARG.OutDataLength); + FARG.OutData[FARG.OutDataLength++] = (uint8_t)(crc16 >> 8); + FARG.OutData[FARG.OutDataLength++] = (uint8_t) crc16; + USART1_SendTxBuf(FARG.OutDataLength); + } +} +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/RSLink.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/RSLink.h new file mode 100644 index 0000000..64d681a --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/RSLink.h @@ -0,0 +1,40 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_RSLINK_H_ +#define _INC_RSLINK_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include +#include "SYSTEM.h" +#include "USART1.h" +#include "IDIBUS_IMPL.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// DELAYS FOR LEDS status + +#define RSLINK_LED_T1_DEFAULT_S 15UL +#define RSLINK_LED_T2_DEFAULT_S 60UL +//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//USART_INTERFACE_TYPE *USI; +//USART_IDIBUS_ROUTINE_TYPE *USIID; +uint8_t RS_Address; +uint8_t RS_SpeedCode; +uint8_t RS_NeedSpeedChangeFlag; // флаг для изменения скорости +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t RxMesageBuf[IDIMMES_MAX_MES_SIZE]; //RX buffer for copy +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_Init(/*USART_HANDLER_TYPE *USART_INTERFACE, USART_IDIBUS_ROUTINE_TYPE *USART_ID_INTERFACE*/); +uint8_t RSLink_SpeedCheckAndUpdate(void); +void RSLink_AddressCheckAndUpdate(void); +void RSLink_Handler(void); +void RSLink_SendSMES(); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_StatusLedInit(void); +void RSLink_StatusLedSetOn(void); +void RSLink_StatusLedSetOff(void); + +void RSLink_DipsInit(void); +uint8_t RSLink_AddrDecode(void); +uint8_t RSLink_SpeedDecode(void); +uint8_t RSLink_TypeDecode(void); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif // #ifndef _INC_RSLINK_H_ +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/USART1.c b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/USART1.c new file mode 100644 index 0000000..39e75c3 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/USART1.c @@ -0,0 +1,108 @@ +#include "USART1.h" + +// USARTs common settings : Speed and Timeouts +const uint16_t USART_UBRR[8] PROGMEM={ (F_CPU/8UL)/19200-1, (F_CPU/8UL)/500000-1, + (F_CPU/8UL)/2400-1, (F_CPU/8UL)/9600-1, + (F_CPU/8UL)/115200-1, (F_CPU/8UL)/250000-1, + (F_CPU/8UL)/1000000-1, /*(F_CPU/8UL)/10000000-1*/ 0}; // Fosc=16MHz : 19.2k, 500k, 2.4k, 9.6k, 115.2k, 250k, 1M, 1M +const uint16_t USART_TIMEOUT[8] PROGMEM={ (IDIBUS_19200B_INTERFRAME_TIMEOUT_US/8*16), (IDIBUS_500K_INTERFRAME_TIMEOUT_US/8*16), + (IDIBUS_2400B_INTERFRAME_TIMEOUT_US/8*16), (IDIBUS_9600B_INTERFRAME_TIMEOUT_US/8*16), + (IDIBUS_115200B_INTERFRAME_TIMEOUT_US/8*16), (IDIBUS_250K_INTERFRAME_TIMEOUT_US/8*16), + (IDIBUS_1M_INTERFRAME_TIMEOUT_US/8*16), (IDIBUS_1M_INTERFRAME_TIMEOUT_US/8*16) }; +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ISR(USART1_TX_vect){ + if (USART1STR.TxSendedCount == USART1STR.TxBufCount){ + //UCSR1B &= ~((1< Z + USART1_DRE_DDR&=~(1< Z + } else { + UDR1=USART1_TX_BUF[USART1STR.TxSendedCount]; + USART1STR.TxSendedCount++; + } +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ISR(USART1_RX_vect){ + //TIMSK3=0; + TCNT3=0; // Timeout Timer3 On, clkI/O/8 (From prescaller) + TCCR3B=2; + TIMSK3=1< Z + USART1_RX_DDR&=~(1< Z + USART1_DRE_DDR&=~(1< 0 + + UCSR1A=(1< USART1_BUF_SIZE) ) { return; } + USART1_TX_DDR|=1< out + USART1_DRE_DDR|=1< +#include "Common/IDIBUS_DEFS.h" +#include +#include +#include "USART_COM.h" +//#include +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +volatile USART_HANDLER_TYPE USART1STR; //Do not remove volatile!!! +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define USART1_BUF_SIZE IDIMMES_MAX_MES_SIZE + 1 // Buffer size +volatile uint8_t USART1_RX_BUF[USART1_BUF_SIZE]; // RX buffer +volatile uint8_t USART1_TX_BUF[USART1_BUF_SIZE]; // TX buffer + +void USART1_Init(void); + +//inline void USART1_IRQN_HANDLER(void); +//inline void USART1_RX_TIMER_HANDLER(void); + +void USART1_SendTxBuf(uint16_t Count); +//uint8_t USART1_IsNewRxMessage(void); +//uint8_t USART1_IsRxError(void); +//uint16_t USART1_getRxBufSize(void); +//uint8_t *USART1_getRxBuf(void); +//uint8_t *USART1_getTxBuf(void); +void USART1_RxTransferRestart(void); +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART1_copyRxBuf(uint8_t *Dst, uint16_t StartPos, uint16_t Count); + +//#define USART1_copyRxBuf(Dst,StartPos,Count) _memcopy(&USART1_RX_BUF[StartPos],Dst,Count); +// void USART1_copyRxBuf(uint8_t *Dst, uint16_t StartPos, uint16_t Count) { _memcopy(&USART1_RX_BUF[StartPos], Dst,Count); } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t USART1_IsTxActive(void); +//#define USART1_IsTxActive() (USART1STR.TxComplete == 1 ? 0 : 1) +//uint8_t USART1_IsTxActive(void){ +// if (USART1STR.TxComplete) return 0; +// else return 1; +//} + +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define USART1_IsNewRxMessage() USART1STR.RxComplete +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define USART1_IsRxError() USART1STR.RxError +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define USART1_getRxBufSize() USART1STR.RxBufCount +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define USART1_getRxBuf() &USART1_RX_BUF[0] +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define USART1_getTxBuf() &USART1_TX_BUF[0] +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART1_SetIdiBusBoudrate(enum IDIBUS_SERIAL_BAUDRATE BoudrateCode); +//void USART1_RxAlarmFrameStart(void); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif /* USART1_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/USART_COM.h b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/USART_COM.h new file mode 100644 index 0000000..7b511a6 --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/idiBus/USART_COM.h @@ -0,0 +1,41 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_USART_COM_H_ +#define _INC_USART_COM_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//#include "stm32f4xx.h" +#include +////#include +#include "System.h" +//#include "CUST_GPIO.h" +//#include "TIMERS.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define F_CPU 16000000UL +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#ifdef _CPU_ATMEGA328PB_ //Maybe move this + #include "m328pb_defs.h" +#endif // #ifdef _CPU_ATMEGA328PB_ +#ifdef _CPU_ATMEGA2560_ + #include "m2560_defs.h" +#endif // _CPU_ATMEGA2560_ + +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct { + //USART_TypeDef *USART; + //DMA_Stream_TypeDef *DMATX; + + volatile uint16_t TxBufCount; + //uint16_t TxPacketSize; + uint16_t TxSendedCount; + volatile uint16_t RxBufCount; + + uint16_t InterFrameTimeoutTicks; + + volatile uint8_t TxComplete; + volatile uint8_t RxError; + volatile uint8_t RxComplete; + +} USART_HANDLER_TYPE; + //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif //_INC_USART_COM_H_ +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/main.c b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/main.c new file mode 100644 index 0000000..d1de86c --- /dev/null +++ b/3xThermo1xHT/bootloaderFiles/idiBUS_bootloader/main.c @@ -0,0 +1,79 @@ +#include "config.h" + +#include "System.h" +#include "boot.h" +#include "USART1.h" +#include "RSLink.h" + +#include +FUSES={ .extended=F_Ext, .high = F_High, .low = F_Low }; // Fuses + Lock programming +LOCKBITS=F_Lock; + +int main(void) +{ + //FUSE CHECK + asm volatile ( + "ldi R31, 0x00 \n\t" + "ldi R30, 0x01 \n\t" + "ldi R16, 0x09 \n\t" + "out 0x37, R16 \n\t" + "lpm R17, Z \n\t" + "cpi R17, %0 \n\t" + "brne L_LOOP_%= \n\t" + // Fuse Extended + "ldi R30, 0x02 \n\t" + "out 0x37, R16 \n\t" + "lpm R17, Z \n\t" + "cpi R17, %1 \n\t" + "brne L_LOOP_%= \n\t" + // Fuse Low Byte + "ldi R30, 0x00 \n\t" + "out 0x37, R16 \n\t" + "lpm R17, Z \n\t" + "cpi R17, %2 \n\t" + "brne L_LOOP_%= \n\t" + // Fuse Hi Byte + "ldi R30, 0x03 \n\t" + "out 0x37, R16 \n\t" + "lpm R17, Z \n\t" + "cpi R17, %3 \n\t" + "breq L_EXIT_%= \n\t" + "L_LOOP_%=: \n\t" + "rjmp L_LOOP_%= \n\t" + "L_EXIT_%=: \n\t" + : //No output + : "M" (F_Lock), + "M" (F_Ext), + "M" (F_Low), + "M" (F_High) + ); + + wdt_enable(WDTO_2S); + wdt_reset(); + + //Move interrupt table + uint8_t temp = MCUCR; + MCUCR=temp|(1< EEPROM_BUF_SIZE || count == 0) { + IDIBUS_MODULE.LONG_OP.State = IDILONGOP_STATE_COMPLETE_WITH_ERR; //isThisSafe???!!! + IDIBUS_MODULE.LONG_OP.Switch = 0; + IDIBUS_MODULE.LONG_OP.Type = IDIBUS_LONGOP_NOPE; + return; + } + EEPROM_BUF_COUNT = count; + EEPROM_ADDR = addr; + IDIBUS_MODULE.LONG_OP.Switch = 1; + + while (1) { + if (EEPROM_BUF_COUNT == 0){ + IDIBUS_MODULE.LONG_OP.State = IDILONGOP_STATE_COMPLETE_NO_ERR; //isThisSafe???!!! + IDIBUS_MODULE.LONG_OP.Switch = 0; + IDIBUS_MODULE.LONG_OP.Type = IDIBUS_LONGOP_NOPE; + EECR &= ~(1< +#include +#include +#include "IDIBUS_IMPL.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define EEPROM_BUF_SIZE 32 +uint16_t EEPROM_ADDR; +uint8_t EEPROM_BUF[EEPROM_BUF_SIZE]; +uint8_t EEPROM_BUF_COUNT; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void EEPROM_WriteEepBuf(uint8_t count, uint16_t addr); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif /* EEPROM_FAST_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEM.c b/3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEM.c new file mode 100644 index 0000000..c45172e --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEM.c @@ -0,0 +1,35 @@ +//############################################################################################################################################################################################################# +#include "SYSTEM.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +volatile uint32_t SystemSystickCounter; +uint32_t System_GetSysTick(void) +{ + cli(); + uint32_t SystemSysTick_Temp = SystemSystickCounter; + sei(); + return SystemSysTick_Temp; +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint32_t HAL_GetTick(void) // redefine _weak HAL function For HAL Inits +{ + cli(); + uint32_t SystemSysTick_Temp = SystemSystickCounter; + sei(); + return SystemSysTick_Temp; +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint32_t System_GetSysTickDifference(uint32_t TimeInstance) +{ + cli(); + uint32_t SystemSysTick_Temp = SystemSystickCounter; + sei(); + if (TimeInstance<=SystemSysTick_Temp ) { return (uint32_t)(SystemSysTick_Temp-TimeInstance); } + else { return (uint32_t)(0xFFFFFFFF-TimeInstance+SystemSysTick_Temp); } +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void System_SWReboot(void){ + cli(); + wdt_enable(WDTO_15MS); + while(1); //Dumb reset +} +//############################################################################################################################################################################################################# \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEM.h b/3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEM.h new file mode 100644 index 0000000..cc921b4 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEM.h @@ -0,0 +1,30 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_SYSTEM_H_ +#define _INC_SYSTEM_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include +#include "config.h" +#include +#include +#include +#include +#include +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#ifdef _LONG_ADDR_SPACE_ + #define flash_read_byte(x,y) pgm_read_byte_far(x+y) + #define flash_read_word(x,y) pgm_read_word_far(x+y) + #define flash_read_dword(x,y) pgm_read_dword_far(x+y) +#else + #define flash_read_byte(x,y) pgm_read_byte(x+y) + #define flash_read_word(x,y) pgm_read_word(x+y) + #define flash_read_dword(x,y) pgm_read_dword(x+y) +#endif +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define System_GetTimeInstance() System_GetSysTick() +uint32_t System_GetSysTick(void); +uint32_t HAL_GetTick(void); +uint32_t System_GetSysTickDifference(uint32_t TimeInstance); +void System_SWReboot(void); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif // #ifndef _INC_SYSTEM_H_ +//############################################################################################################################################################################################################# \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEMCustom.c b/3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEMCustom.c new file mode 100644 index 0000000..7c0665f --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/CommonHW/SYSTEMCustom.c @@ -0,0 +1,32 @@ +//############################################################################################################################################################################################################# +#include "SYSTEMCustom.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void System_InitSysTick(void) +{ +SystemSystickCounter=0; +TCNT0=0xFF-250; // 1 ms +TCCR0B=0; // no clock +TIMSK0=0; // Overflow Interrupt Disable +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ISR(TIMER0_OVF_vect) // 1ms timer0 interrupt +{ +TCNT0=0xFF-250; // 1 ms +if (SystemSystickCounter==0xFFFFFFFF) SystemSystickCounter=0; else SystemSystickCounter++; +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void System_SystickTimerStart(void) +{ +SystemSystickCounter=0; +TCNT0=0xFF-250; // 1 ms +TCCR0B=3; // clkI/O/64 (from prescaller) +TIMSK0=1< +#include +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint32_t SystemSystickCounter; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void System_InitSysTick(void); +void System_SystickTimerStart(void); +void System_SystickTimerStop(void); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif // #ifndef _INC_SYSTEM_CUSTOM_H_ +//############################################################################################################################################################################################################# \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/CommonHW/USART0.c b/3xThermo1xHT/idiBusCoreFiles/CommonHW/USART0.c new file mode 100644 index 0000000..2bad265 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/CommonHW/USART0.c @@ -0,0 +1,135 @@ +#include "USART0.h" +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ISR(USART0_TX_vect){ + if (USART0STR.TxSendedCount == USART0STR.TxBufCount){ + *USART0STR.USART->UCRSB&=~((1<UDR=USART0STR.TX_BUF[USART0STR.TxSendedCount]; + USART0STR.TxSendedCount++; + } +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ISR(USART0_RX_vect){ + TIMSK4=0; TCNT4=0; // Timeout Timer4 On, clkI/O/8 (From prescaller) + TCCR4B=2; TIMSK4=1<UDR; + USART0STR.RxBufCount++; + } +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ISR(TIMER4_COMPA_vect) { + TCCR4B=0; TCNT4=0; TIMSK4=0; // Timeout TIMER3 off + *USART0STR.USART->UCRSB&=~((1< Z + USART0_RX_DDR&=~(1< Z + + *USART0STR.USART->UCRSA=0; + *USART0STR.USART->UCRSB=(1<UCRSC=(1<UBRR = (F_CPU/16UL)/Baudrate-1; + OCR4A = 4015; +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t USART0_IsNewRxMessage(void) { return USART0STR.RxComplete; } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t USART0_IsRxError(void) { return USART0STR.RxError; } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint16_t USART0_getRxBufSize(void) { return USART0STR.RxBufCount; } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +volatile uint8_t *USART0_getRxBuf(void) { return &USART0STR.RX_BUF[0]; } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +volatile uint8_t *USART0_getTxBuf(void) { return &USART0STR.TX_BUF[0]; } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART0_copyRxBuf(uint8_t *Dst, uint16_t StartPos, uint16_t Count) { memcpy(Dst, &USART0STR.RX_BUF[StartPos], Count); } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t USART0_IsTxActive(void){ + if (USART0STR.TxComplete) return 0; + else return 1; +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART0_SendByteBuf(uint8_t *Buf, uint16_t Count){ + if ( (!USART0STR.TxComplete) || (Count == 0) || (Count > USART0_BUF_SIZE) ) { return; } + memcpy(USART0STR.TX_BUF, Buf, Count); + USART0_TX_DDR|=1< out + USART0STR.TxComplete = 0; + USART0STR.TxBufCount = Count; + USART0STR.TxSendedCount = 1; + *USART0STR.USART->UCRSB|=(1<UDR = USART0STR.TX_BUF[0]; +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART0_SendTxBuf(uint16_t Count){ + if ( (!USART0STR.TxComplete) || (Count == 0) || (Count > USART0_BUF_SIZE) ) { return; } + USART0_TX_DDR|=1< out + USART0STR.TxComplete = 0; + USART0STR.TxBufCount = Count; + USART0STR.TxSendedCount = 1; + *USART0STR.USART->UCRSB|=(1<UDR = USART0STR.TX_BUF[0]; +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART0_RxTransferRestart(void){ + //USART0_RX_TIMER_STOP(); //We are already doing this in IRQ + //(void) USART0STR.USART->SR; + //(void) USART0STR.USART->DR; + *USART0STR.USART->UCRSB|=(1<CR1 |= (1U< +#include "USART_COM.h" +#include +#include +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +volatile USART_TypeDef USART0_ADR; +volatile USART_HANDLER_TYPE USART0STR; +volatile USART_INTERFACE_TYPE USART0_INTERFACE; +volatile USART_IDIBUS_ROUTINE_TYPE USART0_IDIBUS; +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define USART0_BUF_SIZE 64 // Buffer size +volatile uint8_t USART0_RX_BUF[USART0_BUF_SIZE]; // RX buffer +volatile uint8_t USART0_TX_BUF[USART0_BUF_SIZE]; // TX buffer + +void USART0_Init(void); +void USART0_SetBaudrate(uint32_t Boudrate); + +//inline void USART0_IRQN_HANDLER(void); +//inline void USART0_RX_TIMER_HANDLER(void); + +void USART0_SendByteBuf(uint8_t *Buf, uint16_t Count); +void USART0_SendTxBuf(uint16_t Count); +uint8_t USART0_IsTxActive(void); +uint8_t USART0_IsNewRxMessage(void); +uint8_t USART0_IsRxError(void); +uint16_t USART0_getRxBufSize(void); +void USART0_copyRxBuf(uint8_t *Dst, uint16_t StartPos, uint16_t Count); +volatile uint8_t *USART0_getRxBuf(void); +volatile uint8_t *USART0_getTxBuf(void); +void USART0_RxTransferRestart(void); +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif /* USART0_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/CommonHW/USART1.c b/3xThermo1xHT/idiBusCoreFiles/CommonHW/USART1.c new file mode 100644 index 0000000..f23e8c2 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/CommonHW/USART1.c @@ -0,0 +1,163 @@ +#include "USART1.h" + +// USARTs common settings : Speed and Timeouts +const uint16_t USART_UBRR[8] PROGMEM={ (F_CPU/8UL)/19200-1, (F_CPU/8UL)/500000-1, + (F_CPU/8UL)/2400-1, (F_CPU/8UL)/9600-1, + (F_CPU/8UL)/115200-1, (F_CPU/8UL)/250000-1, + (F_CPU/8UL)/1000000-1, /*(F_CPU/8UL)/10000000-1*/ 0}; // Fosc=16MHz : 19.2k, 500k, 2.4k, 9.6k, 115.2k, 250k, 1M, 1M +const uint16_t USART_TIMEOUT[8] PROGMEM={ (IDIBUS_19200B_INTERFRAME_TIMEOUT_US/8*16), (IDIBUS_500K_INTERFRAME_TIMEOUT_US/8*16), + (IDIBUS_2400B_INTERFRAME_TIMEOUT_US/8*16), (IDIBUS_9600B_INTERFRAME_TIMEOUT_US/8*16), + (IDIBUS_115200B_INTERFRAME_TIMEOUT_US/8*16), (IDIBUS_250K_INTERFRAME_TIMEOUT_US/8*16), + (IDIBUS_1M_INTERFRAME_TIMEOUT_US/8*16), (IDIBUS_1M_INTERFRAME_TIMEOUT_US/8*16) }; +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ISR(USART1_TX_vect){ + if (USART1STR.TxSendedCount == USART1STR.TxBufCount){ + *USART1STR.USART->UCRSB |= (1<UCRSB &= ~((1< Z + USART1_DRE_DDR&=~(1< 0 + } else { + *USART1STR.USART->UDR=USART1STR.TX_BUF[USART1STR.TxSendedCount]; + USART1STR.TxSendedCount++; + } +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ISR(USART1_RX_vect){ + TIMSK3=0; TCNT3=0; // Timeout Timer3 On, clkI/O/8 (From prescaller) + TCCR3B=2; TIMSK3=1<UCRSA & ((1<UDR; + USART1STR.RxBufCount++; + } +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ISR(TIMER3_COMPA_vect) { + TCCR3B=0; TCNT3=0; TIMSK3=0; // Timeout TIMER3 off + *USART1STR.USART->UCRSB&=~((1< Z + USART1_RX_DDR&=~(1< Z + USART1_DRE_DDR&=~(1< 0 + + *USART1STR.USART->UCRSA=(1<UCRSB=(1<UCRSC=(1<UBRR = (F_CPU/16UL)/Baudrate-1; +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t USART1_IsNewRxMessage(void) { return USART1STR.RxComplete; } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t USART1_IsRxError(void) { return USART1STR.RxError; } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint16_t USART1_getRxBufSize(void) { return USART1STR.RxBufCount; } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t *USART1_getRxBuf(void) { return &USART1STR.RX_BUF[0]; } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t *USART1_getTxBuf(void) { return &USART1STR.TX_BUF[0]; } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART1_copyRxBuf(uint8_t *Dst, uint16_t StartPos, uint16_t Count) { memcpy(Dst, &USART1STR.RX_BUF[StartPos], Count); } +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t USART1_IsTxActive(void){ + if (USART1STR.TxComplete) return 0; + else return 1; +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART1_SetIdiBusBoudrate(enum IDIBUS_SERIAL_BAUDRATE BoudrateCode){ + *USART1STR.USART->UBRR = pgm_read_word(&USART_UBRR[BoudrateCode]); + USART1STR.InterFrameTimeoutTicks = pgm_read_word(&USART_TIMEOUT[BoudrateCode]); + OCR3A = USART1STR.InterFrameTimeoutTicks; +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART1_SendByteBuf(uint8_t *Buf, uint16_t Count){ + if ( (!USART1STR.TxComplete) || (Count == 0) || (Count > USART1_BUF_SIZE) ) { return; } + memcpy(USART1STR.TX_BUF, Buf, Count); + USART1_TX_DDR|=1< out + USART1_DRE_DDR|=1<UCRSB&=~((1<UCRSB|=(1<UDR = USART1STR.TX_BUF[0]; +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART1_SendTxBuf(uint16_t Count){ + if ( (!USART1STR.TxComplete) || (Count == 0) || (Count > USART1_BUF_SIZE) ) { return; } + USART1_TX_DDR|=1< out + USART1_DRE_DDR|=1<UCRSB&=~((1<UCRSB|=(1<UDR = USART1STR.TX_BUF[0]; +} +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART1_RxTransferRestart(void){ + //USART1_RX_TIMER_STOP(); //We are already doing this in IRQ + //(void) USART1STR.USART->SR; + //(void) USART1STR.USART->DR; + *USART1STR.USART->UCRSB|=(1<CR1 |= (1U< +#include "USART_COM.h" +#include +#include +#include +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +volatile USART_TypeDef USART1_ADR; +volatile USART_HANDLER_TYPE USART1STR; +volatile USART_INTERFACE_TYPE USART1_INTERFACE; +volatile USART_IDIBUS_ROUTINE_TYPE USART1_IDIBUS; +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define USART1_BUF_SIZE IDIMMES_MAX_MES_SIZE + 1 // Buffer size +volatile uint8_t USART1_RX_BUF[USART1_BUF_SIZE]; // RX buffer +volatile uint8_t USART1_TX_BUF[USART1_BUF_SIZE]; // TX buffer + +void USART1_Init(void); +void USART1_SetBaudrate(uint32_t Boudrate); + +//inline void USART1_IRQN_HANDLER(void); +//inline void USART1_RX_TIMER_HANDLER(void); + +void USART1_SendByteBuf(uint8_t *Buf, uint16_t Count); +void USART1_SendTxBuf(uint16_t Count); +uint8_t USART1_IsTxActive(void); +uint8_t USART1_IsNewRxMessage(void); +uint8_t USART1_IsRxError(void); +uint16_t USART1_getRxBufSize(void); +void USART1_copyRxBuf(uint8_t *Dst, uint16_t StartPos, uint16_t Count); +uint8_t *USART1_getRxBuf(void); +uint8_t *USART1_getTxBuf(void); +void USART1_RxTransferRestart(void); +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void USART1_SetIdiBusBoudrate(enum IDIBUS_SERIAL_BAUDRATE BoudrateCode); +void USART1_RxAlarmFrameStart(void); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif /* USART1_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/CommonHW/USART_COM.h b/3xThermo1xHT/idiBusCoreFiles/CommonHW/USART_COM.h new file mode 100644 index 0000000..978273f --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/CommonHW/USART_COM.h @@ -0,0 +1,71 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_USART_COM_H_ +#define _INC_USART_COM_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//#include "stm32f4xx.h" +#include +#include +//#include "SYSTEM.h" +//#include "CUST_GPIO.h" +//#include "TIMERS.h" +#include "Common/IDIBUS_DEFS.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#ifdef _CPU_ATMEGA328PB_ //Maybe move this + #include "m328pb_defs.h" +#endif // #ifdef _CPU_ATMEGA328PB_ +#ifdef _CPU_ATMEGA2560_ + #include "m2560_defs.h" +#endif // _CPU_ATMEGA2560_ + +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct { + volatile uint8_t *UCRSA; + volatile uint8_t *UCRSB; + volatile uint8_t *UCRSC; + volatile uint16_t *UBRR; + volatile uint8_t *UDR; + } USART_TypeDef; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct { + volatile USART_TypeDef *USART; + //DMA_Stream_TypeDef *DMATX; + + uint8_t *TX_BUF; + uint8_t *RX_BUF; + uint16_t TxBufCount; + //uint16_t TxPacketSize; + uint16_t TxSendedCount; + uint16_t RxBufCount; + + volatile uint8_t TxComplete; + uint8_t RxError; + uint8_t RxComplete; + + uint16_t InterFrameTimeoutTicks; //Currently there are ticks for timer +} USART_HANDLER_TYPE; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct { + void (*SetNewBaudrate)(uint32_t); + void (*SendByteBuf)(uint8_t*, uint16_t); + void (*SendTxBuf)(uint16_t); + uint8_t (*IsNewRxMessage)(void); + uint8_t (*IsTxActive)(void); + uint8_t (*IsRxError)(void); + uint16_t (*getRxBufSize)(void); + void (*copyRxBuf)(uint8_t*, uint16_t, uint16_t); + uint8_t* (*getRxBuf)(void); + uint8_t* (*getTxBuf)(void); + void (*RxTransferRestart)(void); + } USART_INTERFACE_TYPE; + //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct { + uint8_t TimerMode; + uint16_t ResponseTimeoutUS; + uint16_t AlarmTimeoutUS; + volatile uint8_t ResponseTimeoutComplete; + void (*SetIdiBusBoudrate)(enum IDIBUS_SERIAL_BAUDRATE); + void (*RxAlarmFrameStart)(void); +} USART_IDIBUS_ROUTINE_TYPE; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif //_INC_USART_COM_H_ +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/idiBusCoreFiles/CommonHW/m2560_defs.h b/3xThermo1xHT/idiBusCoreFiles/CommonHW/m2560_defs.h new file mode 100644 index 0000000..7dd1406 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/CommonHW/m2560_defs.h @@ -0,0 +1,17 @@ + // USARTCUSTOM (FOR 2560) + #define USART1_TX_DDR DDRD + #define USART1_TX_PORT PORTD + #define USART1_TX_BIT 3 + #define USART1_RX_DDR DDRD + #define USART1_RX_PORT PORTD + #define USART1_RX_BIT 2 + #define USART1_DRE_DDR DDRD + #define USART1_DRE_PORT PORTD + #define USART1_DRE_BIT 4 + // USARTCUSTOM (FOR 2560) + #define USART0_TX_DDR DDRE + #define USART0_TX_PORT PORTE + #define USART0_TX_BIT 1 + #define USART0_RX_DDR DDRE + #define USART0_RX_PORT PORTE + #define USART0_RX_BIT 0 \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/CommonHW/m328pb_defs.h b/3xThermo1xHT/idiBusCoreFiles/CommonHW/m328pb_defs.h new file mode 100644 index 0000000..9cf6a51 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/CommonHW/m328pb_defs.h @@ -0,0 +1,19 @@ + //USART CUSTOM (FOR 328pb) + #define USART0_TX_DDR DDRD + #define USART0_TX_PORT PORTD + #define USART0_TX_BIT 1 + #define USART0_RX_DDR DDRD + #define USART0_RX_PORT PORTD + #define USART0_RX_BIT 0 + + //USART CUSTOM (FOR 328pb) + #define USART1_TX_DDR DDRB + #define USART1_TX_PORT PORTB + #define USART1_TX_BIT 3 + #define USART1_RX_DDR DDRB + #define USART1_RX_PORT PORTB + #define USART1_RX_BIT 4 + #define USART1_DRE_DDR DDRB + #define USART1_DRE_PORT PORTB + #define USART1_DRE_BIT 5 + diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiBus/Common/IDIBUS_DEFS.h b/3xThermo1xHT/idiBusCoreFiles/IdiBus/Common/IDIBUS_DEFS.h new file mode 100644 index 0000000..058b70b --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiBus/Common/IDIBUS_DEFS.h @@ -0,0 +1,456 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_IDIBUS_DEFS_H_ +#define _INC_IDIBUS_DEFS_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include + +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define F_CPU 16000000UL +#define MODBUS_CRC16_SIZE 2 +#define CRC32_SIZE 4 +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define IDIBUS_BAUDRATE_DSW_CODE_19200B 0x00 +#define IDIBUS_BAUDRATE_DSW_CODE_500K 0x01 +#define IDIBUS_BAUDRATE_DSW_CODE_2400B 0x02 +#define IDIBUS_BAUDRATE_DSW_CODE_9600B 0x03 +#define IDIBUS_BAUDRATE_DSW_CODE_115200B 0x04 +#define IDIBUS_BAUDRATE_DSW_CODE_250K 0x05 +#define IDIBUS_BAUDRATE_DSW_CODE_1M 0x06 +#define IDIBUS_BAUDRATE_DSW_CODE_10M 0x07 + +// Full timeout will be (InterframeTimeout + ResponseTimeout) for request(Write + Read) or InterframeTimeout for write(Write only) +#define IDIBUS_2400B_INTERFRAME_TIMEOUT_US 16042ULL //11 * 3.5 / Baudrate +#define IDIBUS_9600B_INTERFRAME_TIMEOUT_US 4011ULL +#define IDIBUS_19200B_INTERFRAME_TIMEOUT_US 2006ULL +#define IDIBUS_115200B_INTERFRAME_TIMEOUT_US 1750ULL +#define IDIBUS_250K_INTERFRAME_TIMEOUT_US 1750ULL +#define IDIBUS_500K_INTERFRAME_TIMEOUT_US 1750ULL +#define IDIBUS_1M_INTERFRAME_TIMEOUT_US 1750ULL +#define IDIBUS_10M_INTERFRAME_TIMEOUT_US 1750ULL + +#define IDIBUS_2400B_ALARM_TIMEOUT_US 34375ULL //11 * 3.5 / Baudrate +#define IDIBUS_9600B_ALARM_TIMEOUT_US 8594ULL +#define IDIBUS_19200B_ALARM_TIMEOUT_US 4297ULL +#define IDIBUS_115200B_ALARM_TIMEOUT_US 1750ULL +#define IDIBUS_250K_ALARM_TIMEOUT_US 1750ULL +#define IDIBUS_500K_ALARM_TIMEOUT_US 1750ULL +#define IDIBUS_1M_ALARM_TIMEOUT_US 1750ULL +#define IDIBUS_10M_ALARM_TIMEOUT_US 1750ULL + +#define IDIBUS_2400B_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_2400B_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_9600B_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_9600B_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_19200B_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_19200B_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_115200B_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_115200B_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_250K_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_250K_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_500K_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_500K_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_1M_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_1M_INTERFRAME_TIMEOUT_US * 3 / 2 ) +#define IDIBUS_10M_MASTER_RESPONSE_TIMEOUT_US (IDIBUS_10M_INTERFRAME_TIMEOUT_US * 3 / 2 ) + +#define IDIBUS_2400B_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_2400B_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_9600B_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_9600B_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_19200B_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_19200B_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_115200B_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_115200B_INTERFRAME_TIMEOUT_US) +#define IDIBUS_250K_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_250K_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_500K_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_500K_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_1M_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_1M_INTERFRAME_TIMEOUT_US ) +#define IDIBUS_10M_SLAVE_RESPONSE_TIMEOUT_US (IDIBUS_10M_INTERFRAME_TIMEOUT_US ) + + +enum IDIBUS_SERIAL_BAUDRATE { + IDIBUS_BAUDRATE_2400 = IDIBUS_BAUDRATE_DSW_CODE_2400B, + IDIBUS_BAUDRATE_9600 = IDIBUS_BAUDRATE_DSW_CODE_9600B, + IDIBUS_BAUDRATE_19200 = IDIBUS_BAUDRATE_DSW_CODE_19200B, + IDIBUS_BAUDRATE_115200 = IDIBUS_BAUDRATE_DSW_CODE_115200B, + IDIBUS_BAUDRATE_250K = IDIBUS_BAUDRATE_DSW_CODE_250K, + IDIBUS_BAUDRATE_500K = IDIBUS_BAUDRATE_DSW_CODE_500K, + IDIBUS_BAUDRATE_1M = IDIBUS_BAUDRATE_DSW_CODE_1M, + IDIBUS_BAUDRATE_10M = IDIBUS_BAUDRATE_DSW_CODE_10M + }; + +#define IDIBUS_LINK_LED_NO_MMES_TIMEOUT_0_SEC 60U +#define IDIBUS_LINK_LED_NO_MMES_TIMEOUT_0_MS ( IDIBUS_LINK_LED_NO_MMES_TIMEOUT_0_SEC * 1000U ) +#define IDIBUS_LINK_LED_NO_MMES_TIMEOUT_1_SEC 15U +#define IDIBUS_LINK_LED_NO_MMES_TIMEOUT_1_MS ( IDIBUS_LINK_LED_NO_MMES_TIMEOUT_1_SEC * 1000U ) + +enum IDIBUS_RXTIMER_TIMEOUT_MODE { + IDIBUS_TIMER_MODE_RX_TIMEOUT = 0x00, + IDIBUS_TIMER_MODE_ALARM_TIMEOUT, + IDIBUS_TIMER_MODE_RESPONSE_TIMEOUT +}; +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDISN_FIXP_Pos 1U //Internal padding +#define IDISN_FIXP_GS1_COUNTRY_Pos ( IDISN_FIXP_Pos + 0U) +#define IDISN_FIXP_GS1_COUNTRY_Length 3 +#define IDISN_FIXP_GS1_COMPANY_Pos ( IDISN_FIXP_GS1_COUNTRY_Pos + IDISN_FIXP_GS1_COUNTRY_Length ) +#define IDISN_FIXP_GS1_COMPANY_Length 6 +#define IDISN_FIXP_MODULE_TYPE_Pos ( IDISN_FIXP_GS1_COMPANY_Pos + IDISN_FIXP_GS1_COMPANY_Length ) +#define IDISN_FIXP_MODULE_TYPE_Length 3 +#define IDISN_FIXP_HW_REV_Pos ( IDISN_FIXP_MODULE_TYPE_Pos + IDISN_FIXP_MODULE_TYPE_Length ) +#define IDISN_FIXP_HW_REV_Length 2 +#define IDISN_FIXP_SERIAL_Pos ( IDISN_FIXP_HW_REV_Pos + IDISN_FIXP_HW_REV_Length ) +#define IDISN_FIXP_SERIAL_Length 7 +#define IDISN_FIXP_MAC_Pos ( IDISN_FIXP_SERIAL_Pos + IDISN_FIXP_SERIAL_Length ) +#define IDISN_FIXP_MAC_Length 6 +#define IDISN_FIXP_SW_REV_Pos ( IDISN_FIXP_MAC_Pos + IDISN_FIXP_MAC_Length ) +#define IDISN_FIXP_SW_REV_Length 2 +#define IDISN_FIXP_LENGTH ( IDISN_FIXP_GS1_COUNTRY_Length + IDISN_FIXP_GS1_COMPANY_Length + IDISN_FIXP_MODULE_TYPE_Length + \ + IDISN_FIXP_HW_REV_Length + IDISN_FIXP_SERIAL_Length + IDISN_FIXP_MAC_Length + IDISN_FIXP_SW_REV_Length ) + +#define IDISN_VARP_Pos 0 //IDISN_FIXP_LENGTH +#define IDISN_VARP_VERIF_DATE_Pos ( IDISN_VARP_Pos ) +#define IDISN_VARP_VERIF_DATE_Length 4U +#define IDISN_VARP_EXPIR_DATE_Pos ( IDISN_VARP_VERIF_DATE_Pos + IDISN_VARP_VERIF_DATE_Length ) +#define IDISN_VARP_EXPIR_DATE_Length 4U +#define IDISN_VARP_IPv4_Pos ( IDISN_VARP_EXPIR_DATE_Pos + IDISN_VARP_EXPIR_DATE_Length ) +#define IDISN_VARP_IPv4_Length 4U +#define IDISN_VARP_IPv6_Pos ( IDISN_VARP_IPv4_Pos + IDISN_VARP_IPv4_Length ) +#define IDISN_VARP_IPv6_Length 16U +#define IDISN_VARP_AES256_Pos ( IDISN_VARP_IPv6_Pos + IDISN_VARP_IPv6_Length ) +#define IDISN_VARP_AES256_Length 32U +#define IDISN_VARP_LENGTH ( IDISN_VARP_VERIF_DATE_Length + IDISN_VARP_EXPIR_DATE_Length + \ + IDISN_VARP_IPv4_Length + IDISN_VARP_IPv6_Length + IDISN_VARP_AES256_Length ) + +#define IDISN_FULL_LENGTH ( IDISN_FIXP_LENGTH + IDISN_VARP_LENGTH ) +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define ISIBUS_MASTER_MAIN_ADDR 255U +#define ISIBUS_MASTER_SPARE_ADDR 254U +#define IDIBUS_SLAVE_ADDR_MIN 1U +#define IDIBUS_SLAVE_ADDR_MAX 229U +#define IDIBUS_DEVELOPER_ADDR_0 250U +#define IDIBUS_DEVELOPER_ADDR_1 251U +#define IDIBUS_DEVELOPER_ADDR_2 252U +#define IDIBUS_DEVELOPER_ADDR_3 253U +#define IDIBUS_GROUP_0_ADDR 230U +#define IDIBUS_GROUP_1_ADDR 231U +#define IDIBUS_GROUP_2_ADDR 232U +#define IDIBUS_GROUP_3_ADDR 233U +#define IDIBUS_GROUP_4_ADDR 234U +#define IDIBUS_GROUP_5_ADDR 235U +#define IDIBUS_GROUP_6_ADDR 236U +#define IDIBUS_GROUP_7_ADDR 237U +#define IDIBUS_GROUP_8_ADDR 238U +#define IDIBUS_GROUP_9_ADDR 239U +#define IDIBUS_GROUP_10_ADDR 240U +#define IDIBUS_GROUP_11_ADDR 241U +#define IDIBUS_GROUP_12_ADDR 242U +#define IDIBUS_GROUP_13_ADDR 243U +#define IDIBUS_GROUP_14_ADDR 244U +#define IDIBUS_GROUP_15_ADDR 245U + +#define IDIBUS_GROUPS_NUMBER 16U +#define IDIBUS_GROUP_FIRST_NUMBER 0U +#define IDIBUS_GROUP_LAST_NUMBER 15U +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDIMMES_ADDR_Pos 00U +#define IDIMMES_MMPS_Pos 01U +#define IDIMMES_MMPS_LONG_MES_Pos 0U +#define IDIMMES_MMPS_LONG_MES_Msk 0x01U +#define IDIMMES_MMPS_MES_TYPE_Pos 1U +#define IDIMMES_MMPS_MES_TYPE_Msk 0x02U +#define IDIMMES_MMPS_MES_TYPE_MMES 0x00U +#define IDIMMES_MMPS_MES_TYPE_MMESG 0x01U +#define IDIMMES_MMPS_FAST_FUNC_Pos 2U +#define IDIMMES_MMPS_FAST_FUNC_Msk 0x3CU +#define IDIMMES_MMPS_ALARM_FRAME_Pos 6U +#define IDIMMES_MMPS_ALARM_FRAME_Msk 0x40U +#define IDIMMES_MMPS_ENCRYPTED_AES_Pos 7U +#define IDIMMES_MMPS_ENCRYPTED_AES_Msk 0x80U +#define IDIMMES_DEV_Pos 02U +#define IDIMMES_DEV_NUM_Pos 0U +#define IDIMMES_DEV_NUM_Msk 0x1FU +#define IDIMMES_DEV_ALLCH_Pos 5U +#define IDIMMES_DEV_ALLCH_Msk 0x20U +#define IDIMMES_CHNL_Pos 03U +#define IDIMMES_CHNL_NUM_Pos 0U +#define IDIMMES_CHNL_NUM_Msk 0x7FU +#define IDIMMES_CHNL_ALLSAME_Pos 7U +#define IDIMMES_CHNL_ALLSAME_Msk 0x80U +#define IDIMMES_DATA_FUNC_COM_DATA_Pos 04U +#define IDIMMES_MAX_HEADER_LENGTH (IDIMMES_DATA_FUNC_COM_DATA_Pos + 1) +#define IDIMMES_MAX_DATA_SIZE 256U +#define IDIMMES_MAX_MES_SIZE (IDIMMES_MAX_DATA_SIZE + IDIMMES_MAX_HEADER_LENGTH + MODBUS_CRC16_SIZE) +#define IDIMMES_MIN_MES_SIZE (IDIMMES_DATA_FUNC_COM_DATA_Pos + MODBUS_CRC16_SIZE) + +#define IDIMMESG_DATA_COM_FUNC_Pos 02U +#define IDIMMESG_MAX_HEADER_LENGTH (IDIMMESG_DATA_COM_FUNC_Pos + 1) +#define IDIMMESG_MAX_DATA_SIZE IDIMMES_MAX_DATA_SIZE +#define IDIMMESG_MAX_MES_SIZE (IDIMMESG_MAX_DATA_SIZE + IDIMMESG_MAX_HEADER_LENGTH + MODBUS_CRC16_SIZE) +#define IDIMMESG_MODULE_MIN_MES_SIZE (IDIMMESG_DATA_COM_FUNC_Pos + 1 + MODBUS_CRC16_SIZE) +#define IDIMMESG_GROUP_MIN_MES_SIZE (IDIMMESG_DATA_COM_FUNC_Pos + MODBUS_CRC16_SIZE) + +#define IDIMMES_LMES_MSIZE_Pos 0U +#define IDIMMES_LMES_BSIZE_Pos (IDIMMES_LMES_MSIZE_Pos + 4U) +#define IDIMMES_LMES_IDENTIFIER_LENGTH (IDIMMES_LMES_BSIZE_Pos + 1U) +#define IDIMMES_LMES_BSIZE_256B 0U +#define IDIMMES_LMES_BSIZE_1K 1U +#define IDIMMES_LMES_BSIZE_4K 2U +#define IDIMMES_LMES_BSIZE_8K 3U +#define IDIMMES_LMES_BSIZE_16K 4U +#define IDIMMES_LMES_BSIZE_32K 5U +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDISMES_ADDR_Pos 00U +#define IDISMES_SMPS_Pos 01U +#define IDISMES_SMPS_ERROR_BIT_Pos 0U +#define IDISMES_SMPS_LONG_MES_Pos 1U +#define IDISMES_SMPS_LONG_OP_Pos 2U +#define IDISMES_ERROR_Pos 02U +#define IDISMES_DATA_Pos 03U +#define IDISMES_MAX_DATA_SIZE 256U +#define IDISMES_MIN_MES_SIZE (IDISMES_DATA_Pos + MODBUS_CRC16_SIZE) +#define IDISMES_MAX_MES_SIZE (IDISMES_DATA_Pos + IDISMES_MAX_DATA_SIZE + MODBUS_CRC16_SIZE) +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDILONGOP_STATE_COMPLETE_NO_ERR 0x00U +#define IDILONGOP_STATE_IN_PROC 0x01U +#define IDILONGOP_STATE_COMPLETE_WITH_ERR 0x02U +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define IDILONGOP_MES_DATA_LENGTH 5U +#define IDILONGOP_STATE_Pos 0U +#define IDILONGOP_REMAIN_TIME_Pos 1U +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDISTATUS_B0S_Pos 00U +#define IDISTATUS_B0S_ST_ERROR_Pos 0U +#define IDISTATUS_B0S_ST_STATE_Pos 1U +#define IDISTATUS_B0S_ST_STATE_Msk 0x07U +#define IDISTATUS_B0S_ST_STATE_StNoInit 0x00U +#define IDISTATUS_B0S_ST_STATE_StOperate 0x01U +#define IDISTATUS_B0S_ST_STATE_StFreeze 0x02U +#define IDISTATUS_B0S_ST_STATE_StVirtual 0x03U +#define IDISTATUS_B0S_ST_STATE_StFirmwareUpd 0x04U +#define IDISTATUS_B0S_ST_STATE_StReservedMaster 0x05U +#define IDISTATUS_B0S_ST_STATE_StBroken 0x06U +#define IDISTATUS_B0S_ST_STATE_StReserved0 0x07U +#define IDISTATUS_B0S_AES_SUPPORTED_Pos 4U +#define IDISTATUS_B0S_AES_INSTALLED_Pos 5U +#define IDISTATUS_B0S_SEND_ALARM_L0_Pos 6U +#define IDISTATUS_B0S_SEND_ALARM_L1_Pos 7U + +#define IDISTATUS_B1S_Pos 01U +#define IDISTATUS_B1S_MODULE_TYPE_Pos 0U +#define IDISTATUS_B1S_MODULE_TYPE_Msk 0x03U +#define IDISTATUS_B1S_MODULE_TYPE_Master 0x00U +#define IDISTATUS_B1S_MODULE_TYPE_SpareMaster 0x01U +#define IDISTATUS_B1S_MODULE_TYPE_Slave 0x02U +#define IDISTATUS_B1S_MODULE_TYPE_Bridge 0x03U +#define IDISTATUS_B1S_BRIDGE_CONNECTED_Pos 2U +#define IDISTATUS_B1S_SELF_INIT_Pos 3U +#define IDISTATUS_B1S_TIMEOUT_LED_Pos 4U +#define IDISTATUS_B1S_NO_MMES_TIMEOUT_Pos 5U +#define IDISTATUS_B1S_CATCH_ALARM_L0_Pos 6U +#define IDISTATUS_B1S_CATCH_ALARM_L1_Pos 7U + +#define IDISTATUS_SN_Pos 02U +#define IDISTATUS_LENGTH ( IDISTATUS_SN_Pos + IDISN_FULL_LENGTH ) +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDIMMES_NOT_FAST_FUNC 0U +#define IDIMMES_MAX_FAST_FUNC_NUM 15U +#define IDIMMES_COM_START_NUM 220U +#define IDIMMES_COM_C_Init 220U +#define IDIMMES_COM_C_ShtDown 221U +#define IDIMMES_COM_C_Freeze 222U +#define IDIMMES_COM_C_Resume 223U +#define IDIMMES_COM_C_Dummy 224U +#define IDIMMES_COM_C_AssignGroup 225U +#define IDIMMES_COM_C_SetAlarmL12 226U +#define IDIMMES_COM_C_SetAlarmL 227U +#define IDIMMES_COM_C_Virtual 228U +#define IDIMMES_COM_C_SyncReadChnl 229U +#define IDIMMES_COM_C_SyncRead 230U +#define IDIMMES_COM_C_SyncDoChnl 231U +#define IDIMMES_COM_C_SyncDo 232U +#define IDIMMES_COM_C_SyncClear 233U +#define IDIMMES_COM_C_BurstReadCnt 234U +#define IDIMMES_COM_C_BurstReadTime 235U +#define IDIMMES_COM_C_SendTimeDate 236U +#define IDIMMES_COM_C_MkTimedMaster 237U +#define IDIMMES_COM_C_EnterBootloader 238U //OUT OF SPEC !!! +//#define IDIMMES_COM_C_EndFmwUpd 239U +//#define IDIMMES_COM_C_FmwWrite 240U +#define IDIMMES_COM_C_ReadDevFullSN_MS 241U +#define IDIMMES_COM_C_WriteSnIPv4IPv6 242U +#define IDIMMES_COM_C_WriteSnVerifyDates 243U +#define IDIMMES_COM_C_WriteSnAES256 244U +#define IDIMMES_COM_C_SendLongMessage 245U +#define IDIMMES_COM_C_GetLondMessage 246U +#define IDIMMES_COM_C_DummyModule 247U +#define IDIMMES_COM_C_CheckModuleLongOp 248U +#define IDIMMES_COM_C_CheckChannelLongOp 249U +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDIER_MODBUS_NUM_START 1U +#define IDIER_MODBUS_NUM_END 9U +#define IDIER_MODULE_MASTER_NUM_START 10U +#define IDIER_MODULE_MASTER_NUM_END 32U +#define IDIER_MODULE_SLAVE_NUM_START 33U +#define IDIER_MODULE_SLAVE_NUM_END 71U +#define IDIER_MODULE_NUM_START IDIER_MODULE_MASTER_NUM_START +#define IDIER_MODULE_NUM_END IDIER_MODULE_SLAVE_NUM_END +#define IDIER_DEVICE_NUM_START 72U +#define IDIER_DEVICE_NUM_END 89U + +#define IDIER_NOPE 0U +#define MODBUSER_WRONGFUNC 1U +#define MODBUSER_WRONGADDR 2U +#define MODBUSER_WRONGDATA 3U +#define MODBUSER_BROKE 4U +#define MODBUSER_LONGCOMMAND 5U +#define MODBUSER_BUSY 6U +#define MODBUSER_CANTDOFUNC 7U +#define MODBUSER_EXTMEMORYERROR 8U +#define MODBUSER_RESERVED 9U +#define IDIERMST_INVALID_ADDR_NUM 10U +#define IDIERMST_INVALID_DEV_NUM 11U +#define IDIERMST_INVALID_CHN_NUM 12U +#define IDIERMST_INVALID_FUNC_NUM 13U +#define IDIERMST_INVALID_TX_REQUEST_FORMAT 14U +#define IDIERMST_INVALID_TX_PARAM 15U +#define IDIERMST_TX_MES 16U +#define IDIERMST_RCV_TIMEOUT 17U +#define IDIERMST_MES_RX_INTEGRITY 18U +#define IDIERMST_CRC 19U +#define IDIERMST_MULTIPLE_CRC 20U +#define IDIERMST_INVALID_RX_REQUEST_FORMAT 21U +#define IDIERMST_INVALID_RX_PARAM 22U +#define IDIERMST_RESEVED_23 23U +#define IDIERMST_RESEVED_24 24U +#define IDIERMST_RESEVED_25 25U +#define IDIERMST_RESEVED_26 26U +#define IDIERMST_RESEVED_27 27U +#define IDIERMST_EXTRA_28 28U +#define IDIERMST_EXTRA_29 29U +#define IDIERMST_EXTRA_30 30U +#define IDIERMST_EXTRA_31 31U +#define IDIERMST_EXTRA_32 32U +#define IDIERSLV_RESEVED_33 33U +#define IDIERSLV_ENCRYPTION_NOT_SUPPORTED 34U +#define IDIERSLV_ENCRYPTION_NOT_INSTALLED 35U +#define IDIERSLV_JUMBO_NOT_SUPPORTED 36U +#define IDIERSLV_UNSUPPORTED_FUNC_NUM 37U +#define IDIERSLV_INVALID_RX_REQUEST_FORMAT 38U +#define IDIERSLV_INVALID_RX_PARAM 39U +#define IDIERSLV_IN_FREEZE 40U +#define IDIERSLV_RESERVED_41 41U +#define IDIERSLV_RESERVED_42 42U +#define IDIERSLV_RESERVED_43 43U +#define IDIERSLV_RESERVED_44 44U +#define IDIERSLV_RESERVED_45 45U +#define IDIERSLV_EXTRA_46 46U +#define IDIERSLV_EXTRA_47 47U +#define IDIERSLV_EXTRA_48 48U +#define IDIERSLV_EXTRA_49 49U +#define IDIERSLV_EXTRA_50 50U +#define IDIERSLV_BROKE 51U +#define IDIERSLV_NO_FIRMWARE 52U +#define IDIERSLV_NO_INIT 53U +#define IDIERSLV_OVERHEAT 54U +#define IDIERSLV_INP_VOLTAGE 55U +#define IDIERSLV_BRIDGE_OVERFLOW 56U +#define IDIERSLV_BRIDGE_NOT_CONF 57U +#define IDIERSLV_VERIF_DATE 58U +#define IDIERSLV_RTC 59U +#define IDIERSLV_LONG_OP_IN_PROC 60U +#define IDIERSLV_RESERVED_61 61U +#define IDIERSLV_RESERVED_62 62U +#define IDIERSLV_RESERVED_63 63U +#define IDIERSLV_RESERVED_64 64U +#define IDIERSLV_RESERVED_65 65U +#define IDIERSLV_RESERVED_66 66U +#define IDIERSLV_EXTRA_67 67U +#define IDIERSLV_EXTRA_68 68U +#define IDIERSLV_EXTRA_69 69U +#define IDIERSLV_EXTRA_70 70U +#define IDIERSLV_EXTRA_71 71U +#define IDIERDEV_INVALID_DEV_NUM 72U +#define IDIERDEV_INVALID_CHN_NUM 73U +#define IDIERDEV_INVALID_FUNC_NUM 74U +#define IDIERDEV_LONG_OP_IN_PROC 75U +#define IDIERDEV_RESERVED_76 76U +#define IDIERDEV_PARAM_LOW_ST_TIMEOUT 77U +#define IDIERDEV_PARAM_HIGH_ST_TIMEOUT 78U +#define IDIERDEV_PARAM_NOT_CHANGE_TIMEOUT 79U +#define IDIERDEV_RESERVED_80 80U +#define IDIERDEV_RESERVED_81 81U +#define IDIERDEV_RESERVED_82 82U +#define IDIERDEV_RESERVED_83 83U +#define IDIERDEV_RESERVED_84 84U +#define IDIERDEV_RESERVED_85 85U +#define IDIERDEV_RESERVED_86 86U +#define IDIERDEV_RESERVED_87 87U +#define IDIERDEV_RESERVED_88 88U +#define IDIERDEV_RESERVED_89 89U + +#define IDIER_MULTIPLE_CRC_AVRBUF_SIZE 16U +#define IDIER_MULTIPLE_CRC_AVRBUF_THR 5U +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +#define IDIDATE_FORMAT_DAY_Pos 0U +#define IDIDATE_FORMAT_MONTH_Pos 1U +#define IDIDATE_FORMAT_CENTURY_Pos 2U +#define IDIDATE_FORMAT_YEAR99_Pos 3U +#define IDIDATE_FORMAT_LENGTH 4U + +#define IDITIME_FORMAT_SECONDS_Pos 0U +#define IDITIME_FORMAT_MINUTES_Pos 1U +#define IDITIME_FORMAT_HOURS_Pos 2U +#define IDITIME_FORMAT_TIMEZONE_Pos 3U +#define IDITIME_FORMAT_LENGTH 4U + +#define IDITIME_FORMAT_TIMEZONE_MIN (-12) +#define IDITIME_FORMAT_TIMEZONE_MAX 14 + +#define IDIMMES_C_DATETIME_TIME_Pos 0 +#define IDIMMES_C_DATETIME_DATE_Pos (IDIMMES_C_DATETIME_TIME_Pos + IDIDATE_FORMAT_LENGTH) +#define IDIMMES_C_DATETIME_LENGTH (IDIDATE_FORMAT_LENGTH + IDITIME_FORMAT_LENGTH) +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +typedef struct { + struct { + uint8_t StError : 1; + uint8_t StState : 3; + uint8_t AesSupported : 1; + uint8_t AesInstalled : 1; + uint8_t SendAlarmL0 : 1; + uint8_t SendAlarmL1 : 1; + } B0S; + struct { + uint8_t ModuleType : 2; + uint8_t BridgeConnected : 1; + uint8_t SelfInit : 1; + uint8_t TimeoutLed : 1; + uint8_t NoMMESTimeout : 1; + uint8_t CatchAlarmL0 : 1; + uint8_t CatchAlarmL1 : 1; + } B1S; + } IDISTATUS_STATE_TYPE; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct { + IDISTATUS_STATE_TYPE STATE; + #ifdef _LONG_ADDR_SPACE_ + volatile uint_farptr_t SNfix; + #else + volatile uint8_t *SNfix; + #endif + volatile uint8_t *SNvar; + //uint8_t SN[IDISN_FULL_LENGTH]; +} IDISTATUS_SLAVE_TYPE; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif //_INC_IDIBUS_DEFS_H_ +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiBus/Common/MEMORY.h b/3xThermo1xHT/idiBusCoreFiles/IdiBus/Common/MEMORY.h new file mode 100644 index 0000000..c00e6c2 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiBus/Common/MEMORY.h @@ -0,0 +1,33 @@ +#ifndef MEMORY_H_ +#define MEMORY_H_ +volatile typedef struct{ + volatile uint8_t Padding; + volatile uint8_t GS1_country[IDISN_FIXP_GS1_COUNTRY_Length]; + volatile uint8_t GS1_company[IDISN_FIXP_GS1_COMPANY_Length]; + volatile uint8_t ModuleType[IDISN_FIXP_MODULE_TYPE_Length]; + volatile uint8_t HW_revision[IDISN_FIXP_HW_REV_Length]; + volatile uint8_t SN[IDISN_FIXP_SERIAL_Length]; + volatile uint8_t MAC[IDISN_FIXP_MAC_Length]; + volatile uint8_t SW[IDISN_FIXP_SW_REV_Length]; //SW Version (Bootloader/App) + volatile uint32_t AppCRC; //Only in APP +} FLASH_DATABLOCK; +//Universal data block + +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#ifdef _BOOTLOADER_ +#include "BootVersion.h" +const volatile FLASH_DATABLOCK STATIC_DATA_BL __attribute__((section (".locationInBoot"))) = { + //STATIC PART + #include "device.cfg" + .SW = {BOOT_VERSION_MAJOR, BOOT_VERSION_MINOR} //Botloader version +}; +#endif +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define APP_VERSION +const volatile FLASH_DATABLOCK STATIC_DATA_APP __attribute__((section (".locationInApp"))) = { + //.AppCRC = 0x8d173a8c //CRC32 for empty flash + #include "device.cfg" + }; +#undef APP_VERSION +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif /* MEMORY_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiBus/IDIBUS_IMPL.c b/3xThermo1xHT/idiBusCoreFiles/IdiBus/IDIBUS_IMPL.c new file mode 100644 index 0000000..0b91dfa --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiBus/IDIBUS_IMPL.c @@ -0,0 +1,435 @@ +//############################################################################################################################################################################################################# +#include "IDIBUS_IMPL.h" +#include "EEMEM.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// At the request of the customer +volatile char IDUBUS_SPEC_FRAZE_RU[] = "НЕЛЕЗТЬ !!!"; +volatile char IDUBUS_SPEC_FRAZE_EN[] = "HANDS OFF !!!"; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#ifdef _LONG_ADDR_SPACE_ +void IDIBUS_ModuleInit(USART_INTERFACE_TYPE *USART_INTERFACE, uint_farptr_t PROGMEM_SN) +#else +void IDIBUS_ModuleInit(USART_INTERFACE_TYPE *USART_INTERFACE, uint8_t *PROGMEM_SN) +#endif +{ + if (IDUBUS_SPEC_FRAZE_RU[0]) {} + if (IDUBUS_SPEC_FRAZE_EN[0]) {} + + IDIBUS_MODULE.USI = USART_INTERFACE; + + IDIBUS_CustomInit(); + + IDIBUS_MODULE.FreezeMemState = IDISTATUS_B0S_ST_STATE_StOperate; + IDIBUS_MODULE.LONG_OP.Type = IDIBUS_LONGOP_NOPE; + IDIBUS_MODULE.LONG_OP.Switch = 0; + IDIBUS_MODULE.LONG_OP.State = IDILONGOP_STATE_COMPLETE_NO_ERR; + IDIBUS_MODULE.Error = IDIER_NOPE; + IDIBUS_MODULE.c_InitAssignGroup = IDIBUS_GROUP_0_ADDR; + + // SN read ------------------------------------------------------------------------------------------------------> + IDIBUS_MODULE.STATUS.SNfix = PROGMEM_SN; + IDIBUS_MODULE.STATUS.SNvar = &EEBLOCK.EEPROM_SN; + //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + uint8_t InitAssignGroup = eeprom_read_byte(&EEBLOCK.EEPROM_IDIBUS_InitGroup); + + if ( (InitAssignGroup > IDIBUS_GROUP_0_ADDR ) && (InitAssignGroup <= IDIBUS_GROUP_15_ADDR) ) + { + for (uint8_t Dev = 0; Dev < IDIBUS_MODULE.DevicesCount; Dev++) + { + for (uint8_t Ch = 0; Ch + switch ( IDIBUS_MODULE.LONG_OP.Type ) + { + case (IDIBUS_LONGOP_VARSN_IP_WRITE) : { + if (IDIBUS_MODULE.LONG_OP.Switch == 0){ + EEPROM_WriteEepBuf(IDISN_VARP_IPv4_Length+IDISN_VARP_IPv6_Length,&EEBLOCK.EEPROM_SN[IDISN_VARP_IPv4_Pos]); + } + break; } + + case (IDIBUS_LONGOP_VARSN_VERIF_EXP_WRITE) : { + if (IDIBUS_MODULE.LONG_OP.Switch == 0){ + EEPROM_WriteEepBuf(IDISN_VARP_EXPIR_DATE_Length+IDISN_VARP_VERIF_DATE_Length,&EEBLOCK.EEPROM_SN[IDISN_VARP_VERIF_DATE_Pos]); + } + break; } + + case (IDIBUS_LONGOP_VARSN_AES_WRITE) : { + if (IDIBUS_MODULE.LONG_OP.Switch == 0){ + EEPROM_WriteEepBuf(IDISN_VARP_AES256_Length,&EEBLOCK.EEPROM_SN[IDISN_VARP_AES256_Pos]); + } + break; } + + case (IDIBUS_LONGOP_INIT) : { + + if ( IDIBUS_MODULE.c_InitAssignGroup != IDIBUS_GROUP_0_ADDR ) + eeprom_write_byte(&EEBLOCK.EEPROM_IDIBUS_InitGroup,IDIBUS_MODULE.c_InitAssignGroup); + + uint8_t TimeoutMS = 200; + while ( (!eeprom_is_ready() || IDIBUS_MODULE.USI->IsTxActive()) && (TimeoutMS != 0) ) { TimeoutMS--; _delay_ms(1); } + System_SWReboot(); + break; } + + default : {} + } + + // Error Handler Routine ------------------------> + if ( IDIBUS_MODULE.LONG_OP.State == IDILONGOP_STATE_IN_PROC ) + { + if ( System_GetSysTickDifference(IDIBUS_MODULE.LONG_OP.StartTimeInstanceMS) > IDIBUS_MODULE.LONG_OP.DurationMS ) + { + // Long Operation terminate function + IDIBUS_MODULE.LONG_OP.State = IDILONGOP_STATE_COMPLETE_WITH_ERR; + IDIBUS_MODULE.LONG_OP.Type = IDIBUS_LONGOP_NOPE; + IDIBUS_MODULE.LONG_OP.Switch = 0; + } + } +} +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +void IDIBUS_ModuleCommandHandler(IDIBUS_FARG_TYPE *farg) +{ + // If there is special command we don't care about any error in this place + if ( (farg->ComFunc != IDIMMES_COM_C_Init) && (farg->ComFunc != IDIMMES_COM_C_ShtDown) && (farg->ComFunc != IDIMMES_COM_C_SetAlarmL) ) + { + // IF we somehow managed to come to the freeze state, we need to exit from freeze state + if ( IDIBUS_MODULE.STATUS.STATE.B0S.StState == IDISTATUS_B0S_ST_STATE_StFreeze ) + { + if ( farg->ComFunc != IDIMMES_COM_C_Resume ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_IN_FREEZE); return; } + } // If not special command or freeze but long Operation and command not DummyModule + else if ( IDIBUS_MODULE.Error != IDIER_NOPE ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIBUS_MODULE.Error); return; } + else if ( IDIBUS_MODULE.LONG_OP.State == IDILONGOP_STATE_IN_PROC ) + { + if ( farg->ComFunc != IDIMMES_COM_C_CheckModuleLongOp ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_LONG_OP_IN_PROC); return; } + } + } + + // There is no prohibited command if this place - just handle it + switch ( farg->ComFunc ) + { + case (IDIMMES_COM_C_DummyModule) : { + if ( farg->InpDataLength != 0 ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE); } + break; } + + case ( IDIMMES_COM_C_Init ) : { + if ( farg->InpDataLength > 1 ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else if ( (farg->InpDataLength == 1) && (farg->InpData[0] > IDIBUS_GROUP_LAST_NUMBER) ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_PARAM); } + //Some custom error???!! + //else if ( 0 /* CTRL_SelectedMode == _CTRL_MODE_MANUAL_ */ ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIBUS_CUSTDEF_ERCODE_NO_ACCESS); } + else + { + if ( farg->InpDataLength == 1 ) { IDIBUS_MODULE.c_InitAssignGroup = (uint8_t)( farg->InpData[0] + IDIBUS_GROUP_0_ADDR ); } + IDIBUS_MODULE.LONG_OP.Type = IDIBUS_LONGOP_INIT; + IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE); + } + break; } + + case ( IDIMMES_COM_C_ShtDown ) : { + if ( farg->InpDataLength != 0 ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + //Some custom error???!! + //else if ( 0 /* CTRL_SelectedMode == _CTRL_MODE_MANUAL_ */ ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIBUS_CUSTDEF_ERCODE_NO_ACCESS); } + else + { + //IDIBUS_CustomShutdown(); + IDIBUS_MODULE.STATUS.STATE.B0S.StState = IDISTATUS_B0S_ST_STATE_StNoInit; + IDIBUS_MODULE.Error = IDIERSLV_NO_INIT; + IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE); + } + break; } + + case (IDIMMES_COM_C_Freeze) : { + if ( farg->InpDataLength != 0 ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + IDIBUS_MODULE.FreezeMemState = IDIBUS_MODULE.STATUS.STATE.B0S.StState; + IDIBUS_MODULE.STATUS.STATE.B0S.StState = IDISTATUS_B0S_ST_STATE_StFreeze; + IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE); + } + break; } + + case (IDIMMES_COM_C_Resume) : { + if ( farg->InpDataLength != 0 ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + IDIBUS_MODULE.STATUS.STATE.B0S.StState = (uint8_t)(IDIBUS_MODULE.FreezeMemState & 0x07U); + IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIBUS_MODULE.Error); + } + break; } + + case (IDIMMES_COM_C_ReadDevFullSN_MS) : { + if ( farg->InpDataLength != 0 ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + uint8_t ResponseLength = IDISN_FULL_LENGTH - IDISN_VARP_AES256_Length + 2; + uint8_t Response[ResponseLength]; + Response[IDISTATUS_B0S_Pos] = (uint8_t) ( + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B0S.StError << IDISTATUS_B0S_ST_ERROR_Pos) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B0S.StState << IDISTATUS_B0S_ST_STATE_Pos) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B0S.AesSupported << IDISTATUS_B0S_AES_SUPPORTED_Pos) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B0S.AesInstalled << IDISTATUS_B0S_AES_INSTALLED_Pos) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B0S.SendAlarmL0 << IDISTATUS_B0S_SEND_ALARM_L0_Pos) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B0S.SendAlarmL1 << IDISTATUS_B0S_SEND_ALARM_L1_Pos) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B0S.StState << IDISTATUS_B0S_ST_STATE_Pos) ); + Response[IDISTATUS_B1S_Pos] = (uint8_t) ( + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B1S.ModuleType << IDISTATUS_B1S_MODULE_TYPE_Pos) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B1S.BridgeConnected << IDISTATUS_B1S_BRIDGE_CONNECTED_Pos ) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B1S.SelfInit << IDISTATUS_B1S_SELF_INIT_Pos ) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B1S.TimeoutLed << IDISTATUS_B1S_TIMEOUT_LED_Pos ) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B1S.NoMMESTimeout << IDISTATUS_B1S_NO_MMES_TIMEOUT_Pos ) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B1S.CatchAlarmL0 << IDISTATUS_B1S_CATCH_ALARM_L0_Pos ) | + ((uint8_t)IDIBUS_MODULE.STATUS.STATE.B1S.CatchAlarmL1 << IDISTATUS_B1S_CATCH_ALARM_L1_Pos ) ); + for (uint8_t pos=0; pos < IDISN_FIXP_LENGTH; pos++) {Response[IDISTATUS_SN_Pos+pos] = flash_read_byte(IDIBUS_MODULE.STATUS.SNfix,IDISN_FIXP_Pos+pos);} + for (uint8_t pos=0; pos < IDISN_VARP_LENGTH-IDISN_VARP_AES256_Length; pos++) {Response[IDISTATUS_SN_Pos+IDISN_FIXP_LENGTH+pos] = eeprom_read_byte(&IDIBUS_MODULE.STATUS.SNvar[pos]);} + IDIBUS_ResponseProtectedWrite(farg, Response, ResponseLength, IDIER_NOPE); + } + break; } + + case (IDIMMES_COM_C_CheckModuleLongOp) : { + if ( farg->InpDataLength != 0 ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + uint8_t Response[IDILONGOP_MES_DATA_LENGTH]; + Response[IDILONGOP_STATE_Pos] = IDIBUS_MODULE.LONG_OP.State; + uint32_t Countdown; + if ( IDIBUS_MODULE.LONG_OP.State == IDILONGOP_STATE_IN_PROC ) + { + uint32_t TimeFromStart = System_GetSysTickDifference(IDIBUS_MODULE.LONG_OP.StartTimeInstanceMS); + if ( IDIBUS_MODULE.LONG_OP.DurationMS > TimeFromStart ) { Countdown = IDIBUS_MODULE.LONG_OP.DurationMS - TimeFromStart; } + else { Countdown = 0; } + } + else { Countdown = 0; } + Response[IDILONGOP_REMAIN_TIME_Pos] = (uint8_t)(Countdown >> 24); + Response[IDILONGOP_REMAIN_TIME_Pos + 1] = (uint8_t)(Countdown >> 16); + Response[IDILONGOP_REMAIN_TIME_Pos + 2] = (uint8_t)(Countdown >> 8); + Response[IDILONGOP_REMAIN_TIME_Pos + 3] = (uint8_t)(Countdown); + IDIBUS_ResponseProtectedWrite(farg, Response, IDILONGOP_MES_DATA_LENGTH, IDIER_NOPE); + } + break; } + + case (IDIMMES_COM_C_SendTimeDate) : { + if ( farg->InpDataLength != IDIMMES_C_DATETIME_LENGTH ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + if ( + ( farg->InpData[IDIMMES_C_DATETIME_TIME_Pos + IDITIME_FORMAT_SECONDS_Pos] > 60U ) || + ( farg->InpData[IDIMMES_C_DATETIME_TIME_Pos + IDITIME_FORMAT_MINUTES_Pos] > 60U ) || + ( farg->InpData[IDIMMES_C_DATETIME_TIME_Pos + IDITIME_FORMAT_HOURS_Pos] > 23U ) || + ( (int8_t)farg->InpData[IDIMMES_C_DATETIME_TIME_Pos + IDITIME_FORMAT_TIMEZONE_Pos] > IDITIME_FORMAT_TIMEZONE_MAX ) || + ( (int8_t)farg->InpData[IDIMMES_C_DATETIME_TIME_Pos + IDITIME_FORMAT_TIMEZONE_Pos] < IDITIME_FORMAT_TIMEZONE_MIN ) || + ( farg->InpData[IDIMMES_C_DATETIME_DATE_Pos + IDIDATE_FORMAT_DAY_Pos] > 31 ) || + ( farg->InpData[IDIMMES_C_DATETIME_DATE_Pos + IDIDATE_FORMAT_DAY_Pos] == 0 ) || + ( farg->InpData[IDIMMES_C_DATETIME_DATE_Pos + IDIDATE_FORMAT_MONTH_Pos] > 31 ) || + ( farg->InpData[IDIMMES_C_DATETIME_DATE_Pos + IDIDATE_FORMAT_MONTH_Pos] == 0 ) || + ( farg->InpData[IDIMMES_C_DATETIME_DATE_Pos + IDIDATE_FORMAT_CENTURY_Pos] > 99 ) || + ( farg->InpData[IDIMMES_C_DATETIME_DATE_Pos + IDIDATE_FORMAT_YEAR99_Pos] > 99 ) + ) + { + IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_PARAM); + } + else { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE); } + } + break; } + + // LONG OPERATION FUNCS --------------------------------------------------------------> + case (IDIMMES_COM_C_WriteSnIPv4IPv6) : { + if ( farg->InpDataLength != (IDISN_VARP_IPv4_Length + IDISN_VARP_IPv6_Length) ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + memcpy(&EEPROM_BUF, farg->InpData, farg->InpDataLength); + IDIBUS_MODULE.LONG_OP.Type = IDIBUS_LONGOP_VARSN_IP_WRITE; + IDIBUS_MODULE.LONG_OP.Switch = 0; + IDIBUS_MODULE.LONG_OP.State = IDILONGOP_STATE_IN_PROC; + IDIBUS_MODULE.LONG_OP.StartTimeInstanceMS = System_GetTimeInstance(); + IDIBUS_MODULE.LONG_OP.DurationMS = IDIBUS_LONGOP_VARSN_IP_WRITE_DURATION_MS; + farg->LongOpState = 1; + IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE); + } + break; } + + case (IDIMMES_COM_C_WriteSnVerifyDates) : { + if ( farg->InpDataLength != (IDIDATE_FORMAT_LENGTH * 2) ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else if ( + (farg->InpData[IDIDATE_FORMAT_DAY_Pos] == 0)||(farg->InpData[IDIDATE_FORMAT_DAY_Pos] > 31) || + (farg->InpData[IDIDATE_FORMAT_MONTH_Pos] == 0 )||(farg->InpData[IDIDATE_FORMAT_MONTH_Pos] > 12) || + (farg->InpData[IDIDATE_FORMAT_CENTURY_Pos] > 99 ) || + (farg->InpData[IDIDATE_FORMAT_YEAR99_Pos] > 99) || + (farg->InpData[IDIDATE_FORMAT_DAY_Pos+IDIDATE_FORMAT_LENGTH] == 0)||(farg->InpData[IDIDATE_FORMAT_DAY_Pos+IDIDATE_FORMAT_LENGTH] > 31) || + (farg->InpData[IDIDATE_FORMAT_MONTH_Pos+IDIDATE_FORMAT_LENGTH] == 0 )||(farg->InpData[IDIDATE_FORMAT_MONTH_Pos+IDIDATE_FORMAT_LENGTH] > 12) || + (farg->InpData[IDIDATE_FORMAT_CENTURY_Pos+IDIDATE_FORMAT_LENGTH] > 99 ) || + (farg->InpData[IDIDATE_FORMAT_YEAR99_Pos+IDIDATE_FORMAT_LENGTH] > 99) + ) + { + IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_PARAM); + } + else { + //memcpy(&EEPROM_BUF, farg->InpData, (IDIDATE_FORMAT_LENGTH * 2)); + memcpy(&EEPROM_BUF, farg->InpData, farg->InpDataLength); + IDIBUS_MODULE.LONG_OP.Type = IDIBUS_LONGOP_VARSN_VERIF_EXP_WRITE; + IDIBUS_MODULE.LONG_OP.Switch = 0; + IDIBUS_MODULE.LONG_OP.State = IDILONGOP_STATE_IN_PROC; + IDIBUS_MODULE.LONG_OP.StartTimeInstanceMS = System_GetTimeInstance(); + IDIBUS_MODULE.LONG_OP.DurationMS = IDIBUS_LONGOP_VARSN_VERF_EXP_WRITE_DURATION_MS; + farg->LongOpState = 1; + IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE); + } + break; } + + case (IDIMMES_COM_C_WriteSnAES256) : { + if ( farg->InpDataLength != IDISN_VARP_AES256_Length ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + //!!!memcpy(&IDIBUS_MODULE.STATUS.SN[IDISN_VARP_AES256_Pos], farg->InpData, farg->InpDataLength); + memcpy(&EEPROM_BUF, farg->InpData, farg->InpDataLength); + IDIBUS_MODULE.LONG_OP.Type = IDIBUS_LONGOP_VARSN_AES_WRITE; + IDIBUS_MODULE.LONG_OP.Switch = 0; + IDIBUS_MODULE.LONG_OP.State = IDILONGOP_STATE_IN_PROC; + IDIBUS_MODULE.LONG_OP.StartTimeInstanceMS = System_GetTimeInstance(); + IDIBUS_MODULE.LONG_OP.DurationMS = IDIBUS_LONGOP_VARSN_AES_WRITE_DURATION_MS; + farg->LongOpState = 1; + IDIBUS_MODULE.STATUS.STATE.B0S.AesInstalled = 0; + for ( uint8_t I = 0; I < IDISN_VARP_AES256_Length; I++ ) + { + if ( /*IDIBUS_MODULE.STATUS.SN[IDISN_VARP_AES256_Pos + I] != 0 */ 0 /* TODO */ ) { IDIBUS_MODULE.STATUS.STATE.B0S.AesInstalled = 1; break; } + } + IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE); + } + break; } + case (IDIMMES_COM_C_EnterBootloader) : { + const uint8_t packageSize = IDISN_FIXP_MODULE_TYPE_Length+IDISN_FIXP_HW_REV_Length+IDISN_FIXP_SERIAL_Length; + if ( farg->InpDataLength != packageSize) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + uint8_t Check = 1; + for (uint8_t pos=0; pos < packageSize; pos++) { + if (farg->InpData[pos] != flash_read_byte(IDIBUS_MODULE.STATUS.SNfix,IDISN_FIXP_MODULE_TYPE_Pos+pos)) + Check = 0; + } + + if (Check == 1){ + IDIBUS_MODULE.LONG_OP.Type = IDIBUS_LONGOP_INIT; + eeprom_write_byte(&EEBLOCK.BOOTFLAG, 0xB0); + IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE); + } else { + IDIBUS_ResponseProtectedWrite(farg,NULL,0,IDIERSLV_INVALID_RX_PARAM); + } + } + break; } + + + default : { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_UNSUPPORTED_FUNC_NUM); } + } +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void IDIBUS_ChannelBackgroundHandler (void) +{ + + // Error Handler ------------------------> + for ( uint8_t Dev=0; Dev < IDIBUS_MODULE.DevicesCount; Dev++ ) + { + for ( uint8_t Ch=0; ChLONG_OP.State == IDILONGOP_STATE_IN_PROC ) + { + if ( System_GetSysTickDifference(CH->LONG_OP.StartTimeInstanceMS) > CH->LONG_OP.DurationMS ) + { + // Long Operation terminate function + CH->LONG_OP.State = IDILONGOP_STATE_COMPLETE_WITH_ERR; + CH->LONG_OP.Type = IDIBUS_LONGOP_NOPE; + } + } + } + } +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t IDIBUS_CnannelStaticFunc(struct IDIBUS_CHANNEL_STR* CH, IDIBUS_FARG_TYPE *farg) +{ + if ( CH->LONG_OP.State == IDILONGOP_STATE_IN_PROC ) + { + farg->LongOpState = 1; + if ( farg->ComFunc != IDIMMES_COM_C_CheckChannelLongOp ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERDEV_LONG_OP_IN_PROC); return 1; } + } + + if ( farg->ComFunc < IDIMMES_COM_START_NUM ) { return 0; } // If Not channel command + + switch (farg->ComFunc) + { + case (IDIMMES_COM_C_Dummy) : { + if ( farg->InpDataLength != 0 ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE); } + break; } + + case (IDIMMES_COM_C_AssignGroup) : { + if ( (farg->InpDataLength != 1) || (farg->InpData[0] > IDIBUS_GROUP_LAST_NUMBER) ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + CH->BcastAddr = (uint8_t)( farg->InpData[0] + IDIBUS_GROUP_0_ADDR ); + IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE); + } + break; } + + case (IDIMMES_COM_C_CheckChannelLongOp) : { + if ( farg->InpDataLength != 0 ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + uint8_t Response[IDILONGOP_MES_DATA_LENGTH]; + Response[IDILONGOP_STATE_Pos] = CH->LONG_OP.State; + uint32_t Countdown; + if ( CH->LONG_OP.State == IDILONGOP_STATE_IN_PROC ) + { + uint32_t TimeFromStart = System_GetSysTickDifference( CH->LONG_OP.StartTimeInstanceMS ); + if ( CH->LONG_OP.DurationMS > TimeFromStart ) { Countdown = CH->LONG_OP.DurationMS - TimeFromStart; } + else { Countdown = 0; } + } + else { Countdown = 0; } + Response[IDILONGOP_REMAIN_TIME_Pos] = (uint8_t)(Countdown >> 24); + Response[IDILONGOP_REMAIN_TIME_Pos + 1] = (uint8_t)(Countdown >> 16); + Response[IDILONGOP_REMAIN_TIME_Pos + 2] = (uint8_t)(Countdown >> 8); + Response[IDILONGOP_REMAIN_TIME_Pos + 3] = (uint8_t)(Countdown); + IDIBUS_ResponseProtectedWrite(farg, Response, IDILONGOP_MES_DATA_LENGTH, IDIER_NOPE); + } + break; } + + default : { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_UNSUPPORTED_FUNC_NUM); } + } + return 1; +} +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +void IDIBUS_ResponseProtectedWrite(IDIBUS_FARG_TYPE *farg, uint8_t *Data, uint16_t DataLength, uint8_t ErrorCode) +{ + if (farg->OutData != NULL) + { + if ( ErrorCode != IDIER_NOPE ) { IDIBUS_MODULE.STATUS.STATE.B0S.StError = 1; farg->ErrorState = 1; } + else { IDIBUS_MODULE.STATUS.STATE.B0S.StError = 0; } + farg->OutData[farg->ErrorPos] = ErrorCode; + farg->ErrorPos = (uint16_t)(farg->ErrorPos + 1); + farg->OutDataLength = (uint16_t)(farg->OutDataLength + 1); + + if ( (DataLength != 0) && (Data != NULL) ) + { + memcpy(&farg->OutData[farg->OutDataPos], Data, DataLength); + farg->OutDataPos = (uint16_t)( farg->OutDataPos + DataLength ); + farg->OutDataLength = (uint16_t)(farg->OutDataLength + DataLength); + } + } +} +//============================================================================================================================================================================================================= +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//============================================================================================================================================================================================================= +void IDIBUS_ServiceFunc (uint8_t *InpData, uint16_t InpDataLength, uint8_t *OutData, uint16_t *OutDataLength) +{ + +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiBus/IDIBUS_IMPL.h b/3xThermo1xHT/idiBusCoreFiles/IdiBus/IDIBUS_IMPL.h new file mode 100644 index 0000000..c2bc58b --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiBus/IDIBUS_IMPL.h @@ -0,0 +1,98 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_IDIBUS_IMPL_H_ +#define _INC_IDIBUS_IMPL_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include +#include "Common/IDIBUS_DEFS.h" +#include +#include +#include "SYSTEM.h" +#include "MODBUS_CRC.h" +#include "USART_COM.h" +#include "EEPROM_Fast.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +enum IDIBUS_MODULE_LONGOP_TYPES { + IDIBUS_LONGOP_NOPE = 0, + IDIBUS_LONGOP_VARSN_IP_WRITE, + IDIBUS_LONGOP_VARSN_VERIF_EXP_WRITE, + IDIBUS_LONGOP_VARSN_AES_WRITE, + IDIBUS_LONGOP_FMW_WRITE, + IDIBUS_LONGOP_INIT +}; + +#define IDIBUS_LONGOP_VARSN_IP_WRITE_DURATION_MS 200 +#define IDIBUS_LONGOP_VARSN_VERF_EXP_WRITE_DURATION_MS 200 +#define IDIBUS_LONGOP_VARSN_AES_WRITE_DURATION_MS 200 +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct { + uint8_t ComFunc; + uint8_t *InpData; + uint16_t InpDataLength; + uint8_t *OutData; + uint16_t OutDataPos; + uint16_t OutDataLength; + uint16_t ErrorPos; + uint8_t ErrorState; + uint8_t OutLongMesState; + uint8_t LongOpState; +} IDIBUS_FARG_TYPE; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct IDIBUS_CHANNEL_STR { + uint8_t BcastAddr; + uint8_t ChNum; + struct { + uint8_t Type; + uint8_t State; + uint32_t StartTimeInstanceMS; + uint32_t DurationMS; + } LONG_OP; + void (*CH_Func)(struct IDIBUS_CHANNEL_STR*, IDIBUS_FARG_TYPE*); +} IDIBUS_CHANNEL; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct { + IDIBUS_CHANNEL *Channels; + uint8_t ChannelsCount; +} IDIBUS_DEVICE; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +typedef struct { + USART_INTERFACE_TYPE *USI; + IDIBUS_DEVICE *Devices; + uint8_t DevicesCount; + IDISTATUS_SLAVE_TYPE STATUS; + uint8_t FreezeMemState; + uint8_t Error; + uint8_t c_InitAssignGroup; + struct { + uint8_t Type; + uint8_t Switch; + uint8_t State; + uint32_t StartTimeInstanceMS; + uint32_t DurationMS; + } LONG_OP; +} IDIBUS_SLAVE_MODULE; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define IDIBUS_SYSTEM_SW_VERSION 0x3133U +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +IDIBUS_SLAVE_MODULE IDIBUS_MODULE; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#ifdef _LONG_ADDR_SPACE_ +void IDIBUS_ModuleInit(USART_INTERFACE_TYPE *USART_INTERFACE, uint_farptr_t PROGMEM_SN); +#else +void IDIBUS_ModuleInit(USART_INTERFACE_TYPE *USART_INTERFACE, uint8_t *PROGMEM_SN); +#endif + +void IDIBUS_ModuleCommandHandler(IDIBUS_FARG_TYPE *farg); +uint8_t IDIBUS_CnannelStaticFunc(struct IDIBUS_CHANNEL_STR* CH, IDIBUS_FARG_TYPE *farg); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void IDIBUS_ResponseProtectedWrite(IDIBUS_FARG_TYPE *farg, uint8_t *Data, uint16_t DataLength, uint8_t ErrorCode); +void IDIBUS_ModuleBackgroundHandler(void); +void IDIBUS_ChannelBackgroundHandler(void); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void IDIBUS_ServiceFunc (uint8_t *InpData, uint16_t InpDataLength, uint8_t *OutData, uint16_t *OutDataLength); // зачем......... +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void IDIBUS_CustomInit(void); +//void IDIBUS_CustomShutdown(void); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif // #ifndef _INC_IDIBUS_IMPL_H_ +//############################################################################################################################################################################################################# + diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiBus/MODBUS_CRC.c b/3xThermo1xHT/idiBusCoreFiles/IdiBus/MODBUS_CRC.c new file mode 100644 index 0000000..980737d --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiBus/MODBUS_CRC.c @@ -0,0 +1,71 @@ +//############################################################################################################################################################################################################# +#include "MODBUS_CRC.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +const uint8_t MODBUS_auchCRCHi[256] PROGMEM= // Table of CRC values for high order byte +{ +0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, +0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, +0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, +0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, +0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, +0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, +0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, +0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, +0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, +0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, +0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, +0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, +0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, +0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, +0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, +0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 +}; +const uint8_t MODBUS_auchCRCLo[256] PROGMEM= // Table of CRC values for low order byte +{ +0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, +0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, +0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, +0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, +0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, +0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, +0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, +0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, +0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, +0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, +0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, +0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, +0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, +0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, +0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, +0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 +}; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint16_t MODBUS_CRC16_T(uint8_t *MODBUS_puchMsg, uint16_t MODBUS_usDataLen) +{ +uint8_t MODBUS_uchCRCHi=0xFF; // high byte of CRC initialized +uint8_t MODBUS_uchCRCLo=0xFF; // low byte of CRC initialized +uint8_t MODBUS_uIndex; +for (uint16_t I=0; I>=1; MODBUS_crc^=0xA001; } // If the LSB is set Shift right and XOR 0xA001 + else { MODBUS_crc>>=1; } // Else LSB is not set Just shift right + } + } +return MODBUS_crc; +} +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiBus/MODBUS_CRC.h b/3xThermo1xHT/idiBusCoreFiles/IdiBus/MODBUS_CRC.h new file mode 100644 index 0000000..bcc39dc --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiBus/MODBUS_CRC.h @@ -0,0 +1,14 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_MODBUS_CRC_H_ +#define _INC_MODBUS_CRC_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include +#include +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#define MODBUS_CRC16_SIZE 2 +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint16_t MODBUS_CRC16_T(uint8_t *MODBUS_puchMsg, uint16_t MODBUS_usDataLen); +uint16_t MODBUS_CRC16_S(uint8_t *MODBUS_buf, uint16_t MODBUS_len); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif // #ifndef _INC_MODBUS_CRC_H_ +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiBus/RSLink.c b/3xThermo1xHT/idiBusCoreFiles/IdiBus/RSLink.c new file mode 100644 index 0000000..d7cbde4 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiBus/RSLink.c @@ -0,0 +1,329 @@ +//############################################################################################################################################################################################################# +#include "RSLink.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_Init(USART_INTERFACE_TYPE *USART_INTERFACE, USART_IDIBUS_ROUTINE_TYPE *USART_ID_INTERFACE) +{ + RSLINK.USI=USART_INTERFACE; // USART POINTER INIT + RSLINK.USIID=USART_ID_INTERFACE; + RSLINK.NeedSpeedChangeFlag=0; + RSLINK.LastMMES_TimeInstance=System_GetTimeInstance(); + RSLink_StatusLedInit(); // Init LEDs + RSLink_DipsInit(); // Init DIP switches + RSLink_SpeedCheckAndUpdate(); // Set speed + RSLINK.USIID->SetIdiBusBoudrate(RSLINK.SpeedCode); // Set speed usart + RSLink_AddressCheckAndUpdate(); // Set adr + RSLINK.USI->RxTransferRestart(); // Restart RX +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t RSLink_SpeedCheckAndUpdate(void) +{ + uint8_t SpeedDSW_Code = RSLink_SpeedDecode(); + if (RSLINK.SpeedCode != SpeedDSW_Code) { RSLINK.SpeedCode = SpeedDSW_Code; return 1; } + return 0; +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_AddressCheckAndUpdate(void) +{ + RSLINK.Address = RSLink_AddrDecode(); + if ((RSLINK.Address>=IDIBUS_SLAVE_ADDR_MIN)&&(RSLINK.Address<=IDIBUS_SLAVE_ADDR_MAX)) { RSLINK.Address_Error=0; } + else { RSLINK.Address_Error=1; } +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_Handler(void) +{ + // Address and Speed Change Check Routine ======================================= + if ( (RSLINK.NeedSpeedChangeFlag == 1) || RSLink_SpeedCheckAndUpdate() ) + { + if ( RSLINK.USI->IsTxActive() ) { RSLINK.NeedSpeedChangeFlag = 1; } + else { RSLINK.USIID->SetIdiBusBoudrate(RSLINK.SpeedCode); RSLINK.NeedSpeedChangeFlag = 0; } + } + RSLink_AddressCheckAndUpdate(); + + + // Timeout Led Routine ========================================================== + if ( IDIBUS_MODULE.STATUS.STATE.B1S.TimeoutLed == 0 ) + { + if ( + ( (IDIBUS_MODULE.STATUS.STATE.B1S.NoMMESTimeout == 0) && (System_GetSysTickDifference( RSLINK.LastMMES_TimeInstance) >= IDIBUS_LINK_LED_NO_MMES_TIMEOUT_0_MS) ) || + ( (IDIBUS_MODULE.STATUS.STATE.B1S.NoMMESTimeout == 1) && (System_GetSysTickDifference( RSLINK.LastMMES_TimeInstance) >= IDIBUS_LINK_LED_NO_MMES_TIMEOUT_1_MS) ) + ) + { + IDIBUS_MODULE.STATUS.STATE.B1S.TimeoutLed=1; + //RSLink_StatusLedSetOn(); + } + else { RSLink_StatusLedSetOff(); } + } + + // Background Error Handler and Long Operations ================================= + IDIBUS_ModuleBackgroundHandler(); + IDIBUS_ChannelBackgroundHandler(); + + // Message Handling Routine ===================================================== + if ( RSLINK.USI->IsNewRxMessage() == 0 ) { return; } + + if ( RSLINK.USI->IsRxError() == 1) { + RSLINK.USI->RxTransferRestart(); + return; + } + + uint16_t RxMessageSize; + uint8_t *TxMesageBuf = RSLINK.USI->getTxBuf(); + + // Check incorrect and Developers DIP Switch Address ----------------------------> + if ( RSLINK.Address_Error ) + { + switch ( RSLINK.Address ) + { + case ( IDIBUS_DEVELOPER_ADDR_0 ) : { break; } + case ( IDIBUS_DEVELOPER_ADDR_1 ) : { break; } + case ( IDIBUS_DEVELOPER_ADDR_2 ) : { break; } + case ( IDIBUS_DEVELOPER_ADDR_3 ) : { break; } + default : {} + } + RSLINK.USI->RxTransferRestart(); + return; + } + + + // Check normal Message ---------------------------------------------------------> + + // Check Message size + uint8_t RcvAddress; + RxMessageSize = RSLINK.USI->getRxBufSize(); + if ( (RxMessageSize < (MODBUS_CRC16_SIZE+1) ) || (RxMessageSize > IDIMMES_MAX_MES_SIZE) ) { RSLINK.USI->RxTransferRestart(); return; } + else + { + RSLINK.USI->copyRxBuf( &RxMesageBuf[IDIMMES_ADDR_Pos], IDIMMES_ADDR_Pos, 1 ); // Need for CRC + RcvAddress = RxMesageBuf[IDIMMES_ADDR_Pos]; + } + + // MMESG(Module) or MMES -------------> + if ( RcvAddress == RSLINK.Address ) + { + // Check CRC, copy RxBuf and Restart Transfer + RSLINK.USI->copyRxBuf( &RxMesageBuf[IDIMMES_MMPS_Pos], IDIMMES_MMPS_Pos, (uint16_t)(RxMessageSize-1) ); + RSLINK.USI->RxTransferRestart(); + uint16_t CalculatedCRC = MODBUS_CRC16_T( RxMesageBuf, (uint16_t)(RxMessageSize-2) ); + uint16_t ReceivedCRC = (uint16_t)( ((uint16_t)RxMesageBuf[RxMessageSize-2] << 8) | RxMesageBuf[RxMessageSize-1] ); + if ( CalculatedCRC != ReceivedCRC ) { return; } + IDIBUS_MODULE.STATUS.STATE.B1S.TimeoutLed = 0; + RSLINK.LastMMES_TimeInstance = System_GetTimeInstance(); //FOR STM, (reset led) + + IDIBUS_FARG_TYPE FARG; + FARG.OutData = &TxMesageBuf[0]; //set RX addr + FARG.OutDataLength = IDISMES_ERROR_Pos; //Set length 2 (adr+cmd) + FARG.ErrorPos = IDISMES_ERROR_Pos; //set pos err + FARG.OutDataPos = IDISMES_ERROR_Pos + 1; //set pos data + FARG.ErrorState = 0; + FARG.OutLongMesState = 0; + if ( IDIBUS_MODULE.LONG_OP.State == IDILONGOP_STATE_IN_PROC ) { FARG.LongOpState = 1; } + else { FARG.LongOpState = 0; } + + + // Check if too short for MMESG message + if ( RxMessageSize < (IDIMMES_MMPS_Pos + 1 + MODBUS_CRC16_SIZE) ) { IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); RSLink_SendSMES(&FARG); return;} + + // Get MMPS + uint8_t MMPS_FastFunc = (RxMesageBuf[IDIMMES_MMPS_Pos] & IDIMMES_MMPS_FAST_FUNC_Msk) >> IDIMMES_MMPS_FAST_FUNC_Pos; + uint8_t MMPS_MesType = (RxMesageBuf[IDIMMES_MMPS_Pos] & IDIMMES_MMPS_MES_TYPE_Msk) >> IDIMMES_MMPS_MES_TYPE_Pos; + uint8_t MMPS_LongMessage = RxMesageBuf[IDIMMES_MMPS_Pos] & IDIMMES_MMPS_LONG_MES_Msk; + uint8_t MMPS_AlarmFrame = RxMesageBuf[IDIMMES_MMPS_Pos] & IDIMMES_MMPS_ALARM_FRAME_Msk; + uint8_t MMPS_EncryptedAes = RxMesageBuf[IDIMMES_MMPS_Pos] & IDIMMES_MMPS_ENCRYPTED_AES_Msk; + if ( MMPS_AlarmFrame != 0 ) + { + // Do Alarm + } + if ( MMPS_EncryptedAes != 0 ) + { + if ( IDIBUS_MODULE.STATUS.STATE.B0S.AesSupported == 0 ) { IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERSLV_ENCRYPTION_NOT_SUPPORTED); RSLink_SendSMES(&FARG); return; } + else if ( IDIBUS_MODULE.STATUS.STATE.B0S.AesInstalled == 0 ) { IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERSLV_ENCRYPTION_NOT_INSTALLED); RSLink_SendSMES(&FARG); return; } + else + { + // Decrypt ... + } + } + if ( MMPS_LongMessage != 0 ) + { + IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERSLV_JUMBO_NOT_SUPPORTED); + RSLink_SendSMES(&FARG); + return; + } + // If Module Function + if ( MMPS_MesType == IDIMMES_MMPS_MES_TYPE_MMESG ) + { + if ( (MMPS_FastFunc != 0) || (RxMessageSize < IDIMMESG_MODULE_MIN_MES_SIZE) ) { IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + FARG.ComFunc = RxMesageBuf[IDIMMESG_DATA_COM_FUNC_Pos]; + FARG.InpData = &RxMesageBuf[IDIMMESG_DATA_COM_FUNC_Pos + 1]; + FARG.InpDataLength = (uint16_t)(RxMessageSize - (IDIMMESG_DATA_COM_FUNC_Pos + 1) - MODBUS_CRC16_SIZE); + IDIBUS_ModuleCommandHandler(&FARG); + } + RSLink_SendSMES(&FARG); + return; + } + + // IF NOT Module Function + if ( IDIBUS_MODULE.STATUS.STATE.B0S.StState == IDISTATUS_B0S_ST_STATE_StFreeze ) { IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERSLV_IN_FREEZE); RSLink_SendSMES(&FARG); return; } + else if ( IDIBUS_MODULE.Error != IDIER_NOPE ) { IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIBUS_MODULE.Error); RSLink_SendSMES(&FARG); return; } + else if ( IDIBUS_MODULE.LONG_OP.State == IDILONGOP_STATE_IN_PROC ) { IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERSLV_LONG_OP_IN_PROC); RSLink_SendSMES(&FARG); return; } + + if ( MMPS_FastFunc == 0 ) + { + if ( (RxMessageSize < (IDIMMES_MIN_MES_SIZE + 1)) || (RxMesageBuf[IDIMMES_DATA_FUNC_COM_DATA_Pos] <= IDIMMES_MAX_FAST_FUNC_NUM) ) //CHECK LEN ON MSG + { + IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); RSLink_SendSMES(&FARG); + return; + } + FARG.ComFunc = RxMesageBuf[IDIMMES_DATA_FUNC_COM_DATA_Pos]; + FARG.InpData = &RxMesageBuf[IDIMMES_DATA_FUNC_COM_DATA_Pos + 1]; + FARG.InpDataLength = (uint16_t)(RxMessageSize - (IDIMMES_DATA_FUNC_COM_DATA_Pos + 1) - MODBUS_CRC16_SIZE); + } + else + { + if ( RxMessageSize < IDIMMES_MIN_MES_SIZE ) { IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); RSLink_SendSMES(&FARG); return; } + FARG.ComFunc = MMPS_FastFunc; + FARG.InpData = &RxMesageBuf[IDIMMES_DATA_FUNC_COM_DATA_Pos]; + FARG.InpDataLength = (uint16_t)(RxMessageSize - IDIMMES_DATA_FUNC_COM_DATA_Pos - MODBUS_CRC16_SIZE); + } + // Channels command and funcs handling + uint8_t DeviceNum = (RxMesageBuf[IDIMMES_DEV_Pos] & IDIMMES_DEV_NUM_Msk) >> IDIMMES_DEV_NUM_Pos; + uint8_t AllChannels = RxMesageBuf[IDIMMES_DEV_Pos] & IDIMMES_DEV_ALLCH_Msk; + uint8_t ChannelNum = (RxMesageBuf[IDIMMES_CHNL_Pos] & IDIMMES_CHNL_NUM_Msk) >> IDIMMES_CHNL_NUM_Pos; + uint8_t ChannelAllSame = RxMesageBuf[IDIMMES_CHNL_Pos] & IDIMMES_CHNL_ALLSAME_Msk; + + if ( DeviceNum >= IDIBUS_MODULE.DevicesCount ) { IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERDEV_INVALID_DEV_NUM); RSLink_SendSMES(&FARG); return; } + if ( (ChannelNum >= IDIBUS_MODULE.Devices[DeviceNum].ChannelsCount) && (AllChannels == 0) ) { IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERDEV_INVALID_CHN_NUM); RSLink_SendSMES(&FARG); return; } + if ( AllChannels != 0 ) + { + uint8_t ChannelsCount = IDIBUS_MODULE.Devices[DeviceNum].ChannelsCount; + FARG.OutDataPos = (uint16_t)( FARG.OutDataPos + ChannelsCount - 1 ); // SMES = ADDR SMPS ERR1 ERR2 ERR3 DATA1 DATA2 DATA3 CRC + if ( ChannelAllSame == 0 ) + { + uint16_t DataPortionLength = (uint16_t)( FARG.InpDataLength / ChannelsCount ); // If DataLength==0 -> OK (Byte count on one channel) + // SMES = ADDR SMPS ERR1 ERR2!=0 ERR3 DATA1 DATA3 CRC + if ( FARG.InpDataLength != (DataPortionLength * ChannelsCount) ) + { + for (uint8_t I=0; I < ChannelsCount; I++ ) { IDIBUS_ResponseProtectedWrite(&FARG, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + } + else { + FARG.InpDataLength = DataPortionLength; + for (uint8_t I=0; I < ChannelsCount; I++ ) + { + IDIBUS_CHANNEL *CH = &IDIBUS_MODULE.Devices[DeviceNum].Channels[I]; + CH->CH_Func( CH, &FARG ); + FARG.InpData += DataPortionLength; //Pointer offset + } + } + } + else { for (uint8_t I=0; I < IDIBUS_MODULE.Devices[DeviceNum].ChannelsCount; I++ ) + { + IDIBUS_CHANNEL *CH = &IDIBUS_MODULE.Devices[DeviceNum].Channels[I]; + CH->CH_Func( CH, &FARG ); + } + } + } + else + { + IDIBUS_CHANNEL *CH = &IDIBUS_MODULE.Devices[DeviceNum].Channels[ChannelNum]; + CH->CH_Func( CH, &FARG ); + } + RSLink_SendSMES(&FARG); + return; + } //if ( (RcvAddress == RSLINK.Address) && (RxMessageSize >= IDIMMES_MIN_MES_SIZE) ) + + + // MMESG -------------> + // NO RESPONSE!!! + if ( (RcvAddress >= IDIBUS_GROUP_0_ADDR) && (RcvAddress <= IDIBUS_GROUP_15_ADDR) ) + { + // Check CRC, copy RxBuf and Restart Transfer + RSLINK.USI->copyRxBuf( &RxMesageBuf[IDIMMES_MMPS_Pos], IDIMMES_MMPS_Pos, (uint16_t)(RxMessageSize-1) ); + RSLINK.USI->RxTransferRestart(); + uint16_t CalculatedCRC = MODBUS_CRC16_T( RxMesageBuf, (uint16_t)(RxMessageSize-2) ); + uint16_t ReceivedCRC = (uint16_t)( ((uint16_t)RxMesageBuf[RxMessageSize-2] << 8) | RxMesageBuf[RxMessageSize-1] ); + if ( CalculatedCRC != ReceivedCRC ) { return; } + IDIBUS_MODULE.STATUS.STATE.B1S.TimeoutLed = 0; + RSLINK.LastMMES_TimeInstance = System_GetTimeInstance(); + + IDIBUS_FARG_TYPE FARG; + FARG.OutData = NULL; + + // Check if too short for MMESG message + if ( RxMessageSize < (IDIMMES_MMPS_Pos + 1 + MODBUS_CRC16_SIZE) ) { return; } + + // Get MMPS + uint8_t MMPS_FastFunc = (RxMesageBuf[IDIMMES_MMPS_Pos] & IDIMMES_MMPS_FAST_FUNC_Msk) >> IDIMMES_MMPS_FAST_FUNC_Pos; + uint8_t MMPS_MesType = (RxMesageBuf[IDIMMES_MMPS_Pos] & IDIMMES_MMPS_MES_TYPE_Msk) >> IDIMMES_MMPS_MES_TYPE_Pos; + uint8_t MMPS_LongMessage = RxMesageBuf[IDIMMES_MMPS_Pos] & IDIMMES_MMPS_LONG_MES_Msk; + uint8_t MMPS_AlarmFrame = RxMesageBuf[IDIMMES_MMPS_Pos] & IDIMMES_MMPS_ALARM_FRAME_Msk; + uint8_t MMPS_EncryptedAes = RxMesageBuf[IDIMMES_MMPS_Pos] & IDIMMES_MMPS_ENCRYPTED_AES_Msk; + if ( MMPS_AlarmFrame != 0 ) + { + // Do Alarm + } + if ( MMPS_EncryptedAes != 0 ) + { + if ( (IDIBUS_MODULE.STATUS.STATE.B0S.AesSupported == 0) || (IDIBUS_MODULE.STATUS.STATE.B0S.AesInstalled == 0) ) { return; } + else + { + // Decrypt ... + } + } + if ( MMPS_LongMessage != 0 ) + { + return; + } + if ( + ( MMPS_MesType != IDIMMES_MMPS_MES_TYPE_MMESG ) || + ( IDIBUS_MODULE.STATUS.STATE.B0S.StState == IDISTATUS_B0S_ST_STATE_StFreeze ) || // There are no Module commands in group + ( IDIBUS_MODULE.Error != IDIER_NOPE ) || + ( IDIBUS_MODULE.LONG_OP.State == IDILONGOP_STATE_IN_PROC ) + ) { return; } + + if ( MMPS_FastFunc == 0 ) + { + if ( RxMessageSize < (IDIMMESG_GROUP_MIN_MES_SIZE + 1) ) { return; } + FARG.ComFunc = RxMesageBuf[IDIMMESG_DATA_COM_FUNC_Pos]; + if ( FARG.ComFunc <= IDIMMES_MAX_FAST_FUNC_NUM ) { return; } + FARG.InpData = &RxMesageBuf[IDIMMESG_DATA_COM_FUNC_Pos + 1]; + FARG.InpDataLength = (uint16_t)(RxMessageSize - (IDIMMESG_DATA_COM_FUNC_Pos + 1) - MODBUS_CRC16_SIZE); + } + else + { + if ( RxMessageSize < IDIMMESG_GROUP_MIN_MES_SIZE ) { return; } + FARG.ComFunc = MMPS_FastFunc; + FARG.InpData = &RxMesageBuf[IDIMMESG_DATA_COM_FUNC_Pos]; + FARG.InpDataLength = (uint16_t)(RxMessageSize - IDIMMESG_DATA_COM_FUNC_Pos - MODBUS_CRC16_SIZE); + } + for (uint8_t Dev = 0; Dev < IDIBUS_MODULE.DevicesCount; Dev++) + { + for (uint8_t Ch = 0; ChBcastAddr == RcvAddress) ) { CH->CH_Func(CH, &FARG); } + } + } + return; + } //if ( ((RcvAddress >= IDIBUS_GROUP_0_ADDR) && (RcvAddress <= IDIBUS_GROUP_15_ADDR)) ) + + RSLINK.USI->RxTransferRestart(); // NOT MMES AND MMESG -------------> + return; +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_SendSMES(IDIBUS_FARG_TYPE *farg) +{ + if ( (RSLINK.USIID->ResponseTimeoutComplete == 0) && (farg->OutDataLength > IDISMES_ERROR_Pos) ) + { + farg->OutData[IDISMES_ADDR_Pos] = RSLINK.Address; + farg->OutData[IDISMES_SMPS_Pos] = 0; + if ( farg->ErrorState != 0 ) { farg->OutData[IDISMES_SMPS_Pos] |= (1U << IDISMES_SMPS_ERROR_BIT_Pos); } + if ( farg->OutLongMesState != 0 ) { farg->OutData[IDISMES_SMPS_Pos] |= (1U << IDISMES_SMPS_LONG_MES_Pos); } + if ( farg->LongOpState != 0 ) { farg->OutData[IDISMES_SMPS_Pos] |= (1U << IDISMES_SMPS_LONG_OP_Pos); } + uint16_t CRC16 = MODBUS_CRC16_T(&farg->OutData[0], farg->OutDataLength); + farg->OutData[farg->OutDataLength++] = (uint8_t)(CRC16 >> 8); + farg->OutData[farg->OutDataLength++] = (uint8_t) CRC16; + RSLINK.USI->SendTxBuf(farg->OutDataLength); + } +} +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiBus/RSLink.h b/3xThermo1xHT/idiBusCoreFiles/IdiBus/RSLink.h new file mode 100644 index 0000000..34be4a0 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiBus/RSLink.h @@ -0,0 +1,43 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_RSLINK_H_ +#define _INC_RSLINK_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include +#include "SYSTEM.h" +#include "IDIBUS_IMPL.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// DELAYS FOR LEDS status +#define RSLINK_LED_T1_DEFAULT_S 15UL +#define RSLINK_LED_T2_DEFAULT_S 60UL +//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +struct RSLINK_STRUCT +{ +USART_INTERFACE_TYPE *USI; +USART_IDIBUS_ROUTINE_TYPE *USIID; +uint8_t Address; +uint8_t Address_Error; // недопустимый +uint8_t SpeedCode; +uint8_t NeedSpeedChangeFlag; // флаг для изменения скорости +uint32_t LastMMES_TimeInstance; // для led +}; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint8_t RxMesageBuf[IDIMMES_MAX_MES_SIZE]; //RX buffer for copy +struct RSLINK_STRUCT RSLINK; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_Init(USART_INTERFACE_TYPE *USART_INTERFACE, USART_IDIBUS_ROUTINE_TYPE *USART_ID_INTERFACE); +uint8_t RSLink_SpeedCheckAndUpdate(void); +void RSLink_AddressCheckAndUpdate(void); +void RSLink_Handler(void); +void RSLink_SendSMES(IDIBUS_FARG_TYPE *farg); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_StatusLedInit(void); +void RSLink_StatusLedSetOn(void); +void RSLink_StatusLedSetOff(void); + +void RSLink_DipsInit(void); +uint8_t RSLink_AddrDecode(void); +uint8_t RSLink_SpeedDecode(void); +uint8_t RSLink_TypeDecode(void); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif // #ifndef _INC_RSLINK_H_ +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.atsln b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.atsln new file mode 100644 index 0000000..518d999 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.atsln @@ -0,0 +1,22 @@ +п»ї +Microsoft Visual Studio Solution File, Format Version 12.00 +# Atmel Studio Solution File, Format Version 11.00 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "IdiCommon_2560", "IdiCommon_2560.cproj", "{06E88371-DE74-4663-A82F-031E45168730}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug (2560)|AVR = Debug (2560)|AVR + Release (2560)|AVR = Release (2560)|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {06E88371-DE74-4663-A82F-031E45168730}.Debug (2560)|AVR.ActiveCfg = [Build] Debug_2560|AVR + {06E88371-DE74-4663-A82F-031E45168730}.Debug (2560)|AVR.Build.0 = [Build] Debug_2560|AVR + {06E88371-DE74-4663-A82F-031E45168730}.Release (2560)|AVR.ActiveCfg = [Build] Release_2560|AVR + {06E88371-DE74-4663-A82F-031E45168730}.Release (2560)|AVR.Build.0 = [Build] Release_2560|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.componentinfo.xml b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.componentinfo.xml new file mode 100644 index 0000000..f8d11f3 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.componentinfo.xml @@ -0,0 +1,86 @@ +п»ї + + + + + + Device + Startup + + + Atmel + 1.7.0 + C:/Program Files (x86)\Atmel\Studio\7.0\Packs + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\include\ + + include + C + + + include/ + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\include\avr\iom2560.h + + header + C + MkwPezikXVtYA90mpLpFfA== + + include/avr/iom2560.h + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\templates\library.c + template + source + C Lib + VjSGq44t/3IHSL1ATPOBng== + + templates/library.c + Main file (.c) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\templates\library.cpp + template + source + C Lib + G0XtXwMIamMgYWpjMWDloQ== + + templates/library.cpp + Main file (.cpp) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega2560 + + libraryPrefix + GCC + + + gcc/dev/atmega2560 + + + + + ATmega_DFP + C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/1.7.374/Atmel.ATmega_DFP.pdsc + 1.7.374 + true + ATmega2560 + + + + Resolved + Latest + true + + + \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.cproj b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.cproj new file mode 100644 index 0000000..b2b595c --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_2560.cproj @@ -0,0 +1,216 @@ +п»ї + + + 2.0 + 7.0 + com.Atmel.AVRGCC8.C + {06e88371-de74-4663-a82f-031e45168730} + ATmega2560 + none + StaticLibrary + C + lib$(MSBuildProjectName) + .a + $(MSBuildProjectDirectory)\$(Configuration) + + + IdiBus + IdiCommon + IdiBus + Native + true + false + true + true + 0x20000000 + + true + exception_table + 2 + 0 + 0 + + + + + + + + -mmcu=atmega2560 -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega2560" + True + True + True + True + True + True + True + True + + + _CPU_ATMEGA2560_ + _LONG_ADDR_SPACE_ + NDEBUG + + + + + ../CommonHW + ../IdiBus + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + ../../idiBusFiles + ../../moduleFiles + ../../personalizationFiles + + + Optimize for size (-Os) + True + True + True + False + True + + + libm + + + + + .locationInApp=0x1EF80 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + + + + + + + -mmcu=atmega2560 -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega2560" + True + True + True + True + True + True + True + True + + + _CPU_ATMEGA2560_ + _LONG_ADDR_SPACE_ + DEBUG + + + + + ../CommonHW + ../IdiBus + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + ../../idiBusFiles + ../../moduleFiles + ../../personalizationFiles + + + Optimize for size (-Os) + True + True + True + True + True + + + libm + + + + + .locationInApp=0x1EF80 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + Maximum (-g3) + Default (-Wa,-g) + + + libIdiCommon_2560 + .a + StaticLibrary + + + + + + + + compile + IdiBus\EEMEM.h + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + IdiBus\IDIBUS_DEFS.h + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + + \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.atsln b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.atsln new file mode 100644 index 0000000..d220e47 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.atsln @@ -0,0 +1,22 @@ +п»ї +Microsoft Visual Studio Solution File, Format Version 12.00 +# Atmel Studio Solution File, Format Version 11.00 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "IdiCommon_328pb", "IdiCommon_328pb.cproj", "{06E88371-DE74-4663-A82F-031E45168730}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug (328pb)|AVR = Debug (328pb)|AVR + Release (328pb)|AVR = Release (328pb)|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {06E88371-DE74-4663-A82F-031E45168730}.Debug (328pb)|AVR.ActiveCfg = [Build] Debug_328pb|AVR + {06E88371-DE74-4663-A82F-031E45168730}.Debug (328pb)|AVR.Build.0 = [Build] Debug_328pb|AVR + {06E88371-DE74-4663-A82F-031E45168730}.Release (328pb)|AVR.ActiveCfg = [Build] Release_328pb|AVR + {06E88371-DE74-4663-A82F-031E45168730}.Release (328pb)|AVR.Build.0 = [Build] Release_328pb|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.componentinfo.xml b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.componentinfo.xml new file mode 100644 index 0000000..3021b45 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.componentinfo.xml @@ -0,0 +1,86 @@ +п»ї + + + + + + Device + Startup + + + Atmel + 2.0.0 + C:/Program Files (x86)\Atmel\Studio\7.0\Packs + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include\ + + include + C + + + include/ + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include\avr\iom328pb.h + + header + C + ciLFjy803ysEAt1ml/dotQ== + + include/avr/iom328pb.h + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\templates\library.c + template + source + C Lib + VjSGq44t/3IHSL1ATPOBng== + + templates/library.c + Main file (.c) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\templates\library.cpp + template + source + C Lib + G0XtXwMIamMgYWpjMWDloQ== + + templates/library.cpp + Main file (.cpp) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\gcc\dev\atmega328pb + + libraryPrefix + GCC + + + gcc/dev/atmega328pb + + + + + ATmega_DFP + C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/Atmel.ATmega_DFP.pdsc + 2.0.401 + true + ATmega328PB + + + + Resolved + Latest + true + + + \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.cproj b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.cproj new file mode 100644 index 0000000..1d54489 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/IdiCommon_328pb.cproj @@ -0,0 +1,235 @@ +п»ї + + + 2.0 + 7.0 + com.Atmel.AVRGCC8.C + {06e88371-de74-4663-a82f-031e45168730} + ATmega328PB + none + StaticLibrary + C + lib$(MSBuildProjectName) + .a + $(MSBuildProjectDirectory)\$(Configuration) + + + IdiBus + IdiCommon_328pb + IdiBus + Native + true + false + true + true + 0x20000000 + + true + exception_table + 2 + 0 + 0 + + + + + + + + + + + + + + + + + + + + -mmcu=atmega328pb -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb" + True + True + True + True + True + True + True + True + + + _CPU_ATMEGA328PB_ + NDEBUG + + + + + ../CommonHW + ../IdiBus + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + ../../moduleFiles + ../../idiBusFiles + ../../personalizationFiles + + + Optimize for size (-Os) + True + True + True + False + True + + + libm + + + + + .locationInApp=0x37C0 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + + + bin\Release_328pb\ + libIdiCommon + .a + StaticLibrary + + + + + -mmcu=atmega328pb -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb" + True + True + True + True + True + True + True + True + + + _CPU_ATMEGA328PB_ + DEBUG + + + + + ../CommonHW + ../IdiBus + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + ../../moduleFiles + ../../idiBusFiles + ../../personalizationFiles + + + Optimize for size (-Os) + True + True + True + True + True + + + libm + + + + + .locationInApp=0x37C0 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + Maximum (-g3) + Default (-Wa,-g) + + + bin\Debug_328pb\ + libIdiCommon + .a + StaticLibrary + + + + + + + + compile + IdiBus\EEMEM.h + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + IdiBus\IDIBUS_DEFS.h + + + compile + IdiBus\MEMORY.h + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + + \ No newline at end of file diff --git a/3xThermo1xHT/idiBusCoreFiles/README.md b/3xThermo1xHT/idiBusCoreFiles/README.md new file mode 100644 index 0000000..f361325 --- /dev/null +++ b/3xThermo1xHT/idiBusCoreFiles/README.md @@ -0,0 +1 @@ +Do not use this repository separetly from idiBusSlaveTemplate!!! \ No newline at end of file diff --git a/3xThermo1xHT/idiBusFiles/IDIBUS_IMPL_Custom.c b/3xThermo1xHT/idiBusFiles/IDIBUS_IMPL_Custom.c new file mode 100644 index 0000000..41b9a44 --- /dev/null +++ b/3xThermo1xHT/idiBusFiles/IDIBUS_IMPL_Custom.c @@ -0,0 +1,118 @@ +#include "IDIBUS_IMPL_Custom.h" + +int data_flag = 0; +uint8_t data_to_send[12] = {0}; + +void IDIBUS_CustomInit(){ + IDIBUS_MODULE.STATUS.STATE.B0S.StError = 0; + IDIBUS_MODULE.STATUS.STATE.B0S.StState = IDISTATUS_B0S_ST_STATE_StOperate; + IDIBUS_MODULE.STATUS.STATE.B0S.AesSupported = 0; + IDIBUS_MODULE.STATUS.STATE.B0S.AesInstalled = 0; + IDIBUS_MODULE.STATUS.STATE.B0S.SendAlarmL0 = 0; + IDIBUS_MODULE.STATUS.STATE.B0S.SendAlarmL1 = 0; + + IDIBUS_MODULE.STATUS.STATE.B1S.ModuleType = IDISTATUS_B1S_MODULE_TYPE_Slave; + IDIBUS_MODULE.STATUS.STATE.B1S.BridgeConnected = 0; + IDIBUS_MODULE.STATUS.STATE.B1S.SelfInit = 1; + IDIBUS_MODULE.STATUS.STATE.B1S.TimeoutLed = 0; + IDIBUS_MODULE.STATUS.STATE.B1S.NoMMESTimeout = 0; + IDIBUS_MODULE.STATUS.STATE.B1S.CatchAlarmL0 = 0; + IDIBUS_MODULE.STATUS.STATE.B1S.CatchAlarmL1 = 0; + + IDIBUS_MODULE.Devices = IDIBUS_DEVICES; + IDIBUS_MODULE.DevicesCount = IDIBUS_DEVICES_NUMBER; + + IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels = &IDIBUS_GEN_CHNLS[0]; + IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].ChannelsCount = GEN_CHN_COUNT; + + for (uint8_t I=0; I < GEN_CHN_COUNT; I++) + { + IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels[I].ChNum = I; + IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels[I].LONG_OP.Type = 0; + IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels[I].LONG_OP.State = IDILONGOP_STATE_COMPLETE_NO_ERR; + IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels[I].BcastAddr = IDIBUS_GROUP_0_ADDR; + IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels[I].CH_Func = IDIBUS_GEN_ChannelHandler; + } +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void IDIBUS_GEN_ChannelHandler(struct IDIBUS_CHANNEL_STR* CH, IDIBUS_FARG_TYPE *farg){ + if ( IDIBUS_CnannelStaticFunc(CH, farg) != 0) { return; } + + if (CH->ChNum >= GEN_CHN_COUNT) {IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERDEV_INVALID_CHN_NUM); return;} + + switch (farg->ComFunc) + { + case (0x01) : { // Добавить выключение + if ( farg->InpDataLength == 0 ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); } + else + { + //DDRE = 2; + uint8_t ErrorSt = IDIER_NOPE; + memcpy(data_to_send, farg->InpData, sizeof(data_to_send)); + + if (sizeof(data_to_send) / sizeof(data_to_send[0]) != 0) { + data_flag = 1; + } + + TCCR2A |= (1 << WGM21); // CTC + TCCR2B |= (1 << CS21); // Prescaler + OCR2A = 1; + TIMSK2 = (1< +#include +#include +#include "IDIBUS_IMPL.h" +#include "../moduleFiles/SPI.h" + +#define TimerStop TCCR2B = 0 +#define ResetTimer TCNT2 = 0 +#define TimerTime OCR2A +#define TimerStartTick TCCR2B = (1 << CS21) // 0.5 мкс (предделитель 8) +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +enum IDIBUS_MODULE_DEVICES_LIST // ???????????????????????????????????????? +{ + IDIBUS_GEN_DEV = 0x00, + IDIBUS_DEVICES_NUMBER +}; + +enum GenOperations { + GEN_Wait = 0x00, + GEN_Send +}; + +enum GenOperations CurrentState; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +IDIBUS_DEVICE IDIBUS_DEVICES[IDIBUS_DEVICES_NUMBER]; +#define GEN_CHN_COUNT 1 +IDIBUS_CHANNEL IDIBUS_GEN_CHNLS[GEN_CHN_COUNT]; +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void IDIBUS_GEN_ChannelHandler(struct IDIBUS_CHANNEL_STR* CH, IDIBUS_FARG_TYPE *farg); +void STMReset(); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif /* IDIBUS_IMPL_CUSTOM_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/idiBusFiles/RSLinkCustom.c b/3xThermo1xHT/idiBusFiles/RSLinkCustom.c new file mode 100644 index 0000000..2ce7e3a --- /dev/null +++ b/3xThermo1xHT/idiBusFiles/RSLinkCustom.c @@ -0,0 +1,76 @@ +//############################################################################################################################################################################################################# +#include "RSLinkCustom.h" +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void RSLink_StatusLedInit(void) // Status led Init +{ +RSLINK_LED_DDR|=1< 1 +RSLINK_DIPS_nPL_DDR|=1< 1 +RSLINK_DIPS_Q7_DDR&=~(1<>8); +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//############################################################################################################################################################################################################# +//void RSLink_TimerInit() { + ////TCCR2A |= (1 << WGM21); + ////TCCR2A &= ~(1 << WGM20); // CTC Mode + ////TCCR2B &= ~(1 << WGM22); + //// + //////устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L) + ////TIMSK2 |= (1 << OCIE2A); + //// + ////OCR2A = 0xFF; + //// + ////TCCR2B |= (1 << CS20) | (1 << CS22) | (1 << CS21); + // + //TCCR1A |= (1 << WGM12) | (1 << WGM13); + //TCCR1A &= ~(1 << WGM11); // CTC Mode + //TCCR1B &= ~(1 << WGM10); + // + //TIMSK1 |= (1 << OCIE1A); + // + //OCR1AH = 0x27; //записываем в регистр число для сравнения + //OCR1AL = 0x10; + // + //TCCR1B |= (1 << CS12); +//} \ No newline at end of file diff --git a/3xThermo1xHT/idiBusFiles/RSLinkCustom.h b/3xThermo1xHT/idiBusFiles/RSLinkCustom.h new file mode 100644 index 0000000..1eaa6a8 --- /dev/null +++ b/3xThermo1xHT/idiBusFiles/RSLinkCustom.h @@ -0,0 +1,32 @@ +//############################################################################################################################################################################################################# +#ifndef _INC_RSLINK_CUSTOM_H_ +#define _INC_RSLINK_CUSTOM_H_ +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include +#include +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// Status led +#define RSLINK_LED_DDR DDRE +#define RSLINK_LED_PORT PORTE +#define RSLINK_LED_PIN PINE +#define RSLINK_LED_BIT 1 +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// Dip switch Adders, Speed, Bus Type +#define RSLINK_DIPS_CP_PORT PORTD +#define RSLINK_DIPS_CP_DDR DDRD +#define RSLINK_DIPS_CP_PIN PIND +#define RSLINK_DIPS_CP_BIT 7 +#define RSLINK_DIPS_nPL_PORT PORTD +#define RSLINK_DIPS_nPL_DDR DDRD +#define RSLINK_DIPS_nPL_PIN PIND +#define RSLINK_DIPS_nPL_BIT 6 +#define RSLINK_DIPS_Q7_PORT PORTD +#define RSLINK_DIPS_Q7_DDR DDRD +#define RSLINK_DIPS_Q7_PIN PIND +#define RSLINK_DIPS_Q7_BIT 5 +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +uint16_t RSLink_DipsRead(void); +//void RSLink_TimerInit(); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#endif // #ifndef _INC_RSLINK_CUSTOM_H_ +//############################################################################################################################################################################################################# diff --git a/3xThermo1xHT/idiBus_Ext.atsln b/3xThermo1xHT/idiBus_Ext.atsln new file mode 100644 index 0000000..7ff8d91 --- /dev/null +++ b/3xThermo1xHT/idiBus_Ext.atsln @@ -0,0 +1,28 @@ +п»ї +Microsoft Visual Studio Solution File, Format Version 12.00 +# Atmel Studio Solution File, Format Version 11.00 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "idiBus_Ext_3xThermo1HT", "idiBus_Ext_3xThermo1HT.cproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}" +EndProject +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "IdiCommon_328pb", "idiBusCoreFiles\IdiCommon_328pb.cproj", "{06E88371-DE74-4663-A82F-031E45168730}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + [Build] Debug|AVR = [Build] Debug|AVR + [Build] Release|AVR = [Build] Release|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.[Build] Debug|AVR.ActiveCfg = [Build] Debug|AVR + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.[Build] Debug|AVR.Build.0 = [Build] Debug|AVR + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.[Build] Release|AVR.ActiveCfg = [Build] Release|AVR + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.[Build] Release|AVR.Build.0 = [Build] Release|AVR + {06E88371-DE74-4663-A82F-031E45168730}.[Build] Debug|AVR.ActiveCfg = [Build] Debug_328pb|AVR + {06E88371-DE74-4663-A82F-031E45168730}.[Build] Debug|AVR.Build.0 = [Build] Debug_328pb|AVR + {06E88371-DE74-4663-A82F-031E45168730}.[Build] Release|AVR.ActiveCfg = [Build] Release_328pb|AVR + {06E88371-DE74-4663-A82F-031E45168730}.[Build] Release|AVR.Build.0 = [Build] Release_328pb|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/3xThermo1xHT/idiBus_Ext_3xThermo1HT.componentinfo.xml b/3xThermo1xHT/idiBus_Ext_3xThermo1HT.componentinfo.xml new file mode 100644 index 0000000..c524a48 --- /dev/null +++ b/3xThermo1xHT/idiBus_Ext_3xThermo1HT.componentinfo.xml @@ -0,0 +1,86 @@ +п»ї + + + + + + Device + Startup + + + Atmel + 2.0.0 + C:/Program Files (x86)\Atmel\Studio\7.0\Packs + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include\ + + include + C + + + include/ + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include\avr\iom328pb.h + + header + C + ciLFjy803ysEAt1ml/dotQ== + + include/avr/iom328pb.h + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\templates\main.c + template + source + C Exe + KjvOcFWd++tbnsEMfVPd/w== + + templates/main.c + Main file (.c) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\templates\main.cpp + template + source + C Exe + mkKaE95TOoATsuBGv6jmxg== + + templates/main.cpp + Main file (.cpp) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\gcc\dev\atmega328pb + + libraryPrefix + GCC + + + gcc/dev/atmega328pb + + + + + ATmega_DFP + C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/Atmel.ATmega_DFP.pdsc + 2.0.401 + true + ATmega328PB + + + + Resolved + Latest + true + + + \ No newline at end of file diff --git a/3xThermo1xHT/idiBus_Ext_3xThermo1HT.cproj b/3xThermo1xHT/idiBus_Ext_3xThermo1HT.cproj new file mode 100644 index 0000000..0c35d35 --- /dev/null +++ b/3xThermo1xHT/idiBus_Ext_3xThermo1HT.cproj @@ -0,0 +1,277 @@ +п»ї + + + 2.0 + 7.0 + com.Atmel.AVRGCC8.C + dce6c7e3-ee26-4d79-826b-08594b9ad897 + ATmega328PB + none + Executable + C + $(MSBuildProjectName) + .elf + $(MSBuildProjectDirectory)\$(Configuration) + idiBus_Ext + idiBus_Ext_3xThermo1HT + idiBus_Ext + Native + true + false + true + true + 0x20000000 + + true + exception_table + 2 + 0 + 0 + + + + + + + + + + + + + + com.atmel.avrdbg.tool.ispmk2 + 0000B809060C + 0x1E9516 + + + + + + + + com.atmel.avrdbg.tool.simulator + + + Simulator + + ISP + + + + 0 + + ISP + + com.atmel.avrdbg.tool.stk500 + + + STK500 + + 125000 + + + + 125000 + 0 + + ISP + + com.atmel.avrdbg.tool.atmelice + J41800094359 + Atmel-ICE + + + + + 125000 + + ISP + + com.atmel.avrdbg.tool.ispmk2 + 0000B809060C + AVRISP mkII + + + + + 125000 + + + + + custom + + + Custom Programming Tool + + 120 + + + + + + + -mmcu=atmega328pb -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb" + True + True + True + True + True + False + True + True + + + _CPU_ATMEGA328PB_ + NDEBUG + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + ../idiBusCoreFiles/IdiBus + ../idiBusFiles + ../moduleFiles + ../personalizationFiles + ../idiBusCoreFiles/CommonHW + + + Optimize for size (-Os) + True + True + True + + + libm + + + + + .locationInApp=0x37C0 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + + + + + $(SolutionDir)\FirmwareConverter\idiBusFmwPrepTool.exe $(avrdevice) "$(OutputDirectory)\$(OutputFileName).hex" "$(SolutionDir)\personalizationFiles\keys.h" "$(SolutionDir)\personalizationFiles\device.cfg" + + + + + -mmcu=atmega328pb -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb" + True + True + True + True + True + False + True + True + + + _CPU_ATMEGA328PB_ + DEBUG + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + ../idiBusCoreFiles/IdiBus + ../idiBusFiles + ../moduleFiles + ../personalizationFiles + ../idiBusCoreFiles/CommonHW + + + Optimize for size (-Os) + True + True + Maximum (-g3) + True + True + + + libm + + + + + .locationInApp=0x37C0 + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\1.7.374\include\ + + + Default (-Wa,-g) + + + + + $(SolutionDir)\FirmwareConverter\idiBusFmwPrepTool.exe $(avrdevice) "$(OutputDirectory)\$(OutputFileName).hex" "$(SolutionDir)\personalizationFiles\keys.h" "$(SolutionDir)\personalizationFiles\device.cfg" + + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + + + + + + + + compile + + + + + IdiCommon_328pb + {06e88371-de74-4663-a82f-031e45168730} + True + + + + \ No newline at end of file diff --git a/3xThermo1xHT/main.c b/3xThermo1xHT/main.c new file mode 100644 index 0000000..bef5508 --- /dev/null +++ b/3xThermo1xHT/main.c @@ -0,0 +1,86 @@ +//##################################################################################################################################################################################################### +// idiBus_Ext_4xADC0-10_APPL +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include "config.h" +#include +FUSES={ .extended=F_Ext, .high = F_High, .low = F_Low }; // Fuses + Lock programming +LOCKBITS=F_Lock; +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include "USART0.h" +#include "USART1.h" +#include "SPI.h" +#include "USART0Custom.h" +#include "RSLink.h" +#include "RSLinkCustom.h" +#include +#include "SYSTEMCustom.h" +#include "Common/MEMORY.h" +#include "IDIBUS_IMPL_Custom.h" +//##################################################################################################################################################################################################### +//uint8_t data_to_send[12] = {0x05, 0x4E, 0x20, 0x28, 0x01, 0x00, 0x01, 0x9C, 0x40, 0x28, 0x01, 0x01}; +int start_flag = 0; + +int main(void) +{ + //DDRD = 3; // USART PD0, PD1 + //PORTD = 3; + /////////////////////////////// + //STM NRST + DDRC = 0; + PORTC = 0; + /////////////////////////////// + //DDRE |= (1 << PORTE1); + //PORTE = 2; + +cli(); // Запрет прерываний +wdt_enable(WDTO_2S); // Watchdog таймер на 2 сек +wdt_reset(); // Сброс watchdog таймера, чтоб не срабатывал просто так +System_InitSysTick(); // Инициализация системного счетчика времени +System_SystickTimerStart(); // Запуск системного счетчика времени + +//USART0_Init(); +//USART0_INTERFACE.SetNewBaudrate(115200); +//USART_Init(8); +USART1_Init(); + +IDIBUS_ModuleInit(&USART1_INTERFACE, &STATIC_DATA_APP.Padding); +RSLink_Init(&USART1_INTERFACE, &USART1_IDIBUS); +sei(); //Find some place for this + +//uint8_t buf[3] = {'S','6'}; +//USART0_INTERFACE.SendByteBuf(&buf,2); + +// -----SPI----- +SPI_MasterInit(); + +//for (uint8_t i = 0; i < 12; i++) { + //USART_Transmit(data_to_send[i]); +//} + +while (1) + { + + if (start_flag == 0) { + STMReset(); + start_flag = 1; + } + + RSLink_Handler(); + //for (uint8_t i = 0; i < 12; i++) { + //data_to_send[i] = USART_Receive(); + //} + //_delay_ms(100); + //STMReset(); + //_delay_ms(100); + + //if ((PINC)&(1< THERMO_CHN_COUNT-1) ch = THERMO_CHN_COUNT-1; + + if ( ( RSLink_DipsRead() & (1<<(4+ch)) ) == 0) return 1; + + return 0; +} + +void Max_Handler(){ + ThermoData *Selected = &ThermoSensor[MaxSelectedChannel]; + + //If conversion ready or 5s timeout + if ((IsMaxDRDYLow(MaxSelectedChannel) || (System_GetSysTickDifference(Selected->lastTick)>2000)) && Selected->captureFlags != 0) { + sSPI_select(MaxSelectedChannel); + Selected->lastTick = System_GetSysTick(); + sSPI_write_byte(0x0A); + Selected->CJTemp = (uint16_t)sSPI_read_byte()<<8; + Selected->CJTemp |= sSPI_read_byte(); + Selected->Temperature = (uint32_t)sSPI_read_byte()<<11; + Selected->Temperature |= (uint32_t)sSPI_read_byte()<<3; + Selected->Temperature |= (uint32_t)sSPI_read_byte()>>5; + Selected->state = sSPI_read_byte()&(~4); + sSPI_free(); + if ((Selected->captureFlags & OneShotConversion) != 0){ + Selected->captureFlags &= ~(OneShotConversion); + } + } + + MaxSelectedChannel++; + if (MaxSelectedChannel == THERMO_CHN_COUNT) MaxSelectedChannel = 0; +} diff --git a/3xThermo1xHT/moduleFiles/MaxHandler.h b/3xThermo1xHT/moduleFiles/MaxHandler.h new file mode 100644 index 0000000..40c9c89 --- /dev/null +++ b/3xThermo1xHT/moduleFiles/MaxHandler.h @@ -0,0 +1,36 @@ +#ifndef MAXHANDLER_H_ +#define MAXHANDLER_H_ + +#include "software_SPI.h" +#include "RSLinkCustom.h" +#include "SYSTEM.h" + +//Define some channel stuff here +typedef struct{ + uint8_t state; + uint32_t Temperature; + uint16_t CJTemp; + uint32_t lastTick; + uint8_t captureFlags; + //uint8_t pin; + } ThermoData; + +#define THERMO_CHN_COUNT 3 //TODO Duplicate from IDIBUS_IMPL_Custom +//Also hardcoded value in sSPI +ThermoData ThermoSensor[THERMO_CHN_COUNT]; + +enum InitMode { //BitFlags + NoConversion = 0x00, + OneShotConversion = 0x01, + AutoConversion = 0x02 + }; + +uint8_t MaxSelectedChannel; + +void Max_Init(uint8_t ch, uint8_t initMode); + +uint8_t IsMaxDRDYLow(uint8_t ch); + +void Max_Handler(); + +#endif /* MAXHANDLER_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/moduleFiles/SPI.c b/3xThermo1xHT/moduleFiles/SPI.c new file mode 100644 index 0000000..8bf6030 --- /dev/null +++ b/3xThermo1xHT/moduleFiles/SPI.c @@ -0,0 +1,29 @@ +/* + * SPI.c + * + * Created: 24.10.2023 15:34:10 + * Author: Katya + */ + +#include "SPI.h" + +void SPI_MasterInit(void) { + // Настройка пина SS (PE2) как выхода + DDRE |= (1 << PORTE2); + // Установка SS в высокое состояние (неактивный) + PORTE |= (1 << PORTE2); + + /* Set MOSI, SS and SCK output */ + DDRE |= (1 << MOSI); + DDRC |= (1 << SCK) | (1 << SS); + + /* Enable SPI, Master */ + SPCR1 = (1 << SPE1) | (1 << MSTR1); +} + +void SPI_MasterTransmit(uint8_t data) { + PORTC &= ~(1 << PORTC2); // начало передачи - низкий уровень + SPDR1 = data; + while(!(SPSR1 & (1< +#include +#include +#include +#include + +void SPI_MasterInit (void); +void SPI_MasterTransmit(uint8_t data); + +#endif /* SPI_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/moduleFiles/USART0Custom.c b/3xThermo1xHT/moduleFiles/USART0Custom.c new file mode 100644 index 0000000..f2bcd6d --- /dev/null +++ b/3xThermo1xHT/moduleFiles/USART0Custom.c @@ -0,0 +1,33 @@ +/* + * USART0Custom.c + * + * Created: 26.10.2023 17:37:08 + * Author: Katya + */ + +#include "USART0Custom.h" + +void USART_Init (uint16_t speed) { + // Ст. и мл. скорость + UBRR0H = 0; + UBRR0L = (uint8_t)(speed); + // Прерывания при приеме, вкл прием/передача + UCSR0B = (1 << RXEN0) | (1 << TXEN0); + // 8 бит данных, 2 стоп-бита + UCSR0C = (1< +#include +#include +#include +#include +#include + +void USART_Init (uint16_t speed); +void USART_Transmit (uint8_t data); +uint8_t USART_Receive(); +uint8_t USART_DataAvailable(); + + +#endif /* USART0CUSTOM_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/moduleFiles/software_SPI.c b/3xThermo1xHT/moduleFiles/software_SPI.c new file mode 100644 index 0000000..1b1e735 --- /dev/null +++ b/3xThermo1xHT/moduleFiles/software_SPI.c @@ -0,0 +1,59 @@ +#include "software_SPI.h" + +void sSPI_init(){ + DDRC |= (1< 3/*Max channel count*/) return; + + sSPI_free(); + + if (ch == 3) + PORTD &= (~(0b111<<(PORTD2))); + else + PORTD &= (~(1<<(PORTD2+ch))); +} + +inline void sSPI_free(){ + PORTD |= (1< 0; i--){ + if ( (byte>>(i-1)) & 1 ) + MOSI_Hi; + else + MOSI_Lo; + + _delay_us(delay); + + CLK_invert; + + _delay_us(delay); + + CLK_invert; + } +} + +uint8_t sSPI_read_byte(){ + uint8_t rx = 0; + + for (uint8_t i = 8; i > 0; i--){ + CLK_invert; + + _delay_us(delay); + + rx |= ((PINC >> PORTC2)&1)<<(i-1); + + CLK_invert; + + _delay_us(delay); + } + + return rx; +} diff --git a/3xThermo1xHT/moduleFiles/software_SPI.h b/3xThermo1xHT/moduleFiles/software_SPI.h new file mode 100644 index 0000000..80297c1 --- /dev/null +++ b/3xThermo1xHT/moduleFiles/software_SPI.h @@ -0,0 +1,31 @@ +#ifndef SOFTWARE_SPI_H_ +#define SOFTWARE_SPI_H_ + + +#include +#include +#include + +#define delay 2 + + +//PC0 = clock +//PC1 = MOSI (output) +//PC2 = MISO (input) +//PC3-5 empty + +#define CLK_invert PORTC ^= (1< + +//Select one MCU + +//For 328pb +#ifdef _CPU_ATMEGA328PB_ + + #define PAGE_SIZE 128UL + #define PAGE_SIZE_BIT 7 + + //DONT FORGET TO CHANGE LINKER OPTIONS!!!! + #define locationInBoot (0x3FE8UL) //CAREFUL ONLY 48 byte in size for data + #define locationInApp (0x37C0UL) + + //FUSES + #define F_Low 0xE0 + #define F_Ext 0xFC + + #ifdef DEBUG + #define F_High 0xD0 //Allow DebugWIRE + EEPROM save + #define F_Lock 0xFF //Disable LOCKS + #else + #define F_High 0xC8 //No DEBUG thing + No EEPROM save + #define F_Lock 0xCC + #endif + + #define SRAM_size 2048UL + +#endif + +//For 2560 +#ifdef _CPU_ATMEGA2560_ + + #define _LONG_ADDR_SPACE_ + #define _FAT_CRC_ + + #define PAGE_SIZE 256ULL + #define PAGE_SIZE_BIT 8 + + //Settings in the linker + #define locationInBoot (0x1FF80ULL) + #define locationInApp (0x1EF80ULL) + + //FUSES + #define F_Low 0xE0 + #define F_Ext 0xFC + + #ifdef DEBUG + #define F_High 0x00 //Enable JTAG and OCD + EEPROM save + #define F_Lock 0xFF //Disable LOCKS + #else + #define F_High 0xC8 //No DEBUG thing + No EEPROM save + #define F_Lock 0xCC + #endif + + + #define SRAM_size 8192UL + +#endif + +//COMMON Define +#define PAGE_COUNT (((locationInApp<<1)/PAGE_SIZE)+1) + +#endif /* CONFIG_H_ */ \ No newline at end of file diff --git a/3xThermo1xHT/personalizationFiles/device.cfg b/3xThermo1xHT/personalizationFiles/device.cfg new file mode 100644 index 0000000..b101207 --- /dev/null +++ b/3xThermo1xHT/personalizationFiles/device.cfg @@ -0,0 +1,9 @@ +.GS1_country = {'1','2','3'}, //GS1 country (ASCII) +.GS1_company = {'1','2','3','4','5','6'}, //GS1 company (ASCII) +.ModuleType = {'G','N','1' }, //Module type (ASCII) +.HW_revision = {0, 7}, //HW Revision (Binary) +.SN = {'A','N','O','T','H','E','R'}, //Serial number (ASCII) +.MAC = {255,250,230,128,127,1}, //MAC addr (Binary) +#ifdef APP_VERSION +.SW = {0, 0x01 }, //SW App Version (Binary) (DO NOT SHUFFLE VERSIONS) +#endif \ No newline at end of file diff --git a/3xThermo1xHT/personalizationFiles/keys.h b/3xThermo1xHT/personalizationFiles/keys.h new file mode 100644 index 0000000..d334d62 --- /dev/null +++ b/3xThermo1xHT/personalizationFiles/keys.h @@ -0,0 +1,7 @@ +#ifndef KEYS_H_ +#define KEYS_H_ + +const uint8_t IV[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +const uint8_t key[32] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F}; + +#endif /* KEYS_H_ */ \ No newline at end of file diff --git a/GccApplication1/.vs/GccApplication1/v14/.atsuo b/GccApplication1/.vs/GccApplication1/v14/.atsuo new file mode 100644 index 0000000000000000000000000000000000000000..f654d7faf16ca0ca0273e9271f8cd3302a02ba69 GIT binary patch literal 64512 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 STf$bJI8_G|Hdl3gF#SKW2b`h+ literal 0 HcmV?d00001 diff --git a/GccApplication1/GccApplication1.atsln b/GccApplication1/GccApplication1.atsln new file mode 100644 index 0000000..df52c4b --- /dev/null +++ b/GccApplication1/GccApplication1.atsln @@ -0,0 +1,22 @@ +п»ї +Microsoft Visual Studio Solution File, Format Version 12.00 +# Atmel Studio Solution File, Format Version 11.00 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "GccApplication1", "GccApplication1\GccApplication1.cproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|AVR = Debug|AVR + Release|AVR = Release|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|AVR.ActiveCfg = Debug|AVR + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|AVR.Build.0 = Debug|AVR + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|AVR.ActiveCfg = Release|AVR + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|AVR.Build.0 = Release|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/GccApplication1/GccApplication1/Debug/GccApplication1.eep b/GccApplication1/GccApplication1/Debug/GccApplication1.eep new file mode 100644 index 0000000..7c166a1 --- /dev/null +++ b/GccApplication1/GccApplication1/Debug/GccApplication1.eep @@ -0,0 +1 @@ +:00000001FF diff --git a/GccApplication1/GccApplication1/Debug/GccApplication1.elf b/GccApplication1/GccApplication1/Debug/GccApplication1.elf new file mode 100644 index 0000000000000000000000000000000000000000..2e5eca5d9542539632905fd62e0719b9afc8b408 GIT binary patch literal 14984 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 literal 0 HcmV?d00001 diff --git a/GccApplication1/GccApplication1/Debug/GccApplication1.hex b/GccApplication1/GccApplication1/Debug/GccApplication1.hex new file mode 100644 index 0000000..78e0862 --- /dev/null +++ b/GccApplication1/GccApplication1/Debug/GccApplication1.hex @@ -0,0 +1,36 @@ +:100000000C945A000C9477000C9477000C947700B1 +:100010000C9477000C9477000C9477000C94770084 +:100020000C9477000C9477000C9477000C94770074 +:100030000C9477000C9477000C9477000C94770064 +:100040000C9477000C9477000C9477000C94770054 +:100050000C9477000C9477000C9477000C94770044 +:100060000C9477000C9477000C9477000C94770034 +:100070000C9477000C9477000C9477000C94770024 +:100080000C9477000C9477000C9477000C94770014 +:100090000C9477000C9477000C9477000C94770004 +:1000A0000C9477000C9477000C9477000C947700F4 +:1000B0000C94770011241FBECFEFD8E0DEBFCDBF78 +:1000C00011E0A0E0B1E0E8E1F2E002C005900D929D +:1000D000AC30B107D9F721E0ACE0B1E001C01D922E +:1000E000AC30B207E1F70E948F000C940A010C9427 +:1000F00000003C9A44982FEF81EE94E0215080401C +:100100009040E1F700C000003C982FEF81EE94E0B2 +:10011000215080409040E1F700C000000895CF9347 +:10012000DF93CDB7DEB72C970FB6F894DEBF0FBEC6 +:10013000CDBF8CE0E0E0F1E0DE01119601900D9280 +:100140008A95E1F783E08AB98BB917B818B8699A2C +:100150006A98729888E090E00E94F70078940E9474 +:10016000D4006E012DE0C20ED11C0E947900339B99 +:10017000FCCF719A8FEF93EDE0E381509040E04027 +:10018000E1F700C000008E010F5F1F4FF801F190F2 +:100190008F018F2D0E9402018F2D0E94DE000C1511 +:1001A0001D05A1F77198E1CF6A9A729A6B9A87B18F +:1001B000866087B980E58093AC000895429880936B +:1001C000AE008091AD00882384F0EDEAF0E0719AF2 +:1001D0002FEF81EE94E0215080409040E1F700C085 +:1001E000000071988081882394F7429A08951092B4 +:1001F000C5008093C40088E18093C1008EE08093A5 +:10020000C2000895E0ECF0E0908195FFFDCF80936F +:08021000C6000895F894FFCF29 +:0C021800014E20280100019C402801013B +:00000001FF diff --git a/GccApplication1/GccApplication1/Debug/GccApplication1.lss b/GccApplication1/GccApplication1/Debug/GccApplication1.lss new file mode 100644 index 0000000..1d0a371 --- /dev/null +++ b/GccApplication1/GccApplication1/Debug/GccApplication1.lss @@ -0,0 +1,385 @@ + +GccApplication1.elf: file format elf32-avr + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .data 0000000c 00800100 00000218 0000028c 2**0 + CONTENTS, ALLOC, LOAD, DATA + 1 .text 00000218 00000000 00000000 00000074 2**1 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 2 .comment 00000030 00000000 00000000 00000298 2**0 + CONTENTS, READONLY + 3 .note.gnu.avr.deviceinfo 00000040 00000000 00000000 000002c8 2**2 + CONTENTS, READONLY + 4 .debug_aranges 00000088 00000000 00000000 00000308 2**0 + CONTENTS, READONLY, DEBUGGING + 5 .debug_info 00000d91 00000000 00000000 00000390 2**0 + CONTENTS, READONLY, DEBUGGING + 6 .debug_abbrev 00000b49 00000000 00000000 00001121 2**0 + CONTENTS, READONLY, DEBUGGING + 7 .debug_line 00000601 00000000 00000000 00001c6a 2**0 + CONTENTS, READONLY, DEBUGGING + 8 .debug_frame 000000cc 00000000 00000000 0000226c 2**2 + CONTENTS, READONLY, DEBUGGING + 9 .debug_str 0000054c 00000000 00000000 00002338 2**0 + CONTENTS, READONLY, DEBUGGING + 10 .debug_loc 000001f6 00000000 00000000 00002884 2**0 + CONTENTS, READONLY, DEBUGGING + 11 .debug_ranges 00000058 00000000 00000000 00002a7a 2**0 + CONTENTS, READONLY, DEBUGGING + +Disassembly of section .text: + +00000000 <__vectors>: + 0: 0c 94 5a 00 jmp 0xb4 ; 0xb4 <__ctors_end> + 4: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 8: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + c: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 10: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 14: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 18: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 1c: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 20: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 24: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 28: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 2c: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 30: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 34: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 38: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 3c: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 40: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 44: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 48: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 4c: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 50: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 54: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 58: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 5c: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 60: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 64: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 68: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 6c: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 70: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 74: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 78: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 7c: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 80: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 84: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 88: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 8c: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 90: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 94: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 98: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + 9c: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + a0: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + a4: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + a8: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + ac: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + b0: 0c 94 77 00 jmp 0xee ; 0xee <__bad_interrupt> + +000000b4 <__ctors_end>: + b4: 11 24 eor r1, r1 + b6: 1f be out 0x3f, r1 ; 63 + b8: cf ef ldi r28, 0xFF ; 255 + ba: d8 e0 ldi r29, 0x08 ; 8 + bc: de bf out 0x3e, r29 ; 62 + be: cd bf out 0x3d, r28 ; 61 + +000000c0 <__do_copy_data>: + c0: 11 e0 ldi r17, 0x01 ; 1 + c2: a0 e0 ldi r26, 0x00 ; 0 + c4: b1 e0 ldi r27, 0x01 ; 1 + c6: e8 e1 ldi r30, 0x18 ; 24 + c8: f2 e0 ldi r31, 0x02 ; 2 + ca: 02 c0 rjmp .+4 ; 0xd0 <__do_copy_data+0x10> + cc: 05 90 lpm r0, Z+ + ce: 0d 92 st X+, r0 + d0: ac 30 cpi r26, 0x0C ; 12 + d2: b1 07 cpc r27, r17 + d4: d9 f7 brne .-10 ; 0xcc <__do_copy_data+0xc> + +000000d6 <__do_clear_bss>: + d6: 21 e0 ldi r18, 0x01 ; 1 + d8: ac e0 ldi r26, 0x0C ; 12 + da: b1 e0 ldi r27, 0x01 ; 1 + dc: 01 c0 rjmp .+2 ; 0xe0 <.do_clear_bss_start> + +000000de <.do_clear_bss_loop>: + de: 1d 92 st X+, r1 + +000000e0 <.do_clear_bss_start>: + e0: ac 30 cpi r26, 0x0C ; 12 + e2: b2 07 cpc r27, r18 + e4: e1 f7 brne .-8 ; 0xde <.do_clear_bss_loop> + e6: 0e 94 8f 00 call 0x11e ; 0x11e
    + ea: 0c 94 0a 01 jmp 0x214 ; 0x214 <_exit> + +000000ee <__bad_interrupt>: + ee: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> + +000000f2 : + } + } +} + + void STMReset() { + DDRC |= (1 << PINC4); + f2: 3c 9a sbi 0x07, 4 ; 7 + PORTC &= ~(1 << PINC4); + f4: 44 98 cbi 0x08, 4 ; 8 + #else + //round up by default + __ticks_dc = (uint32_t)(ceil(fabs(__tmp))); + #endif + + __builtin_avr_delay_cycles(__ticks_dc); + f6: 2f ef ldi r18, 0xFF ; 255 + f8: 81 ee ldi r24, 0xE1 ; 225 + fa: 94 e0 ldi r25, 0x04 ; 4 + fc: 21 50 subi r18, 0x01 ; 1 + fe: 80 40 sbci r24, 0x00 ; 0 + 100: 90 40 sbci r25, 0x00 ; 0 + 102: e1 f7 brne .-8 ; 0xfc + 104: 00 c0 rjmp .+0 ; 0x106 + 106: 00 00 nop + _delay_ms(100); + DDRC &= ~(1 << PINC4); + 108: 3c 98 cbi 0x07, 4 ; 7 + 10a: 2f ef ldi r18, 0xFF ; 255 + 10c: 81 ee ldi r24, 0xE1 ; 225 + 10e: 94 e0 ldi r25, 0x04 ; 4 + 110: 21 50 subi r18, 0x01 ; 1 + 112: 80 40 sbci r24, 0x00 ; 0 + 114: 90 40 sbci r25, 0x00 ; 0 + 116: e1 f7 brne .-8 ; 0x110 + 118: 00 c0 rjmp .+0 ; 0x11a + 11a: 00 00 nop + 11c: 08 95 ret + +0000011e
    : + //bytes++; + //PORTE = 0; +//} + +int main(void) +{ + 11e: cf 93 push r28 + 120: df 93 push r29 + 122: cd b7 in r28, 0x3d ; 61 + 124: de b7 in r29, 0x3e ; 62 + 126: 2c 97 sbiw r28, 0x0c ; 12 + 128: 0f b6 in r0, 0x3f ; 63 + 12a: f8 94 cli + 12c: de bf out 0x3e, r29 ; 62 + 12e: 0f be out 0x3f, r0 ; 63 + 130: cd bf out 0x3d, r28 ; 61 + uint8_t data_to_send[] = {0x01, 0x4E, 0x20, 0x28, 0x01, 0x00, 0x01, 0x9C, 0x40, 0x28, 0x01, 0x01}; + 132: 8c e0 ldi r24, 0x0C ; 12 + 134: e0 e0 ldi r30, 0x00 ; 0 + 136: f1 e0 ldi r31, 0x01 ; 1 + 138: de 01 movw r26, r28 + 13a: 11 96 adiw r26, 0x01 ; 1 + 13c: 01 90 ld r0, Z+ + 13e: 0d 92 st X+, r0 + 140: 8a 95 dec r24 + 142: e1 f7 brne .-8 ; 0x13c + DDRD = 3; // USART PD0, PD1 + 144: 83 e0 ldi r24, 0x03 ; 3 + 146: 8a b9 out 0x0a, r24 ; 10 + PORTD = 3; + 148: 8b b9 out 0x0b, r24 ; 11 + /////////////////////////////// + //STM NRST + DDRC = 0; + 14a: 17 b8 out 0x07, r1 ; 7 + PORTC = 0; + 14c: 18 b8 out 0x08, r1 ; 8 + /////////////////////////////// + DDRE |= (1 << PORTE1); + 14e: 69 9a sbi 0x0d, 1 ; 13 + DDRE &= ~(1 << PORTE2); + 150: 6a 98 cbi 0x0d, 2 ; 13 + PORTE &= ~(1 << PORTE2); + 152: 72 98 cbi 0x0e, 2 ; 14 + //PORTE = 2; + + USART_Init(8); // установка скорости 115200: (16 000 000 / (16 * 115 200) ) - 1, U2X = 0 + 154: 88 e0 ldi r24, 0x08 ; 8 + 156: 90 e0 ldi r25, 0x00 ; 0 + 158: 0e 94 f7 00 call 0x1ee ; 0x1ee + sei(); + 15c: 78 94 sei + + // -----SPI----- + SPI_MasterInit(); + 15e: 0e 94 d4 00 call 0x1a8 ; 0x1a8 + 162: 6e 01 movw r12, r28 + 164: 2d e0 ldi r18, 0x0D ; 13 + 166: c2 0e add r12, r18 + 168: d1 1c adc r13, r1 + //PORTE &= ~(1 << PORTE1); // STATUS выкл + //for (uint8_t i = 0; i < 12; i++) { + //USART_Transmit(data_to_send[i]); + //} + // $05$4E$20$28$01$00$03$9C$40$28$01$01 + STMReset(); + 16a: 0e 94 79 00 call 0xf2 ; 0xf2 + //_delay_ms(100); + //PORTE &= ~(1 << PORTE1); // STATUS выкл + // + //PORTE |= (1 << PORTE1); // STATUS вкл + + if ((PINC)&(1< + PORTE |= (1 << PORTE1); // STATUS вкл + 172: 71 9a sbi 0x0e, 1 ; 14 + 174: 8f ef ldi r24, 0xFF ; 255 + 176: 93 ed ldi r25, 0xD3 ; 211 + 178: e0 e3 ldi r30, 0x30 ; 48 + 17a: 81 50 subi r24, 0x01 ; 1 + 17c: 90 40 sbci r25, 0x00 ; 0 + 17e: e0 40 sbci r30, 0x00 ; 0 + 180: e1 f7 brne .-8 ; 0x17a + 182: 00 c0 rjmp .+0 ; 0x184 + 184: 00 00 nop + 186: 8e 01 movw r16, r28 + 188: 0f 5f subi r16, 0xFF ; 255 + 18a: 1f 4f sbci r17, 0xFF ; 255 + _delay_ms(1000); + for (int i = 0; i < 12; i++) { + USART_Transmit(data_to_send[i]); + 18c: f8 01 movw r30, r16 + 18e: f1 90 ld r15, Z+ + 190: 8f 01 movw r16, r30 + 192: 8f 2d mov r24, r15 + 194: 0e 94 02 01 call 0x204 ; 0x204 + SPI_MasterTransmit(data_to_send[i]); + 198: 8f 2d mov r24, r15 + 19a: 0e 94 de 00 call 0x1bc ; 0x1bc + //PORTE |= (1 << PORTE1); // STATUS вкл + + if ((PINC)&(1< + USART_Transmit(data_to_send[i]); + SPI_MasterTransmit(data_to_send[i]); + } + PORTE &= ~(1 << PORTE1); // STATUS выкл + 1a4: 71 98 cbi 0x0e, 1 ; 14 + 1a6: e1 cf rjmp .-62 ; 0x16a + +000001a8 : + */ +#include "spi.h" + +void SPI_MasterInit(void) { + // Настройка пина SS (PB2) как выхода + DDRE |= (1 << PORTE2); + 1a8: 6a 9a sbi 0x0d, 2 ; 13 + + // Установка SS в высокое состояние (неактивный) + PORTE |= (1 << PORTE2); + 1aa: 72 9a sbi 0x0e, 2 ; 14 + /* Set MOSI, SS and SCK output */ + DDRE |= (1 << MOSI); + 1ac: 6b 9a sbi 0x0d, 3 ; 13 + DDRC |= (1 << SCK) | (1 << SS); + 1ae: 87 b1 in r24, 0x07 ; 7 + 1b0: 86 60 ori r24, 0x06 ; 6 + 1b2: 87 b9 out 0x07, r24 ; 7 + + /* Enable SPI, Master */ + SPCR1 = (1 << SPE1) | (1 << MSTR1); + 1b4: 80 e5 ldi r24, 0x50 ; 80 + 1b6: 80 93 ac 00 sts 0x00AC, r24 ; 0x8000ac <__TEXT_REGION_LENGTH__+0x7f80ac> + 1ba: 08 95 ret + +000001bc : +} + +void SPI_MasterTransmit(uint8_t data) { + PORTC &= ~(1 << PORTC2); // начало передачи - низкий уровень + 1bc: 42 98 cbi 0x08, 2 ; 8 + SPDR1 = data; + 1be: 80 93 ae 00 sts 0x00AE, r24 ; 0x8000ae <__TEXT_REGION_LENGTH__+0x7f80ae> + while(!(SPSR1 & (1< + 1c6: 88 23 and r24, r24 + 1c8: 84 f0 brlt .+32 ; 0x1ea + 1ca: ed ea ldi r30, 0xAD ; 173 + 1cc: f0 e0 ldi r31, 0x00 ; 0 + PORTE |= (1 << PORTE1); // STATUS вкл + 1ce: 71 9a sbi 0x0e, 1 ; 14 + 1d0: 2f ef ldi r18, 0xFF ; 255 + 1d2: 81 ee ldi r24, 0xE1 ; 225 + 1d4: 94 e0 ldi r25, 0x04 ; 4 + 1d6: 21 50 subi r18, 0x01 ; 1 + 1d8: 80 40 sbci r24, 0x00 ; 0 + 1da: 90 40 sbci r25, 0x00 ; 0 + 1dc: e1 f7 brne .-8 ; 0x1d6 + 1de: 00 c0 rjmp .+0 ; 0x1e0 + 1e0: 00 00 nop + _delay_ms(100); + PORTE &= ~(1 << PORTE1); // STATUS выкл + 1e2: 71 98 cbi 0x0e, 1 ; 14 +} + +void SPI_MasterTransmit(uint8_t data) { + PORTC &= ~(1 << PORTC2); // начало передачи - низкий уровень + SPDR1 = data; + while(!(SPSR1 & (1< + PORTE |= (1 << PORTE1); // STATUS вкл + _delay_ms(100); + PORTE &= ~(1 << PORTE1); // STATUS выкл + } + PORTC |= (1 << PORTC2); // конец передачи - высокий уровень + 1ea: 42 9a sbi 0x08, 2 ; 8 + 1ec: 08 95 ret + +000001ee : + +#include "usart0.h" + +void USART_Init (uint16_t speed) { + // Ст. и мл. скорость + UBRR0H = 0; + 1ee: 10 92 c5 00 sts 0x00C5, r1 ; 0x8000c5 <__TEXT_REGION_LENGTH__+0x7f80c5> + UBRR0L = (uint8_t)(speed); + 1f2: 80 93 c4 00 sts 0x00C4, r24 ; 0x8000c4 <__TEXT_REGION_LENGTH__+0x7f80c4> + // Прерывания при приеме, вкл прием/передача + UCSR0B = (1 << RXEN0) | (1 << TXEN0); + 1f6: 88 e1 ldi r24, 0x18 ; 24 + 1f8: 80 93 c1 00 sts 0x00C1, r24 ; 0x8000c1 <__TEXT_REGION_LENGTH__+0x7f80c1> + // 8 бит данных, 2 стоп-бита + UCSR0C = (1< + 202: 08 95 ret + +00000204 : +} + +void USART_Transmit (uint8_t data) { + while (!(UCSR0A & (1< + UDR0 = data; // Начало передачи + 20e: 80 93 c6 00 sts 0x00C6, r24 ; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7f80c6> + 212: 08 95 ret + +00000214 <_exit>: + 214: f8 94 cli + +00000216 <__stop_program>: + 216: ff cf rjmp .-2 ; 0x216 <__stop_program> diff --git a/GccApplication1/GccApplication1/Debug/GccApplication1.map b/GccApplication1/GccApplication1/Debug/GccApplication1.map new file mode 100644 index 0000000..424f245 --- /dev/null +++ b/GccApplication1/GccApplication1/Debug/GccApplication1.map @@ -0,0 +1,549 @@ +Archive member included to satisfy reference by file (symbol) + +c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o (exit) +c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + main.o (__do_copy_data) +c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + main.o (__do_clear_bss) + +Discarded input sections + + .data 0x00000000 0x0 C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + .bss 0x00000000 0x0 C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + .text 0x00000000 0x0 delay.o + .data 0x00000000 0x0 delay.o + .bss 0x00000000 0x0 delay.o + .text.delay8 0x00000000 0xa delay.o + .text.delay16 0x00000000 0xe delay.o + .text.init_PUTR + 0x00000000 0x6 delay.o + .text.PUTR 0x00000000 0x94 delay.o + .debug_info 0x00000000 0x19a delay.o + .debug_abbrev 0x00000000 0xf1 delay.o + .debug_loc 0x00000000 0x112 delay.o + .debug_aranges + 0x00000000 0x38 delay.o + .debug_ranges 0x00000000 0x28 delay.o + .debug_line 0x00000000 0x148 delay.o + .debug_str 0x00000000 0x1a4 delay.o + .comment 0x00000000 0x31 delay.o + .debug_frame 0x00000000 0x78 delay.o + .text 0x00000000 0x0 main.o + .data 0x00000000 0x0 main.o + .bss 0x00000000 0x0 main.o + .bss.bytes 0x00000000 0x2 main.o + .text 0x00000000 0x0 spi.o + .data 0x00000000 0x0 spi.o + .bss 0x00000000 0x0 spi.o + .text 0x00000000 0x0 usart0.o + .data 0x00000000 0x0 usart0.o + .bss 0x00000000 0x0 usart0.o + .text.USART_Receive + 0x00000000 0x10 usart0.o + .text.USART_DataAvailable + 0x00000000 0xc usart0.o + .text 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + .data 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + .text.libgcc.mul + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + .text.libgcc.fixed + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + .data 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + .text.libgcc.mul + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + .text.libgcc.fixed + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + .data 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + .text.libgcc.mul + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + .text.libgcc.fixed + 0x00000000 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + +Memory Configuration + +Name Origin Length Attributes +text 0x00000000 0x00008000 xr +data 0x00800100 0x00000800 rw !x +eeprom 0x00810000 0x00000400 rw !x +fuse 0x00820000 0x00000003 rw !x +lock 0x00830000 0x00000400 rw !x +signature 0x00840000 0x00000400 rw !x +user_signatures 0x00850000 0x00000400 rw !x +*default* 0x00000000 0xffffffff + +Linker script and memory map + +Address of section .data set to 0x800100 +LOAD C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o +LOAD delay.o +LOAD main.o +LOAD spi.o +LOAD usart0.o +START GROUP +LOAD c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/../../../../avr/lib/avr5\libm.a +END GROUP +START GROUP +LOAD c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a +LOAD c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/../../../../avr/lib/avr5\libm.a +LOAD c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/../../../../avr/lib/avr5\libc.a +LOAD C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5\libatmega328pb.a +END GROUP + [0x00000000] __TEXT_REGION_ORIGIN__ = DEFINED (__TEXT_REGION_ORIGIN__)?__TEXT_REGION_ORIGIN__:0x0 + [0x00800100] __DATA_REGION_ORIGIN__ = DEFINED (__DATA_REGION_ORIGIN__)?__DATA_REGION_ORIGIN__:0x800060 + [0x00008000] __TEXT_REGION_LENGTH__ = DEFINED (__TEXT_REGION_LENGTH__)?__TEXT_REGION_LENGTH__:0x20000 + [0x00000800] __DATA_REGION_LENGTH__ = DEFINED (__DATA_REGION_LENGTH__)?__DATA_REGION_LENGTH__:0xffa0 + [0x00000400] __EEPROM_REGION_LENGTH__ = DEFINED (__EEPROM_REGION_LENGTH__)?__EEPROM_REGION_LENGTH__:0x10000 + [0x00000003] __FUSE_REGION_LENGTH__ = DEFINED (__FUSE_REGION_LENGTH__)?__FUSE_REGION_LENGTH__:0x400 + 0x00000400 __LOCK_REGION_LENGTH__ = DEFINED (__LOCK_REGION_LENGTH__)?__LOCK_REGION_LENGTH__:0x400 + 0x00000400 __SIGNATURE_REGION_LENGTH__ = DEFINED (__SIGNATURE_REGION_LENGTH__)?__SIGNATURE_REGION_LENGTH__:0x400 + 0x00000400 __USER_SIGNATURE_REGION_LENGTH__ = DEFINED (__USER_SIGNATURE_REGION_LENGTH__)?__USER_SIGNATURE_REGION_LENGTH__:0x400 + +.hash + *(.hash) + +.dynsym + *(.dynsym) + +.dynstr + *(.dynstr) + +.gnu.version + *(.gnu.version) + +.gnu.version_d + *(.gnu.version_d) + +.gnu.version_r + *(.gnu.version_r) + +.rel.init + *(.rel.init) + +.rela.init + *(.rela.init) + +.rel.text + *(.rel.text) + *(.rel.text.*) + *(.rel.gnu.linkonce.t*) + +.rela.text + *(.rela.text) + *(.rela.text.*) + *(.rela.gnu.linkonce.t*) + +.rel.fini + *(.rel.fini) + +.rela.fini + *(.rela.fini) + +.rel.rodata + *(.rel.rodata) + *(.rel.rodata.*) + *(.rel.gnu.linkonce.r*) + +.rela.rodata + *(.rela.rodata) + *(.rela.rodata.*) + *(.rela.gnu.linkonce.r*) + +.rel.data + *(.rel.data) + *(.rel.data.*) + *(.rel.gnu.linkonce.d*) + +.rela.data + *(.rela.data) + *(.rela.data.*) + *(.rela.gnu.linkonce.d*) + +.rel.ctors + *(.rel.ctors) + +.rela.ctors + *(.rela.ctors) + +.rel.dtors + *(.rel.dtors) + +.rela.dtors + *(.rela.dtors) + +.rel.got + *(.rel.got) + +.rela.got + *(.rela.got) + +.rel.bss + *(.rel.bss) + +.rela.bss + *(.rela.bss) + +.rel.plt + *(.rel.plt) + +.rela.plt + *(.rela.plt) + +.text 0x00000000 0x218 + *(.vectors) + .vectors 0x00000000 0xb4 C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + 0x00000000 __vector_default + 0x00000000 __vectors + *(.vectors) + *(.progmem.gcc*) + 0x000000b4 . = ALIGN (0x2) + 0x000000b4 __trampolines_start = . + *(.trampolines) + .trampolines 0x000000b4 0x0 linker stubs + *(.trampolines*) + 0x000000b4 __trampolines_end = . + *libprintf_flt.a:*(.progmem.data) + *libc.a:*(.progmem.data) + *(.progmem*) + 0x000000b4 . = ALIGN (0x2) + *(.jumptables) + *(.jumptables*) + *(.lowtext) + *(.lowtext*) + 0x000000b4 __ctors_start = . + *(.ctors) + 0x000000b4 __ctors_end = . + 0x000000b4 __dtors_start = . + *(.dtors) + 0x000000b4 __dtors_end = . + SORT(*)(.ctors) + SORT(*)(.dtors) + *(.init0) + .init0 0x000000b4 0x0 C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + 0x000000b4 __init + *(.init0) + *(.init1) + *(.init1) + *(.init2) + .init2 0x000000b4 0xc C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + *(.init2) + *(.init3) + *(.init3) + *(.init4) + .init4 0x000000c0 0x16 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_copy_data.o) + 0x000000c0 __do_copy_data + .init4 0x000000d6 0x10 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_clear_bss.o) + 0x000000d6 __do_clear_bss + *(.init4) + *(.init5) + *(.init5) + *(.init6) + *(.init6) + *(.init7) + *(.init7) + *(.init8) + *(.init8) + *(.init9) + .init9 0x000000e6 0x8 C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + *(.init9) + *(.text) + .text 0x000000ee 0x4 C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + 0x000000ee __vector_38 + 0x000000ee __vector_22 + 0x000000ee __vector_28 + 0x000000ee __vector_1 + 0x000000ee __vector_32 + 0x000000ee __vector_34 + 0x000000ee __vector_24 + 0x000000ee __vector_12 + 0x000000ee __bad_interrupt + 0x000000ee __vector_6 + 0x000000ee __vector_31 + 0x000000ee __vector_35 + 0x000000ee __vector_39 + 0x000000ee __vector_3 + 0x000000ee __vector_23 + 0x000000ee __vector_30 + 0x000000ee __vector_25 + 0x000000ee __vector_11 + 0x000000ee __vector_13 + 0x000000ee __vector_17 + 0x000000ee __vector_19 + 0x000000ee __vector_7 + 0x000000ee __vector_41 + 0x000000ee __vector_43 + 0x000000ee __vector_27 + 0x000000ee __vector_5 + 0x000000ee __vector_33 + 0x000000ee __vector_37 + 0x000000ee __vector_4 + 0x000000ee __vector_44 + 0x000000ee __vector_9 + 0x000000ee __vector_2 + 0x000000ee __vector_21 + 0x000000ee __vector_15 + 0x000000ee __vector_36 + 0x000000ee __vector_29 + 0x000000ee __vector_40 + 0x000000ee __vector_8 + 0x000000ee __vector_26 + 0x000000ee __vector_14 + 0x000000ee __vector_10 + 0x000000ee __vector_16 + 0x000000ee __vector_18 + 0x000000ee __vector_20 + 0x000000ee __vector_42 + 0x000000f2 . = ALIGN (0x2) + *(.text.*) + .text.STMReset + 0x000000f2 0x2c main.o + 0x000000f2 STMReset + .text.main 0x0000011e 0x8a main.o + 0x0000011e main + .text.SPI_MasterInit + 0x000001a8 0x14 spi.o + 0x000001a8 SPI_MasterInit + .text.SPI_MasterTransmit + 0x000001bc 0x32 spi.o + 0x000001bc SPI_MasterTransmit + .text.USART_Init + 0x000001ee 0x16 usart0.o + 0x000001ee USART_Init + .text.USART_Transmit + 0x00000204 0x10 usart0.o + 0x00000204 USART_Transmit + 0x00000214 . = ALIGN (0x2) + *(.fini9) + .fini9 0x00000214 0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + 0x00000214 _exit + 0x00000214 exit + *(.fini9) + *(.fini8) + *(.fini8) + *(.fini7) + *(.fini7) + *(.fini6) + *(.fini6) + *(.fini5) + *(.fini5) + *(.fini4) + *(.fini4) + *(.fini3) + *(.fini3) + *(.fini2) + *(.fini2) + *(.fini1) + *(.fini1) + *(.fini0) + .fini0 0x00000214 0x4 c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr5\libgcc.a(_exit.o) + *(.fini0) + 0x00000218 _etext = . + +.data 0x00800100 0xc load address 0x00000218 + 0x00800100 PROVIDE (__data_start, .) + *(.data) + *(.data*) + *(.gnu.linkonce.d*) + *(.rodata) + .rodata 0x00800100 0xc main.o + *(.rodata*) + *(.gnu.linkonce.r*) + 0x0080010c . = ALIGN (0x2) + 0x0080010c _edata = . + 0x0080010c PROVIDE (__data_end, .) + +.bss 0x0080010c 0x0 + 0x0080010c PROVIDE (__bss_start, .) + *(.bss) + *(.bss*) + *(COMMON) + 0x0080010c PROVIDE (__bss_end, .) + 0x00000218 __data_load_start = LOADADDR (.data) + 0x00000224 __data_load_end = (__data_load_start + SIZEOF (.data)) + +.noinit 0x0080010c 0x0 + [!provide] PROVIDE (__noinit_start, .) + *(.noinit*) + [!provide] PROVIDE (__noinit_end, .) + 0x0080010c _end = . + [!provide] PROVIDE (__heap_start, .) + +.eeprom 0x00810000 0x0 + *(.eeprom*) + 0x00810000 __eeprom_end = . + +.fuse + *(.fuse) + *(.lfuse) + *(.hfuse) + *(.efuse) + +.lock + *(.lock*) + +.signature + *(.signature*) + +.user_signatures + *(.user_signatures*) + +.stab + *(.stab) + +.stabstr + *(.stabstr) + +.stab.excl + *(.stab.excl) + +.stab.exclstr + *(.stab.exclstr) + +.stab.index + *(.stab.index) + +.stab.indexstr + *(.stab.indexstr) + +.comment 0x00000000 0x30 + *(.comment) + .comment 0x00000000 0x30 main.o + 0x31 (size before relaxing) + .comment 0x00000030 0x31 spi.o + .comment 0x00000030 0x31 usart0.o + +.note.gnu.avr.deviceinfo + 0x00000000 0x40 + .note.gnu.avr.deviceinfo + 0x00000000 0x40 C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + +.note.gnu.build-id + *(.note.gnu.build-id) + +.debug + *(.debug) + +.line + *(.line) + +.debug_srcinfo + *(.debug_srcinfo) + +.debug_sfnames + *(.debug_sfnames) + +.debug_aranges 0x00000000 0x88 + *(.debug_aranges) + .debug_aranges + 0x00000000 0x28 main.o + .debug_aranges + 0x00000028 0x28 spi.o + .debug_aranges + 0x00000050 0x38 usart0.o + +.debug_pubnames + *(.debug_pubnames) + +.debug_info 0x00000000 0xd91 + *(.debug_info .gnu.linkonce.wi.*) + .debug_info 0x00000000 0x8ea C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + .debug_info 0x000008ea 0x274 main.o + .debug_info 0x00000b5e 0x130 spi.o + .debug_info 0x00000c8e 0x103 usart0.o + +.debug_abbrev 0x00000000 0xb49 + *(.debug_abbrev) + .debug_abbrev 0x00000000 0x86e C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + .debug_abbrev 0x0000086e 0x174 main.o + .debug_abbrev 0x000009e2 0xde spi.o + .debug_abbrev 0x00000ac0 0x89 usart0.o + +.debug_line 0x00000000 0x601 + *(.debug_line .debug_line.* .debug_line_end) + .debug_line 0x00000000 0x1a6 C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + .debug_line 0x000001a6 0x1d2 main.o + .debug_line 0x00000378 0x162 spi.o + .debug_line 0x000004da 0x127 usart0.o + +.debug_frame 0x00000000 0xcc + *(.debug_frame) + .debug_frame 0x00000000 0x44 main.o + .debug_frame 0x00000044 0x34 spi.o + .debug_frame 0x00000078 0x54 usart0.o + +.debug_str 0x00000000 0x54c + *(.debug_str) + .debug_str 0x00000000 0x318 C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/gcc/dev/atmega328pb/avr5/crtatmega328pb.o + .debug_str 0x00000318 0x1e5 main.o + 0x21e (size before relaxing) + .debug_str 0x000004fd 0x10 spi.o + 0x1de (size before relaxing) + .debug_str 0x0000050d 0x3f usart0.o + 0x1bf (size before relaxing) + +.debug_loc 0x00000000 0x1f6 + *(.debug_loc) + .debug_loc 0x00000000 0x169 main.o + .debug_loc 0x00000169 0x67 spi.o + .debug_loc 0x000001d0 0x26 usart0.o + +.debug_macinfo + *(.debug_macinfo) + +.debug_weaknames + *(.debug_weaknames) + +.debug_funcnames + *(.debug_funcnames) + +.debug_typenames + *(.debug_typenames) + +.debug_varnames + *(.debug_varnames) + +.debug_pubtypes + *(.debug_pubtypes) + +.debug_ranges 0x00000000 0x58 + *(.debug_ranges) + .debug_ranges 0x00000000 0x18 main.o + .debug_ranges 0x00000018 0x18 spi.o + .debug_ranges 0x00000030 0x28 usart0.o + +.debug_macro + *(.debug_macro) +OUTPUT(GccApplication1.elf elf32-avr) +LOAD linker stubs diff --git a/GccApplication1/GccApplication1/Debug/GccApplication1.srec b/GccApplication1/GccApplication1/Debug/GccApplication1.srec new file mode 100644 index 0000000..ffcbefc --- /dev/null +++ b/GccApplication1/GccApplication1/Debug/GccApplication1.srec @@ -0,0 +1,37 @@ +S01700004763634170706C69636174696F6E312E737265635B +S11300000C945A000C9477000C9477000C947700AD +S11300100C9477000C9477000C9477000C94770080 +S11300200C9477000C9477000C9477000C94770070 +S11300300C9477000C9477000C9477000C94770060 +S11300400C9477000C9477000C9477000C94770050 +S11300500C9477000C9477000C9477000C94770040 +S11300600C9477000C9477000C9477000C94770030 +S11300700C9477000C9477000C9477000C94770020 +S11300800C9477000C9477000C9477000C94770010 +S11300900C9477000C9477000C9477000C94770000 +S11300A00C9477000C9477000C9477000C947700F0 +S11300B00C94770011241FBECFEFD8E0DEBFCDBF74 +S11300C011E0A0E0B1E0E8E1F2E002C005900D9299 +S11300D0AC30B107D9F721E0ACE0B1E001C01D922A +S11300E0AC30B207E1F70E948F000C940A010C9423 +S11300F000003C9A44982FEF81EE94E02150804018 +S11301009040E1F700C000003C982FEF81EE94E0AE +S1130110215080409040E1F700C000000895CF9343 +S1130120DF93CDB7DEB72C970FB6F894DEBF0FBEC2 +S1130130CDBF8CE0E0E0F1E0DE01119601900D927C +S11301408A95E1F783E08AB98BB917B818B8699A28 +S11301506A98729888E090E00E94F70078940E9470 +S1130160D4006E012DE0C20ED11C0E947900339B95 +S1130170FCCF719A8FEF93EDE0E381509040E04023 +S1130180E1F700C000008E010F5F1F4FF801F190EE +S11301908F018F2D0E9402018F2D0E94DE000C150D +S11301A01D05A1F77198E1CF6A9A729A6B9A87B18B +S11301B0866087B980E58093AC0008954298809367 +S11301C0AE008091AD00882384F0EDEAF0E0719AEE +S11301D02FEF81EE94E0215080409040E1F700C081 +S11301E0000071988081882394F7429A08951092B0 +S11301F0C5008093C40088E18093C1008EE08093A1 +S1130200C2000895E0ECF0E0908195FFFDCF80936B +S10B0210C6000895F894FFCF25 +S10F0218014E20280100019C4028010137 +S9030000FC diff --git a/GccApplication1/GccApplication1/Debug/Makefile b/GccApplication1/GccApplication1/Debug/Makefile new file mode 100644 index 0000000..0c3119c --- /dev/null +++ b/GccApplication1/GccApplication1/Debug/Makefile @@ -0,0 +1,163 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +SHELL := cmd.exe +RM := rm -rf + +USER_OBJS := + +LIBS := +PROJ := + +O_SRCS := +C_SRCS := +S_SRCS := +S_UPPER_SRCS := +OBJ_SRCS := +ASM_SRCS := +PREPROCESSING_SRCS := +OBJS := +OBJS_AS_ARGS := +C_DEPS := +C_DEPS_AS_ARGS := +EXECUTABLES := +OUTPUT_FILE_PATH := +OUTPUT_FILE_PATH_AS_ARGS := +AVR_APP_PATH :=$$$AVR_APP_PATH$$$ +QUOTE := " +ADDITIONAL_DEPENDENCIES:= +OUTPUT_FILE_DEP:= +LIB_DEP:= +LINKER_SCRIPT_DEP:= + +# Every subdirectory with source files must be described here +SUBDIRS := + + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../delay.c \ +../main.c \ +../spi.c \ +../usart0.c + + +PREPROCESSING_SRCS += + + +ASM_SRCS += + + +OBJS += \ +delay.o \ +main.o \ +spi.o \ +usart0.o + +OBJS_AS_ARGS += \ +delay.o \ +main.o \ +spi.o \ +usart0.o + +C_DEPS += \ +delay.d \ +main.d \ +spi.d \ +usart0.d + +C_DEPS_AS_ARGS += \ +delay.d \ +main.d \ +spi.d \ +usart0.d + +OUTPUT_FILE_PATH +=GccApplication1.elf + +OUTPUT_FILE_PATH_AS_ARGS +=GccApplication1.elf + +ADDITIONAL_DEPENDENCIES:= + +OUTPUT_FILE_DEP:= ./makedep.mk + +LIB_DEP+= + +LINKER_SCRIPT_DEP+= + + +# AVR32/GNU C Compiler +./delay.o: .././delay.c + @echo Building file: $< + @echo Invoking: AVR/GNU C Compiler : 5.4.0 + $(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -x c -funsigned-char -funsigned-bitfields -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include" -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega328pb -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\gcc\dev\atmega328pb" -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -o "$@" "$<" + @echo Finished building: $< + + +./main.o: .././main.c + @echo Building file: $< + @echo Invoking: AVR/GNU C Compiler : 5.4.0 + $(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -x c -funsigned-char -funsigned-bitfields -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include" -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega328pb -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\gcc\dev\atmega328pb" -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -o "$@" "$<" + @echo Finished building: $< + + +./spi.o: .././spi.c + @echo Building file: $< + @echo Invoking: AVR/GNU C Compiler : 5.4.0 + $(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -x c -funsigned-char -funsigned-bitfields -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include" -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega328pb -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\gcc\dev\atmega328pb" -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -o "$@" "$<" + @echo Finished building: $< + + +./usart0.o: .././usart0.c + @echo Building file: $< + @echo Invoking: AVR/GNU C Compiler : 5.4.0 + $(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -x c -funsigned-char -funsigned-bitfields -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include" -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega328pb -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\gcc\dev\atmega328pb" -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -o "$@" "$<" + @echo Finished building: $< + + + + + +# AVR32/GNU Preprocessing Assembler + + + +# AVR32/GNU Assembler + + + + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: $(OUTPUT_FILE_PATH) $(ADDITIONAL_DEPENDENCIES) + +$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP) $(LIB_DEP) $(LINKER_SCRIPT_DEP) + @echo Building target: $@ + @echo Invoking: AVR/GNU Linker : 5.4.0 + $(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="GccApplication1.map" -Wl,--start-group -Wl,-lm -Wl,--end-group -Wl,--gc-sections -mmcu=atmega328pb -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\gcc\dev\atmega328pb" + @echo Finished building target: $@ + "C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures "GccApplication1.elf" "GccApplication1.hex" + "C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "GccApplication1.elf" "GccApplication1.eep" || exit 0 + "C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objdump.exe" -h -S "GccApplication1.elf" > "GccApplication1.lss" + "C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O srec -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures "GccApplication1.elf" "GccApplication1.srec" + "C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-size.exe" "GccApplication1.elf" + + + + + + + +# Other Targets +clean: + -$(RM) $(OBJS_AS_ARGS) $(EXECUTABLES) + -$(RM) $(C_DEPS_AS_ARGS) + rm -rf "GccApplication1.elf" "GccApplication1.a" "GccApplication1.hex" "GccApplication1.lss" "GccApplication1.eep" "GccApplication1.map" "GccApplication1.srec" "GccApplication1.usersignatures" + \ No newline at end of file diff --git a/GccApplication1/GccApplication1/Debug/delay.d b/GccApplication1/GccApplication1/Debug/delay.d new file mode 100644 index 0000000..b0c7ad3 --- /dev/null +++ b/GccApplication1/GccApplication1/Debug/delay.d @@ -0,0 +1,39 @@ +delay.d delay.o: .././delay.c .././delay.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\io.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\sfr_defs.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\inttypes.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\lib\gcc\avr\5.4.0\include\stdint.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\stdint.h \ + C:\Program\ Files\ (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include/avr/iom328pb.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\portpins.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\common.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\version.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\fuse.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\lock.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\cpufunc.h + +.././delay.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\io.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\sfr_defs.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\inttypes.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\lib\gcc\avr\5.4.0\include\stdint.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\stdint.h: + +C:\Program\ Files\ (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include/avr/iom328pb.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\portpins.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\common.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\version.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\fuse.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\lock.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\cpufunc.h: diff --git a/GccApplication1/GccApplication1/Debug/delay.o b/GccApplication1/GccApplication1/Debug/delay.o new file mode 100644 index 0000000000000000000000000000000000000000..9ead6876631d31b96509e3c8a2a468d26c1b851b GIT binary patch literal 5980 zcmb7HTWnlM8J;<3ZLcp`Cw7wFTxHv&s+)FC>@;^M%UPy~p}11gA0KvjWgB_t3kQ64CQ7m}z21Ok*;N6Hly%#oLuku`1$bM)zddmx6ZDZy*PV$_QG42-s(Kp`r{jCF1^$GvkULMDqB-4 z25-pdm98t(SKg40C*IvZ*FV>E#<`xDNX)KDZ5{0F>aLU5hn*gq*s3(btM&`>1dlsBl7cK^Ji0fD0?GP7Nl5F=^$Vjym!i z0BRH&>Y|XOEjyG01pmJ2tsvH8j7-R;-}Eys@3d2(w@pn14u ziENYcrgPg`B#i3osvZtvHF&}pR?UP6-{xMg-5b{lHyjM;APG&)m|>e_;ATsMz%4JI zkkEBQv*;ue>NL%4gG0oK>C!6Y?skI34~X6EYnquUO;Y3xG=06u&C2{N@^dS>0%c=F zWK?-lKqh2sRP`B++Iz#Of;5aOX)=y@#m0*%v&oueNc>agzGf?l9nn>lNil5Ht~ep@ zBsY57jaQ34oJL(OKUG_hnx)`I_`hj866%N(@N?uxktTubjwzO&x5g8hjme2}X{?+c zkB;UG*-EtYaBt5e$+SP7EhH=c)y{Zgrr$))qfWcpCKSN+7sij%Qh_Tl_lk zz;4%co1`lmAA~N{SdXEckXsJ{%mR3{ak4 zI!GGt<*0r>bD$Eeth-0#i+Mk_cmKX2F+AmG197jIELQSk#q3BFxhjkPJ^Q158#Y9r z@YZ=<(b#w~Hd;tma+|w}OR>s<{6uVcatz#fW^ywU`$RN0wl*3YgaOjF83~4WY}7=J zF{;huHXF@n3nLW>VU_XorDCj-RXt@RX+LfA6Y0zWL@rNed}u4VQrVAXi<9FOQ79G1 zqGp^ZuX>ip8nchLXq4^k4wLZeP5Gj4V{(5bTdpKOk@lz3$?e(70lzen?BB7cJK3Mf zBqk;b`AnKqy`A5lMLt9&evsgXD%4$$3$5mef%Vmsrazprm&v@`MSP^veD z?4+;-sePt)Q;&N+-r7|6`t`k!1e+pw;%|ab2}f78M4fM;V(qUZzXLYU18MU-nC8m> zD0n~<5%*Om5ec1g6Op>=A{Q1oB4UdXz#q>RvDxD91Kw)!tE!k_{wCK@8)f16Ar-57Q;Lw-3H$2JYavE+ zaa|3fujQ#;d>XvD#B3DU*CGczS5qTb*dGqYUsO{9xxpv6Ds$DYR$1tojT*UPX^jDL z#qtIG-3$1;L`F+k4{ccQ3z}y=v|(js&2x=yBCOs66tN!KxI5+~rBcuAP3=mhgaQKr z7~0XVfImKwDrd(OK9Vh$G&7LeaTv9{UJRrL1_$>lpd{TJj0i}L(0hjqidQbb<;*hY zN6furbC62z6W2vdy@%#53EsSXXF0&EkL?<-M*kFA8=XMUq0wdp{V*DRN73idjLifv zZJtGc$dYqBJ`hNpheYbvqKB!%SJ5xixDy3>53$~^hluaO59l#8`o0F6ZjGbBJQI|! zLeDu9ABX%?8h?zQ^QZh2G;Rc*()fP#$B1hfFNopG6kX7A+WdxC-y*-$m@z*fhVMzt^RL8ABp3)f)QxJF~vd#{BzY0P*#EWBG| z=55HrTn}S%+?0iR2T;!aRkfipYnyV;N7aVLpVxA3)0ZrKQsXxCs!m`}d{)c3N8AIm zE>$P6c?z;OwVe1z8q=QpLHiE$?`gamy{Z$)iB+8dGar|<4Y8^j$m76&({f^-J;r<* zJ@=BBd*|rAW1g5h$;pGbPP2C?BN1&1a>d#*d&l`jv3IQDDCN3_SCI#1Jl339`(u=2 zT&|I1;+xvQ5Ne-HeC`1;NVth3p#3XS(9EKjQ9_t|C7ed$2E;tqvx5WO&mQQ z!wT;N=3isVcL6Wbn0wT&@$oxe)ce)wtN>0Z@5wsUK#&XJW4(N{ah%)TR+g(Ui_AcdWr`82;Z)$ zd~vjd0TfOT50|rt^caDtP|DoGr_1T$Sk}xVu(^Y%kS}IUR4he!nbP=pmalX*|G;k) z|Kj-l`d^7}LTsZt6ZBcfAB(6XJ%C2+k^%iEyN96*qy0C#ZrCgwSCj>kHq-jIpMb7R{Lf#-QJ zWbD!q*yAp34$c|ZftO)*+(W>|2T=SO?Yt#0@F3)Nykm&B7#9iS0aoLk05(2=;uvh^ z2{akq9C(ANI*1KyvjhfCLuZdWjdS}0C^;_kZSwbRVB-TQUV?&W+mO+H9RfREytS4W z9QSIxw}Fihp!f-#c%K+Dx*tMd$9n_uo`;O{<0pzb*2}Naj1Qpr5DLCo3>nC8svWNd zlj?<%@s?^G>Amp9Sn2d)MsG3EIR4IpZ L^tmcmoBO{3bP<2z literal 0 HcmV?d00001 diff --git a/GccApplication1/GccApplication1/Debug/main.d b/GccApplication1/GccApplication1/Debug/main.d new file mode 100644 index 0000000..a74d29a --- /dev/null +++ b/GccApplication1/GccApplication1/Debug/main.d @@ -0,0 +1,65 @@ +main.d main.o: .././main.c .././main.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\io.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\sfr_defs.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\inttypes.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\lib\gcc\avr\5.4.0\include\stdint.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\stdint.h \ + C:\Program\ Files\ (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include/avr/iom328pb.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\portpins.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\common.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\version.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\fuse.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\lock.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\interrupt.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\stdio.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\lib\gcc\avr\5.4.0\include\stdarg.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\lib\gcc\avr\5.4.0\include\stddef.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\stdlib.h \ + .././usart0.h .././spi.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\util\delay.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\util\delay_basic.h \ + c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\math.h + +.././main.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\io.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\sfr_defs.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\inttypes.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\lib\gcc\avr\5.4.0\include\stdint.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\stdint.h: + +C:\Program\ Files\ (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include/avr/iom328pb.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\portpins.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\common.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\version.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\fuse.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\lock.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\interrupt.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\stdio.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\lib\gcc\avr\5.4.0\include\stdarg.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\lib\gcc\avr\5.4.0\include\stddef.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\stdlib.h: + +.././usart0.h: + +.././spi.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\util\delay.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\util\delay_basic.h: + +c:\program\ files\ (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\math.h: diff --git a/GccApplication1/GccApplication1/Debug/main.o b/GccApplication1/GccApplication1/Debug/main.o new file mode 100644 index 0000000000000000000000000000000000000000..22d84ad8d4c8b50d428e2c7c7684b3a2fb8c13b7 GIT binary patch literal 6832 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 literal 0 HcmV?d00001 diff --git a/GccApplication1/GccApplication1/GccApplication1.componentinfo.xml b/GccApplication1/GccApplication1/GccApplication1.componentinfo.xml new file mode 100644 index 0000000..53cff68 --- /dev/null +++ b/GccApplication1/GccApplication1/GccApplication1.componentinfo.xml @@ -0,0 +1,86 @@ +п»ї + + + + + + Device + Startup + + + Atmel + 2.0.0 + C:/Program Files (x86)\Atmel\Studio\7.0\Packs + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include\ + + include + C + + + include/ + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\include\avr\iom328pb.h + + header + C + ciLFjy803ysEAt1ml/dotQ== + + include/avr/iom328pb.h + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\templates\main.c + template + source + C Exe + rwiL+kQhXb1eoW7Dnm7abg== + + templates/main.c + Main file (.c) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\templates\main.cpp + template + source + C Exe + mkKaE95TOoATsuBGv6jmxg== + + templates/main.cpp + Main file (.cpp) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\2.0.401\gcc\dev\atmega328pb + + libraryPrefix + GCC + + + gcc/dev/atmega328pb + + + + + ATmega_DFP + C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/2.0.401/Atmel.ATmega_DFP.pdsc + 2.0.401 + true + ATmega328PB + + + + Resolved + Fixed + true + + + \ No newline at end of file diff --git a/GccApplication1/GccApplication1/GccApplication1.cproj b/GccApplication1/GccApplication1/GccApplication1.cproj new file mode 100644 index 0000000..6e6d2cf --- /dev/null +++ b/GccApplication1/GccApplication1/GccApplication1.cproj @@ -0,0 +1,177 @@ +п»ї + + + 2.0 + 7.0 + com.Atmel.AVRGCC8.C + dce6c7e3-ee26-4d79-826b-08594b9ad897 + ATmega328PB + none + Executable + C + $(MSBuildProjectName) + .elf + $(MSBuildProjectDirectory)\$(Configuration) + GccApplication1 + GccApplication1 + GccApplication1 + Native + true + false + true + true + 0x20000000 + + true + exception_table + 2 + 0 + 0 + + + + + + + + + + + + + + com.atmel.avrdbg.tool.ispmk2 + 0000B809060C + 0x1E9516 + + + + 0 + + ISP + + com.atmel.avrdbg.tool.stk500 + + + STK500 + + ISP + 125000 + + + + 125000 + + ISP + + com.atmel.avrdbg.tool.ispmk2 + 0000B809060C + AVRISP mkII + + + + + + -mmcu=atmega328pb -B "%24(PackRepoDir)\Atmel\ATmega_DFP\2.0.401\gcc\dev\atmega328pb" + True + True + True + True + False + True + True + + + NDEBUG + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\2.0.401\include\ + + + Optimize for size (-Os) + True + True + True + + + libm + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\2.0.401\include\ + + + + + + + + + -mmcu=atmega328pb -B "%24(PackRepoDir)\Atmel\ATmega_DFP\2.0.401\gcc\dev\atmega328pb" + True + True + True + True + False + True + True + + + DEBUG + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\2.0.401\include\ + + + Optimize (-O1) + True + True + Default (-g2) + True + + + libm + + + + + %24(PackRepoDir)\Atmel\ATmega_DFP\2.0.401\include\ + + + Default (-Wa,-g) + + + + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + + \ No newline at end of file diff --git a/GccApplication1/GccApplication1/delay.c b/GccApplication1/GccApplication1/delay.c new file mode 100644 index 0000000..4ce1c78 --- /dev/null +++ b/GccApplication1/GccApplication1/delay.c @@ -0,0 +1,80 @@ +// delay.c +#include "delay.h" +// неоптимизируемые компилятором функции процессорных задержек +void delay8(uint8_t ticks) +{ + /* + архитектрура AVR8 (2560, 328pb), частота = 16 MHz, период 62.5 ns + испытано на коде c замером осциллографом + PORTA |= (1 << 1); + delay8(val); + PORTA &= ~(1 << 1); + полученная формула задержки (мкс) = 0,191 * ticks + 1,227, если ticks > 0 + 0 ticks = 1,38 мкс + */ + __asm__ volatile ( + "cpc %A0,__zero_reg__ \n\t" \ + "breq L_Exit_%= \n\t" \ + "L_LOOP_%=: \n\t" \ + "subi %A0,1 \n\t" \ + "brne L_LOOP_%= \n\t" \ + "L_Exit_%=: \n\t" \ + : "=w" (ticks) \ + : "0" (ticks) \ + ); \ + return; +} + +void delay16(uint16_t ticks) +{ + /* + архитектрура AVR8 (2560, 328pb), частота = 16 MHz, период 62.5 ns + испытано на коде c замером осциллографом + PORTA |= (1 << 1); + delay16(val); + PORTA &= ~(1 << 1); + полученная формула задержки (мкс) = 0,250 * ticks + 1,294 , если ticks > 0 + 0 ticks = 1,44 мкс + */ + __asm__ volatile ( + "cp %A0,__zero_reg__ \n\t" \ + "cpc %B0,__zero_reg__ \n\t" \ + "breq L_Exit_%= \n\t" \ + "L_LOOP_%=: \n\t" \ + "subi %A0,1 \n\t" \ + "sbci %B0,0 \n\t" \ + "brne L_LOOP_%= \n\t" \ + "L_Exit_%=: \n\t" \ + : "=w" (ticks) \ + : "0" (ticks) \ + ); \ + return; +} + +void init_PUTR() +{ + DDRC |= 1 << PORTC0; + PORTC |= 1 << PORTC0; +} + +void PUTR(uint8_t byte) +{ + #define BIT_TICK 35 // 115200 + uint8_t bit[8]; + for(uint8_t i = 0; i < 8; i++) + bit[i] = (byte >> i) & 0x01; + + // transmittion + PORTC &= ~(1 << PORTC0); + delay8(BIT_TICK); + for(uint8_t i = 0; i < 8; i++) + { + if(bit[i] != 0) + PORTC |= 1 << PORTC0; + else + PORTC &= ~(1 << PORTC0); + delay8(BIT_TICK); + } + PORTC |= 1 << PORTC0; + delay8(BIT_TICK); +} \ No newline at end of file diff --git a/GccApplication1/GccApplication1/delay.h b/GccApplication1/GccApplication1/delay.h new file mode 100644 index 0000000..85dd501 --- /dev/null +++ b/GccApplication1/GccApplication1/delay.h @@ -0,0 +1,14 @@ +// delay.h + +#ifndef DELAY_H_ +#define DELAY_H_ + +#include +#include + +void delay8(uint8_t); +void delay16(uint16_t); +void init_PUTR(); +void PUTR(uint8_t); + +#endif \ No newline at end of file diff --git a/GccApplication1/GccApplication1/main.c b/GccApplication1/GccApplication1/main.c new file mode 100644 index 0000000..2534770 --- /dev/null +++ b/GccApplication1/GccApplication1/main.c @@ -0,0 +1,83 @@ +/* + * GccApplication1.c + * + * Created: 11.10.2023 16:40:59 + * Author : Katya + */ +#include "main.h" + + +int bytes = 0; + +//ISR (USART0_RX_vect) { + //data_to_send[bytes] = UDR0; + //bytes++; + //PORTE = 0; +//} + +int main(void) +{ + uint8_t data_to_send[] = {0x01, 0x4E, 0x20, 0x28, 0x01, 0x00, 0x01, 0x9C, 0x40, 0x28, 0x01, 0x01}; + DDRD = 3; // USART PD0, PD1 + PORTD = 3; + /////////////////////////////// + //STM NRST + DDRC = 0; + PORTC = 0; + /////////////////////////////// + DDRE |= (1 << PORTE1); + DDRE &= ~(1 << PORTE2); + PORTE &= ~(1 << PORTE2); + //PORTE = 2; + + USART_Init(8); // установка скорости 115200: (16 000 000 / (16 * 115 200) ) - 1, U2X = 0 + sei(); + + // -----SPI----- + SPI_MasterInit(); + //_delay_ms(100); + //PORTE |= (1 << PORTE1); + //_delay_ms(100); + //PORTE &= ~(1 << PORTE1); // STATUS выкл + + while (1) + { + //if ((PINC)&(1< +#include +#include +#include +#include "usart0.h" +#include "spi.h" +#include + +void STMReset(); + +#endif /* MAIN_H_ */ \ No newline at end of file diff --git a/GccApplication1/GccApplication1/spi.c b/GccApplication1/GccApplication1/spi.c new file mode 100644 index 0000000..3e654da --- /dev/null +++ b/GccApplication1/GccApplication1/spi.c @@ -0,0 +1,32 @@ +/* + * spi.c + * + * Created: 13.10.2023 11:03:48 + * Author: Katya + */ +#include "spi.h" + +void SPI_MasterInit(void) { + // Настройка пина SS (PB2) как выхода + DDRE |= (1 << PORTE2); + + // Установка SS в высокое состояние (неактивный) + PORTE |= (1 << PORTE2); + /* Set MOSI, SS and SCK output */ + DDRE |= (1 << MOSI); + DDRC |= (1 << SCK) | (1 << SS); + + /* Enable SPI, Master */ + SPCR1 = (1 << SPE1) | (1 << MSTR1); +} + +void SPI_MasterTransmit(uint8_t data) { + PORTC &= ~(1 << PORTC2); // начало передачи - низкий уровень + SPDR1 = data; + while(!(SPSR1 & (1<