From 1757b6c3f3eb2260981862ff7fa72fb7aa4b7165 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Fri, 4 Nov 2022 12:38:38 -0500 Subject: [PATCH] Remove GD32 --- dist.sh | 14 - greenpak/README.md | 8 - greenpak/SCSI_Accelerator_SLG46824.gp6 | 647 ---- greenpak/SCSI_Accelerator_SLG46824.hex | 17 - greenpak/SCSI_Accelerator_SLG46824.png | Bin 30491 -> 0 bytes .../BlueSCSI_platform.cpp | 525 ---- .../BlueSCSI_platform.h | 151 - .../BlueSCSI_v1_0_gpio.h | 119 - .../BlueSCSI_v1_1_gpio.h | 164 - .../bluescsi_gd32f205.ld | 175 -- .../bluescsi_gd32f205_btldr.ld | 182 -- lib/BlueSCSI_platform_GD32F205/bsp.h | 5 - .../gd32_sdio_sdcard.c | 2520 ---------------- .../gd32_sdio_sdcard.h | 271 -- lib/BlueSCSI_platform_GD32F205/greenpak.cpp | 188 -- lib/BlueSCSI_platform_GD32F205/greenpak.h | 13 - lib/BlueSCSI_platform_GD32F205/greenpak_fw.h | 24 - lib/BlueSCSI_platform_GD32F205/scsi2sd_time.h | 14 - lib/BlueSCSI_platform_GD32F205/scsiPhy.cpp | 600 ---- lib/BlueSCSI_platform_GD32F205/scsiPhy.h | 67 - .../scsi_accel_asm.cpp | 152 - .../scsi_accel_asm.h | 8 - .../scsi_accel_dma.cpp | 659 ---- .../scsi_accel_dma.h | 27 - .../scsi_accel_greenpak.cpp | 365 --- .../scsi_accel_greenpak.h | 9 - .../scsi_accel_sync.cpp | 479 --- .../scsi_accel_sync.h | 17 - .../sd_card_sdio.cpp | 310 -- .../sd_card_spi.cpp | 274 -- lib/SdFat_NoArduino/.gitattributes | 22 - lib/SdFat_NoArduino/.gitignore | 215 -- lib/SdFat_NoArduino/.piopm | 1 - lib/SdFat_NoArduino/LICENSE.md | 21 - lib/SdFat_NoArduino/README.md | 110 - lib/SdFat_NoArduino/doc/Doxyfile | 2685 ----------------- lib/SdFat_NoArduino/doc/SdErrorCodes.txt | 50 - lib/SdFat_NoArduino/doc/SdFat.html | 10 - lib/SdFat_NoArduino/doc/ZipMsg/index.html | 4 - lib/SdFat_NoArduino/doc/clean_html.bat | 3 - lib/SdFat_NoArduino/doc/del_html.bat | 3 - lib/SdFat_NoArduino/doc/html.zip | Bin 2261073 -> 0 bytes lib/SdFat_NoArduino/doc/html/index.html | 4 - lib/SdFat_NoArduino/doc/mainpage.h | 289 -- .../examples/AvrAdcLogger/AvrAdcLogger.h | 31 - .../examples/AvrAdcLogger/AvrAdcLogger.ino | 898 ------ .../BackwardCompatibility.ino | 83 - .../examples/BufferedPrint/BufferedPrint.ino | 235 -- .../DirectoryFunctions/DirectoryFunctions.ino | 158 - .../examples/ExFatLogger/ExFatLogger.h | 9 - .../examples/ExFatLogger/ExFatLogger.ino | 595 ---- .../MinimumSizeSdReader.ino | 58 - .../examples/OpenNext/OpenNext.ino | 105 - .../examples/QuickStart/QuickStart.ino | 187 -- .../examples/ReadCsvFile/ReadCsvFile.ino | 156 - .../RtcTimestampTest/RtcTimestampTest.ino | 236 -- .../examples/SdErrorCodes/SdErrorCodes.ino | 19 - .../examples/SdFormatter/SdFormatter.ino | 249 -- .../examples/SdInfo/SdInfo.ino | 265 -- .../examples/SoftwareSpi/SoftwareSpi.ino | 80 - .../TeensyDmaAdcLogger/TeensyDmaAdcLogger.ino | 247 -- .../TeensyRtcTimestamp/TeensyRtcTimestamp.ino | 139 - .../TeensySdioDemo/TeensySdioDemo.ino | 221 -- .../TeensySdioLogger/TeensySdioLogger.ino | 148 - .../UnicodeFilenames/UnicodeFilenames.ino | 98 - .../UserChipSelectFunction.ino | 47 - .../examples/UserSPIDriver/UserSPIDriver.ino | 81 - lib/SdFat_NoArduino/examples/bench/bench.ino | 276 -- .../#attic/AnalogLogger/AnalogLogger.ino | 197 -- .../BaseExtCaseTest/BaseExtCaseTest.ino | 46 - .../#attic/HelloWorld/HelloWorld.ino | 20 - .../#attic/MiniSerial/MiniSerial.ino | 29 - .../PrintBenchmarkSD/PrintBenchmarkSD.ino | 125 - .../examplesV1/#attic/SD_Size/SD_Size.ino | 30 - .../examplesV1/#attic/SdFatSize/SdFatSize.ino | 33 - .../#attic/StreamParseInt/StreamParseInt.ino | 44 - .../examplesV1/#attic/append/append.ino | 77 - .../examplesV1/#attic/average/average.ino | 82 - .../examplesV1/#attic/benchSD/benchSD.ino | 149 - .../examplesV1/#attic/bufstream/bufstream.ino | 39 - .../examplesV1/#attic/cin_cout/cin_cout.ino | 39 - .../examplesV1/#attic/eventlog/eventlog.ino | 62 - .../#attic/fgetsRewrite/fgetsRewrite.ino | 111 - .../examplesV1/#attic/readlog/readlog.ino | 51 - .../examples/examplesV1/#attic/readme.txt | 34 - .../AnalogBinLogger/AnalogBinLogger.h | 39 - .../AnalogBinLogger/AnalogBinLogger.ino | 826 ----- .../DirectoryFunctions/DirectoryFunctions.ino | 129 - .../examplesV1/LongFileName/LongFileName.ino | 102 - .../A long name can be 255 characters.txt | 4 - .../LongFileName/testFiles/LFN,NAME.TXT | 1 - .../LongFileName/testFiles/MIXCASE.txt | 5 - .../LongFileName/testFiles/Not_8_3.txt | 2 - .../LongFileName/testFiles/OK%83.TXT | 1 - .../LongFileName/testFiles/STD_8_3.TXT | 1 - .../LongFileName/testFiles/With Blank.txt | 2 - .../LongFileName/testFiles/With.Two dots.txt | 2 - .../LongFileName/testFiles/lower.txt | 5 - .../LongFileName/testFiles/mixed.TXT | 5 - .../LowLatencyLogger/LowLatencyLogger.ino | 655 ---- .../LowLatencyLogger/UserFunctions.cpp | 41 - .../examplesV1/LowLatencyLogger/UserTypes.h | 15 - .../LowLatencyLogger.ino | 655 ---- .../LowLatencyLoggerADXL345.ino | 1 - .../LowLatencyLoggerADXL345/UserFunctions.cpp | 70 - .../LowLatencyLoggerADXL345/UserTypes.h | 17 - .../LowLatencyLoggerADXL345/readme.txt | 1 - .../LowLatencyLogger.ino | 655 ---- .../LowLatencyLoggerMPU6050.ino | 2 - .../LowLatencyLoggerMPU6050/UserFunctions.cpp | 51 - .../LowLatencyLoggerMPU6050/UserTypes.h | 18 - .../examples/examplesV1/OpenNext/OpenNext.ino | 60 - .../PrintBenchmark/PrintBenchmark.ino | 152 - .../examplesV1/QuickStart/QuickStart.ino | 161 - .../examples/examplesV1/RawWrite/RawWrite.ino | 180 -- .../examples/examplesV1/ReadCsv/ReadCsv.ino | 212 -- .../examplesV1/ReadCsvArray/ReadCsvArray.ino | 139 - .../ReadCsvStream/ReadCsvStream.ino | 121 - .../examplesV1/ReadWrite/ReadWrite.ino | 81 - .../examplesV1/STM32Test/STM32Test.ino | 175 -- .../examplesV1/SdFormatter/SdFormatter.ino | 552 ---- .../examples/examplesV1/SdInfo/SdInfo.ino | 248 -- .../examplesV1/SoftwareSpi/SoftwareSpi.ino | 59 - .../examplesV1/StdioBench/StdioBench.ino | 215 -- .../TeensySdioDemo/TeensySdioDemo.ino | 169 -- .../examplesV1/Timestamp/Timestamp.ino | 162 - .../examples/examplesV1/TwoCards/TwoCards.ino | 170 -- .../VolumeFreeSpace/VolumeFreeSpace.ino | 82 - .../examples/examplesV1/bench/bench.ino | 222 -- .../examplesV1/dataLogger/dataLogger.ino | 150 - .../examples/examplesV1/fgets/fgets.ino | 88 - .../examplesV1/formatting/formatting.ino | 73 - .../examples/examplesV1/getline/getline.ino | 84 - .../examples/examplesV1/rename/rename.ino | 106 - .../examples/examplesV1/wipe/wipe.ino | 43 - .../examples/rename/rename.ino | 146 - lib/SdFat_NoArduino/library.properties | 11 - lib/SdFat_NoArduino/src/BufferedPrint.h | 269 -- .../src/DigitalIO/DigitalPin.h | 381 --- lib/SdFat_NoArduino/src/DigitalIO/SoftSPI.h | 161 - .../boards/AvrDevelopersGpioPinMap.h | 37 - .../src/DigitalIO/boards/BobuinoGpioPinMap.h | 37 - .../src/DigitalIO/boards/GpioPinMap.h | 64 - .../src/DigitalIO/boards/LeonardoGpioPinMap.h | 35 - .../src/DigitalIO/boards/MegaGpioPinMap.h | 75 - .../boards/SleepingBeautyGpioPinMap.h | 37 - .../DigitalIO/boards/Standard1284GpioPinMap.h | 37 - .../src/DigitalIO/boards/Teensy2GpioPinMap.h | 30 - .../DigitalIO/boards/Teensy2ppGpioPinMap.h | 51 - .../src/DigitalIO/boards/UnoGpioPinMap.h | 25 - lib/SdFat_NoArduino/src/DigitalIO/readme.txt | 3 - .../src/ExFatLib/ExFatConfig.h | 33 - lib/SdFat_NoArduino/src/ExFatLib/ExFatDbg.cpp | 621 ---- .../src/ExFatLib/ExFatFile.cpp | 694 ----- lib/SdFat_NoArduino/src/ExFatLib/ExFatFile.h | 839 ----- .../src/ExFatLib/ExFatFilePrint.cpp | 228 -- .../src/ExFatLib/ExFatFileWrite.cpp | 756 ----- .../src/ExFatLib/ExFatFormatter.cpp | 363 --- .../src/ExFatLib/ExFatFormatter.h | 55 - lib/SdFat_NoArduino/src/ExFatLib/ExFatLib.h | 29 - .../src/ExFatLib/ExFatName.cpp | 194 -- .../src/ExFatLib/ExFatPartition.cpp | 330 -- .../src/ExFatLib/ExFatPartition.h | 230 -- .../src/ExFatLib/ExFatVolume.cpp | 45 - .../src/ExFatLib/ExFatVolume.h | 336 --- lib/SdFat_NoArduino/src/FatLib/FatDbg.cpp | 268 -- lib/SdFat_NoArduino/src/FatLib/FatFile.cpp | 1477 --------- lib/SdFat_NoArduino/src/FatLib/FatFile.h | 1062 ------- lib/SdFat_NoArduino/src/FatLib/FatFileLFN.cpp | 594 ---- .../src/FatLib/FatFilePrint.cpp | 109 - lib/SdFat_NoArduino/src/FatLib/FatFileSFN.cpp | 311 -- .../src/FatLib/FatFormatter.cpp | 280 -- lib/SdFat_NoArduino/src/FatLib/FatFormatter.h | 66 - lib/SdFat_NoArduino/src/FatLib/FatLib.h | 29 - lib/SdFat_NoArduino/src/FatLib/FatName.cpp | 356 --- .../src/FatLib/FatPartition.cpp | 494 --- lib/SdFat_NoArduino/src/FatLib/FatPartition.h | 297 -- lib/SdFat_NoArduino/src/FatLib/FatVolume.cpp | 45 - lib/SdFat_NoArduino/src/FatLib/FatVolume.h | 338 --- lib/SdFat_NoArduino/src/FreeStack.cpp | 80 - lib/SdFat_NoArduino/src/FreeStack.h | 94 - lib/SdFat_NoArduino/src/FsLib/FsFile.cpp | 206 -- lib/SdFat_NoArduino/src/FsLib/FsFile.h | 809 ----- lib/SdFat_NoArduino/src/FsLib/FsFormatter.h | 57 - lib/SdFat_NoArduino/src/FsLib/FsLib.h | 34 - lib/SdFat_NoArduino/src/FsLib/FsNew.cpp | 29 - lib/SdFat_NoArduino/src/FsLib/FsNew.h | 46 - lib/SdFat_NoArduino/src/FsLib/FsVolume.cpp | 66 - lib/SdFat_NoArduino/src/FsLib/FsVolume.h | 390 --- lib/SdFat_NoArduino/src/MinimumSerial.cpp | 71 - lib/SdFat_NoArduino/src/MinimumSerial.h | 67 - lib/SdFat_NoArduino/src/RingBuf.h | 366 --- lib/SdFat_NoArduino/src/SdCard/CPPLINT.cfg | 1 - lib/SdFat_NoArduino/src/SdCard/SdCard.h | 82 - lib/SdFat_NoArduino/src/SdCard/SdCardInfo.cpp | 45 - lib/SdFat_NoArduino/src/SdCard/SdCardInfo.h | 490 --- .../src/SdCard/SdCardInterface.h | 116 - lib/SdFat_NoArduino/src/SdCard/SdSpiCard.cpp | 729 ----- lib/SdFat_NoArduino/src/SdCard/SdSpiCard.h | 419 --- lib/SdFat_NoArduino/src/SdCard/SdioCard.h | 254 -- lib/SdFat_NoArduino/src/SdCard/SdioTeensy.cpp | 1088 ------- lib/SdFat_NoArduino/src/SdCard/SdioTeensy.h | 277 -- lib/SdFat_NoArduino/src/SdFat.h | 514 ---- lib/SdFat_NoArduino/src/SdFatConfig.h | 434 --- .../src/SpiDriver/SdSpiArduinoDriver.h | 96 - .../src/SpiDriver/SdSpiArtemis.cpp | 79 - lib/SdFat_NoArduino/src/SpiDriver/SdSpiAvr.h | 124 - .../src/SpiDriver/SdSpiBareUnoDriver.h | 200 -- .../src/SpiDriver/SdSpiBaseClass.h | 78 - .../src/SpiDriver/SdSpiChipSelect.cpp | 48 - .../src/SpiDriver/SdSpiDriver.h | 155 - .../src/SpiDriver/SdSpiDue.cpp | 216 -- .../src/SpiDriver/SdSpiESP.cpp | 96 - .../src/SpiDriver/SdSpiLibDriver.h | 90 - .../src/SpiDriver/SdSpiParticle.cpp | 78 - .../src/SpiDriver/SdSpiSTM32.cpp | 82 - .../src/SpiDriver/SdSpiSTM32Core.cpp | 75 - .../src/SpiDriver/SdSpiSoftDriver.h | 121 - .../src/SpiDriver/SdSpiTeensy3.cpp | 90 - lib/SdFat_NoArduino/src/common/ArduinoFiles.h | 159 - lib/SdFat_NoArduino/src/common/CPPLINT.cfg | 3 - .../src/common/CompileDateTime.h | 74 - lib/SdFat_NoArduino/src/common/DebugMacros.h | 74 - lib/SdFat_NoArduino/src/common/FmtNumber.cpp | 515 ---- lib/SdFat_NoArduino/src/common/FmtNumber.h | 43 - .../src/common/FsApiConstants.h | 85 - .../src/common/FsBlockDevice.h | 33 - .../src/common/FsBlockDeviceInterface.h | 95 - lib/SdFat_NoArduino/src/common/FsCache.cpp | 75 - lib/SdFat_NoArduino/src/common/FsCache.h | 184 -- lib/SdFat_NoArduino/src/common/FsDateTime.cpp | 175 -- lib/SdFat_NoArduino/src/common/FsDateTime.h | 193 -- lib/SdFat_NoArduino/src/common/FsName.cpp | 54 - lib/SdFat_NoArduino/src/common/FsName.h | 66 - lib/SdFat_NoArduino/src/common/FsStructs.cpp | 64 - lib/SdFat_NoArduino/src/common/FsStructs.h | 408 --- lib/SdFat_NoArduino/src/common/FsUtf.cpp | 115 - lib/SdFat_NoArduino/src/common/FsUtf.h | 109 - lib/SdFat_NoArduino/src/common/PrintBasic.cpp | 91 - lib/SdFat_NoArduino/src/common/PrintBasic.h | 170 -- lib/SdFat_NoArduino/src/common/SysCall.h | 62 - lib/SdFat_NoArduino/src/common/upcase.cpp | 228 -- lib/SdFat_NoArduino/src/common/upcase.h | 30 - .../src/iostream/ArduinoStream.h | 150 - .../src/iostream/StdioStream.cpp | 451 --- .../src/iostream/StdioStream.h | 663 ---- .../src/iostream/StreamBaseClass.cpp | 160 - lib/SdFat_NoArduino/src/iostream/bufstream.h | 171 -- lib/SdFat_NoArduino/src/iostream/fstream.h | 330 -- lib/SdFat_NoArduino/src/iostream/ios.h | 448 --- lib/SdFat_NoArduino/src/iostream/iostream.h | 158 - lib/SdFat_NoArduino/src/iostream/istream.cpp | 395 --- lib/SdFat_NoArduino/src/iostream/istream.h | 384 --- lib/SdFat_NoArduino/src/iostream/ostream.cpp | 153 - lib/SdFat_NoArduino/src/iostream/ostream.h | 348 --- lib/SdFat_NoArduino/src/sdios.h | 34 - platformio.ini | 41 - utils/convert_greenpak_hex.sh | 14 - utils/run_gdb_v1_0.sh | 17 - utils/run_gdb_v1_1.sh | 17 - 260 files changed, 51528 deletions(-) delete mode 100644 dist.sh delete mode 100644 greenpak/README.md delete mode 100644 greenpak/SCSI_Accelerator_SLG46824.gp6 delete mode 100644 greenpak/SCSI_Accelerator_SLG46824.hex delete mode 100644 greenpak/SCSI_Accelerator_SLG46824.png delete mode 100644 lib/BlueSCSI_platform_GD32F205/BlueSCSI_platform.cpp delete mode 100644 lib/BlueSCSI_platform_GD32F205/BlueSCSI_platform.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/BlueSCSI_v1_0_gpio.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/BlueSCSI_v1_1_gpio.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/bluescsi_gd32f205.ld delete mode 100644 lib/BlueSCSI_platform_GD32F205/bluescsi_gd32f205_btldr.ld delete mode 100644 lib/BlueSCSI_platform_GD32F205/bsp.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/gd32_sdio_sdcard.c delete mode 100644 lib/BlueSCSI_platform_GD32F205/gd32_sdio_sdcard.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/greenpak.cpp delete mode 100644 lib/BlueSCSI_platform_GD32F205/greenpak.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/greenpak_fw.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/scsi2sd_time.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/scsiPhy.cpp delete mode 100644 lib/BlueSCSI_platform_GD32F205/scsiPhy.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/scsi_accel_asm.cpp delete mode 100644 lib/BlueSCSI_platform_GD32F205/scsi_accel_asm.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/scsi_accel_dma.cpp delete mode 100644 lib/BlueSCSI_platform_GD32F205/scsi_accel_dma.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/scsi_accel_greenpak.cpp delete mode 100644 lib/BlueSCSI_platform_GD32F205/scsi_accel_greenpak.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/scsi_accel_sync.cpp delete mode 100644 lib/BlueSCSI_platform_GD32F205/scsi_accel_sync.h delete mode 100644 lib/BlueSCSI_platform_GD32F205/sd_card_sdio.cpp delete mode 100644 lib/BlueSCSI_platform_GD32F205/sd_card_spi.cpp delete mode 100644 lib/SdFat_NoArduino/.gitattributes delete mode 100644 lib/SdFat_NoArduino/.gitignore delete mode 100644 lib/SdFat_NoArduino/.piopm delete mode 100644 lib/SdFat_NoArduino/LICENSE.md delete mode 100644 lib/SdFat_NoArduino/README.md delete mode 100644 lib/SdFat_NoArduino/doc/Doxyfile delete mode 100644 lib/SdFat_NoArduino/doc/SdErrorCodes.txt delete mode 100644 lib/SdFat_NoArduino/doc/SdFat.html delete mode 100644 lib/SdFat_NoArduino/doc/ZipMsg/index.html delete mode 100644 lib/SdFat_NoArduino/doc/clean_html.bat delete mode 100644 lib/SdFat_NoArduino/doc/del_html.bat delete mode 100644 lib/SdFat_NoArduino/doc/html.zip delete mode 100644 lib/SdFat_NoArduino/doc/html/index.html delete mode 100644 lib/SdFat_NoArduino/doc/mainpage.h delete mode 100644 lib/SdFat_NoArduino/examples/AvrAdcLogger/AvrAdcLogger.h delete mode 100644 lib/SdFat_NoArduino/examples/AvrAdcLogger/AvrAdcLogger.ino delete mode 100644 lib/SdFat_NoArduino/examples/BackwardCompatibility/BackwardCompatibility.ino delete mode 100644 lib/SdFat_NoArduino/examples/BufferedPrint/BufferedPrint.ino delete mode 100644 lib/SdFat_NoArduino/examples/DirectoryFunctions/DirectoryFunctions.ino delete mode 100644 lib/SdFat_NoArduino/examples/ExFatLogger/ExFatLogger.h delete mode 100644 lib/SdFat_NoArduino/examples/ExFatLogger/ExFatLogger.ino delete mode 100644 lib/SdFat_NoArduino/examples/MinimumSizeSdReader/MinimumSizeSdReader.ino delete mode 100644 lib/SdFat_NoArduino/examples/OpenNext/OpenNext.ino delete mode 100644 lib/SdFat_NoArduino/examples/QuickStart/QuickStart.ino delete mode 100644 lib/SdFat_NoArduino/examples/ReadCsvFile/ReadCsvFile.ino delete mode 100644 lib/SdFat_NoArduino/examples/RtcTimestampTest/RtcTimestampTest.ino delete mode 100644 lib/SdFat_NoArduino/examples/SdErrorCodes/SdErrorCodes.ino delete mode 100644 lib/SdFat_NoArduino/examples/SdFormatter/SdFormatter.ino delete mode 100644 lib/SdFat_NoArduino/examples/SdInfo/SdInfo.ino delete mode 100644 lib/SdFat_NoArduino/examples/SoftwareSpi/SoftwareSpi.ino delete mode 100644 lib/SdFat_NoArduino/examples/TeensyDmaAdcLogger/TeensyDmaAdcLogger.ino delete mode 100644 lib/SdFat_NoArduino/examples/TeensyRtcTimestamp/TeensyRtcTimestamp.ino delete mode 100644 lib/SdFat_NoArduino/examples/TeensySdioDemo/TeensySdioDemo.ino delete mode 100644 lib/SdFat_NoArduino/examples/TeensySdioLogger/TeensySdioLogger.ino delete mode 100644 lib/SdFat_NoArduino/examples/UnicodeFilenames/UnicodeFilenames.ino delete mode 100644 lib/SdFat_NoArduino/examples/UserChipSelectFunction/UserChipSelectFunction.ino delete mode 100644 lib/SdFat_NoArduino/examples/UserSPIDriver/UserSPIDriver.ino delete mode 100644 lib/SdFat_NoArduino/examples/bench/bench.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/AnalogLogger/AnalogLogger.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/BaseExtCaseTest/BaseExtCaseTest.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/HelloWorld/HelloWorld.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/MiniSerial/MiniSerial.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/PrintBenchmarkSD/PrintBenchmarkSD.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/SD_Size/SD_Size.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/SdFatSize/SdFatSize.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/StreamParseInt/StreamParseInt.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/append/append.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/average/average.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/benchSD/benchSD.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/bufstream/bufstream.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/cin_cout/cin_cout.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/eventlog/eventlog.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/fgetsRewrite/fgetsRewrite.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/readlog/readlog.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/#attic/readme.txt delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/AnalogBinLogger/AnalogBinLogger.h delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/AnalogBinLogger/AnalogBinLogger.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/DirectoryFunctions/DirectoryFunctions.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LongFileName/LongFileName.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LongFileName/testFiles/A long name can be 255 characters.txt delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LongFileName/testFiles/LFN,NAME.TXT delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LongFileName/testFiles/MIXCASE.txt delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LongFileName/testFiles/Not_8_3.txt delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LongFileName/testFiles/OK%83.TXT delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LongFileName/testFiles/STD_8_3.TXT delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LongFileName/testFiles/With Blank.txt delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LongFileName/testFiles/With.Two dots.txt delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LongFileName/testFiles/lower.txt delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LongFileName/testFiles/mixed.TXT delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLogger/LowLatencyLogger.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLogger/UserFunctions.cpp delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLogger/UserTypes.h delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLoggerADXL345/LowLatencyLogger.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLoggerADXL345/LowLatencyLoggerADXL345.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLoggerADXL345/UserFunctions.cpp delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLoggerADXL345/UserTypes.h delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLoggerADXL345/readme.txt delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLoggerMPU6050/LowLatencyLogger.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLoggerMPU6050/LowLatencyLoggerMPU6050.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLoggerMPU6050/UserFunctions.cpp delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/LowLatencyLoggerMPU6050/UserTypes.h delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/OpenNext/OpenNext.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/PrintBenchmark/PrintBenchmark.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/QuickStart/QuickStart.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/RawWrite/RawWrite.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/ReadCsv/ReadCsv.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/ReadCsvArray/ReadCsvArray.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/ReadCsvStream/ReadCsvStream.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/ReadWrite/ReadWrite.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/STM32Test/STM32Test.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/SdFormatter/SdFormatter.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/SdInfo/SdInfo.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/SoftwareSpi/SoftwareSpi.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/StdioBench/StdioBench.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/TeensySdioDemo/TeensySdioDemo.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/Timestamp/Timestamp.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/TwoCards/TwoCards.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/VolumeFreeSpace/VolumeFreeSpace.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/bench/bench.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/dataLogger/dataLogger.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/fgets/fgets.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/formatting/formatting.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/getline/getline.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/rename/rename.ino delete mode 100644 lib/SdFat_NoArduino/examples/examplesV1/wipe/wipe.ino delete mode 100644 lib/SdFat_NoArduino/examples/rename/rename.ino delete mode 100644 lib/SdFat_NoArduino/library.properties delete mode 100644 lib/SdFat_NoArduino/src/BufferedPrint.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/DigitalPin.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/SoftSPI.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/boards/AvrDevelopersGpioPinMap.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/boards/BobuinoGpioPinMap.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/boards/GpioPinMap.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/boards/LeonardoGpioPinMap.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/boards/MegaGpioPinMap.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/boards/SleepingBeautyGpioPinMap.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/boards/Standard1284GpioPinMap.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/boards/Teensy2GpioPinMap.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/boards/Teensy2ppGpioPinMap.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/boards/UnoGpioPinMap.h delete mode 100644 lib/SdFat_NoArduino/src/DigitalIO/readme.txt delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatConfig.h delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatDbg.cpp delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatFile.cpp delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatFile.h delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatFilePrint.cpp delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatFileWrite.cpp delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatFormatter.cpp delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatFormatter.h delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatLib.h delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatName.cpp delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatPartition.cpp delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatPartition.h delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatVolume.cpp delete mode 100644 lib/SdFat_NoArduino/src/ExFatLib/ExFatVolume.h delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatDbg.cpp delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatFile.cpp delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatFile.h delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatFileLFN.cpp delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatFilePrint.cpp delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatFileSFN.cpp delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatFormatter.cpp delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatFormatter.h delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatLib.h delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatName.cpp delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatPartition.cpp delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatPartition.h delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatVolume.cpp delete mode 100644 lib/SdFat_NoArduino/src/FatLib/FatVolume.h delete mode 100644 lib/SdFat_NoArduino/src/FreeStack.cpp delete mode 100644 lib/SdFat_NoArduino/src/FreeStack.h delete mode 100644 lib/SdFat_NoArduino/src/FsLib/FsFile.cpp delete mode 100644 lib/SdFat_NoArduino/src/FsLib/FsFile.h delete mode 100644 lib/SdFat_NoArduino/src/FsLib/FsFormatter.h delete mode 100644 lib/SdFat_NoArduino/src/FsLib/FsLib.h delete mode 100644 lib/SdFat_NoArduino/src/FsLib/FsNew.cpp delete mode 100644 lib/SdFat_NoArduino/src/FsLib/FsNew.h delete mode 100644 lib/SdFat_NoArduino/src/FsLib/FsVolume.cpp delete mode 100644 lib/SdFat_NoArduino/src/FsLib/FsVolume.h delete mode 100644 lib/SdFat_NoArduino/src/MinimumSerial.cpp delete mode 100644 lib/SdFat_NoArduino/src/MinimumSerial.h delete mode 100644 lib/SdFat_NoArduino/src/RingBuf.h delete mode 100644 lib/SdFat_NoArduino/src/SdCard/CPPLINT.cfg delete mode 100644 lib/SdFat_NoArduino/src/SdCard/SdCard.h delete mode 100644 lib/SdFat_NoArduino/src/SdCard/SdCardInfo.cpp delete mode 100644 lib/SdFat_NoArduino/src/SdCard/SdCardInfo.h delete mode 100644 lib/SdFat_NoArduino/src/SdCard/SdCardInterface.h delete mode 100644 lib/SdFat_NoArduino/src/SdCard/SdSpiCard.cpp delete mode 100644 lib/SdFat_NoArduino/src/SdCard/SdSpiCard.h delete mode 100644 lib/SdFat_NoArduino/src/SdCard/SdioCard.h delete mode 100644 lib/SdFat_NoArduino/src/SdCard/SdioTeensy.cpp delete mode 100644 lib/SdFat_NoArduino/src/SdCard/SdioTeensy.h delete mode 100644 lib/SdFat_NoArduino/src/SdFat.h delete mode 100644 lib/SdFat_NoArduino/src/SdFatConfig.h delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiArduinoDriver.h delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiArtemis.cpp delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiAvr.h delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiBareUnoDriver.h delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiBaseClass.h delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiChipSelect.cpp delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiDriver.h delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiDue.cpp delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiESP.cpp delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiLibDriver.h delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiParticle.cpp delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiSTM32.cpp delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiSTM32Core.cpp delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiSoftDriver.h delete mode 100644 lib/SdFat_NoArduino/src/SpiDriver/SdSpiTeensy3.cpp delete mode 100644 lib/SdFat_NoArduino/src/common/ArduinoFiles.h delete mode 100644 lib/SdFat_NoArduino/src/common/CPPLINT.cfg delete mode 100644 lib/SdFat_NoArduino/src/common/CompileDateTime.h delete mode 100644 lib/SdFat_NoArduino/src/common/DebugMacros.h delete mode 100644 lib/SdFat_NoArduino/src/common/FmtNumber.cpp delete mode 100644 lib/SdFat_NoArduino/src/common/FmtNumber.h delete mode 100644 lib/SdFat_NoArduino/src/common/FsApiConstants.h delete mode 100644 lib/SdFat_NoArduino/src/common/FsBlockDevice.h delete mode 100644 lib/SdFat_NoArduino/src/common/FsBlockDeviceInterface.h delete mode 100644 lib/SdFat_NoArduino/src/common/FsCache.cpp delete mode 100644 lib/SdFat_NoArduino/src/common/FsCache.h delete mode 100644 lib/SdFat_NoArduino/src/common/FsDateTime.cpp delete mode 100644 lib/SdFat_NoArduino/src/common/FsDateTime.h delete mode 100644 lib/SdFat_NoArduino/src/common/FsName.cpp delete mode 100644 lib/SdFat_NoArduino/src/common/FsName.h delete mode 100644 lib/SdFat_NoArduino/src/common/FsStructs.cpp delete mode 100644 lib/SdFat_NoArduino/src/common/FsStructs.h delete mode 100644 lib/SdFat_NoArduino/src/common/FsUtf.cpp delete mode 100644 lib/SdFat_NoArduino/src/common/FsUtf.h delete mode 100644 lib/SdFat_NoArduino/src/common/PrintBasic.cpp delete mode 100644 lib/SdFat_NoArduino/src/common/PrintBasic.h delete mode 100644 lib/SdFat_NoArduino/src/common/SysCall.h delete mode 100644 lib/SdFat_NoArduino/src/common/upcase.cpp delete mode 100644 lib/SdFat_NoArduino/src/common/upcase.h delete mode 100644 lib/SdFat_NoArduino/src/iostream/ArduinoStream.h delete mode 100644 lib/SdFat_NoArduino/src/iostream/StdioStream.cpp delete mode 100644 lib/SdFat_NoArduino/src/iostream/StdioStream.h delete mode 100644 lib/SdFat_NoArduino/src/iostream/StreamBaseClass.cpp delete mode 100644 lib/SdFat_NoArduino/src/iostream/bufstream.h delete mode 100644 lib/SdFat_NoArduino/src/iostream/fstream.h delete mode 100644 lib/SdFat_NoArduino/src/iostream/ios.h delete mode 100644 lib/SdFat_NoArduino/src/iostream/iostream.h delete mode 100644 lib/SdFat_NoArduino/src/iostream/istream.cpp delete mode 100644 lib/SdFat_NoArduino/src/iostream/istream.h delete mode 100644 lib/SdFat_NoArduino/src/iostream/ostream.cpp delete mode 100644 lib/SdFat_NoArduino/src/iostream/ostream.h delete mode 100644 lib/SdFat_NoArduino/src/sdios.h delete mode 100755 utils/convert_greenpak_hex.sh delete mode 100755 utils/run_gdb_v1_0.sh delete mode 100755 utils/run_gdb_v1_1.sh diff --git a/dist.sh b/dist.sh deleted file mode 100644 index 9780f363..00000000 --- a/dist.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -x - -DATE=$(date +%Y%m%d) -VERSION="v1.1-$DATE" -mkdir -p dist -rm -f dist/*.bin - -for f in $(ls .pio/build/*/firmware.bin); do - NAME="BlueSCSI-$VERSION-$(echo $f | cut -d\/ -f3).bin" - cp $f dist/$NAME -done diff --git a/greenpak/README.md b/greenpak/README.md deleted file mode 100644 index 080da36b..00000000 --- a/greenpak/README.md +++ /dev/null @@ -1,8 +0,0 @@ -GreenPAK design files -===================== - -This folder contains design files for `SLG46824` programmable logic device. -It is optionally used on BlueSCSI V1.1 to speed up access to SCSI bus. This applies to asynchronous transfers only - -What this logic does is implement the `REQ` / `ACK` handshake in hardware. -The CPU only has to write new data to the GPIO, and the external logic will toggle `REQ` signal quickly. diff --git a/greenpak/SCSI_Accelerator_SLG46824.gp6 b/greenpak/SCSI_Accelerator_SLG46824.gp6 deleted file mode 100644 index c6ffe5f9..00000000 --- a/greenpak/SCSI_Accelerator_SLG46824.gp6 +++ /dev/null @@ -1,647 +0,0 @@ - - - - - C4 9 0 0 0 0 0 0 38 C2 0 0 0 0 0 0 0 0 0 0 0 0 D0 8 13 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 E7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 30 70 0 30 20 30 30 0 0 30 30 30 0 30 30 30 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 22 30 C 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 40 0 0 0 0 0 0 D7 14 20 0 1 0 0 0 2 1 0 0 2 0 1 0 0 2 1 0 0 2 0 1 0 0 2 1 0 0 2 0 1 0 0 2 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 A5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (-702.00,682.00); (-695.00,682.00) - - - (-702.00,712.00); (-695.00,712.00) - - - (-189.00,520.00); (432.00,520.00); (432.00,360.00) - - - (-189.00,520.00); (45.00,520.00); (45.00,216.00) - - - (-186.00,294.00); (-13.00,294.00); (-13.00,182.00); (-2.00,182.00) - - - (-188.00,403.00); (105.00,403.00); (105.00,341.00); (120.00,341.00) - - - (-186.00,294.00); (105.00,294.00); (105.00,331.00); (120.00,331.00) - - - (89.00,186.00); (114.00,186.00); (114.00,321.00); (120.00,321.00) - - - (191.00,326.00); (388.00,326.00) - - - (-187.00,213.00); (-127.00,213.00); (-127.00,311.00); (120.00,311.00) - - - (-30.00,192.00); (-2.00,192.00) - - - (191.00,326.00); (213.00,326.00); (213.00,113.00); (-123.00,113.00); (-123.00,184.00); (-107.00,184.00) - - - (-187.00,213.00); (-126.00,213.00); (-126.00,200.00); (-107.00,200.00) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/greenpak/SCSI_Accelerator_SLG46824.hex b/greenpak/SCSI_Accelerator_SLG46824.hex deleted file mode 100644 index d45392a5..00000000 --- a/greenpak/SCSI_Accelerator_SLG46824.hex +++ /dev/null @@ -1,17 +0,0 @@ -:10000000C40900000000000038C200000000000029 -:10001000000000000000D0081301000000000000F4 -:1000200000000000000000000000000000000000D0 -:1000300000000000000000000000000000000000C0 -:100040000000E700000000000000000000000000C9 -:1000500000000000000000000000000000000000A0 -:100060000030700030203030000030303000303050 -:100070003030000000000000000000000000000020 -:1000800000000000001422300C00000000000000FE -:10009000060000000000000000004000000000001A -:1000A00000D714200001000000020100000200013E -:1000B0000000020100000200010000020100000235 -:1000C0000001000002000100000001010100000029 -:1000D0000000000000000000000000000000000020 -:1000E0000000000000000000000000000000000010 -:1000F000000000000000000000000000000000A55B -:00000001FF \ No newline at end of file diff --git a/greenpak/SCSI_Accelerator_SLG46824.png b/greenpak/SCSI_Accelerator_SLG46824.png deleted file mode 100644 index 13606db73674b79d5987c83b30c17c0c2dbcc8a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30491 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 diff --git a/lib/BlueSCSI_platform_GD32F205/BlueSCSI_platform.cpp b/lib/BlueSCSI_platform_GD32F205/BlueSCSI_platform.cpp deleted file mode 100644 index 4e004f1e..00000000 --- a/lib/BlueSCSI_platform_GD32F205/BlueSCSI_platform.cpp +++ /dev/null @@ -1,525 +0,0 @@ -#include "BlueSCSI_platform.h" -#include "gd32f20x_sdio.h" -#include "gd32f20x_fmc.h" -#include "BlueSCSI_log.h" -#include "BlueSCSI_config.h" -#include "greenpak.h" -#include -#include -#include - -extern "C" { - -const char *g_bluescsiplatform_name = PLATFORM_NAME; -static bool g_enable_apple_quirks = false; - -/*************************/ -/* Timing functions */ -/*************************/ - -static volatile uint32_t g_millisecond_counter; -static volatile uint32_t g_watchdog_timeout; -static uint32_t g_ns_to_cycles; // Q0.32 fixed point format - -static void watchdog_handler(uint32_t *sp); - -unsigned long millis() -{ - return g_millisecond_counter; -} - -void delay(unsigned long ms) -{ - uint32_t start = g_millisecond_counter; - while ((uint32_t)(g_millisecond_counter - start) < ms); -} - -void delay_ns(unsigned long ns) -{ - uint32_t CNT_start = DWT->CYCCNT; - if (ns <= 100) return; // Approximate call overhead - ns -= 100; - - uint32_t cycles = ((uint64_t)ns * g_ns_to_cycles) >> 32; - while ((uint32_t)(DWT->CYCCNT - CNT_start) < cycles); -} - -void SysTick_Handler_inner(uint32_t *sp) -{ - g_millisecond_counter++; - - if (g_watchdog_timeout > 0) - { - g_watchdog_timeout--; - - const uint32_t busreset_time = WATCHDOG_CRASH_TIMEOUT - WATCHDOG_BUS_RESET_TIMEOUT; - if (g_watchdog_timeout <= busreset_time) - { - if (!scsiDev.resetFlag) - { - bluelog("WATCHDOG TIMEOUT at PC ", sp[6], " LR ", sp[5], " attempting bus reset"); - scsiDev.resetFlag = 1; - } - - if (g_watchdog_timeout == 0) - { - watchdog_handler(sp); - } - } - } -} - -__attribute__((interrupt, naked)) -void SysTick_Handler(void) -{ - // Take note of stack pointer so that we can print debug - // info in watchdog handler. - asm("mrs r0, msp\n" - "b SysTick_Handler_inner": : : "r0"); -} - -// This function is called by scsiPhy.cpp. -// It resets the systick counter to give 1 millisecond of uninterrupted transfer time. -// The total number of skips is kept track of to keep the correct time on average. -void SysTick_Handle_PreEmptively() -{ - static int skipped_clocks = 0; - - __disable_irq(); - uint32_t loadval = SysTick->LOAD; - skipped_clocks += loadval - SysTick->VAL; - SysTick->VAL = 0; - - if (skipped_clocks > loadval) - { - // We have skipped enough ticks that it is time to fake a call - // to SysTick interrupt handler. - skipped_clocks -= loadval; - uint32_t stack_frame[8] = {0}; - stack_frame[6] = (uint32_t)__builtin_return_address(0); - SysTick_Handler_inner(stack_frame); - } - __enable_irq(); -} - -/***************/ -/* GPIO init */ -/***************/ - -// Initialize SPI and GPIO configuration -// Clock has already been initialized by system_gd32f20x.c -void bluescsiplatform_init() -{ - SystemCoreClockUpdate(); - - // Enable SysTick to drive millis() - g_millisecond_counter = 0; - SysTick_Config(SystemCoreClock / 1000U); - NVIC_SetPriority(SysTick_IRQn, 0x00U); - - // Enable DWT counter to drive delay_ns() - g_ns_to_cycles = ((uint64_t)SystemCoreClock << 32) / 1000000000; - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; - - // Enable debug output on SWO pin - DBG_CTL |= DBG_CTL_TRACE_IOEN; - if (TPI->ACPR == 0) - { - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - TPI->ACPR = SystemCoreClock / 2000000 - 1; // 2 Mbps baudrate for SWO - // TPI->ACPR = SystemCoreClock / 30000000 - 1; // 30 Mbps baudrate for SWO - TPI->SPPR = 2; - TPI->FFCR = 0x100; // TPIU packet framing disabled - // DWT->CTRL |= (1 << DWT_CTRL_EXCTRCENA_Pos); - // DWT->CTRL |= (1 << DWT_CTRL_CYCTAP_Pos) - // | (15 << DWT_CTRL_POSTPRESET_Pos) - // | (1 << DWT_CTRL_PCSAMPLENA_Pos) - // | (3 << DWT_CTRL_SYNCTAP_Pos) - // | (1 << DWT_CTRL_CYCCNTENA_Pos); - ITM->LAR = 0xC5ACCE55; - ITM->TCR = (1 << ITM_TCR_DWTENA_Pos) - | (1 << ITM_TCR_SYNCENA_Pos) - | (1 << ITM_TCR_ITMENA_Pos); - ITM->TER = 0xFFFFFFFF; // Enable all stimulus ports - } - - // Enable needed clocks for GPIO - rcu_periph_clock_enable(RCU_AF); - rcu_periph_clock_enable(RCU_GPIOA); - rcu_periph_clock_enable(RCU_GPIOB); - rcu_periph_clock_enable(RCU_GPIOC); - rcu_periph_clock_enable(RCU_GPIOD); - rcu_periph_clock_enable(RCU_GPIOE); - - // Switch to SWD debug port (disable JTAG) to release PB4 as GPIO - gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE); - - // SCSI pins. - // Initialize open drain outputs to high. - SCSI_RELEASE_OUTPUTS(); - gpio_init(SCSI_OUT_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_DATA_MASK | SCSI_OUT_REQ); - gpio_init(SCSI_OUT_IO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_IO_PIN); - gpio_init(SCSI_OUT_CD_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_CD_PIN); - gpio_init(SCSI_OUT_SEL_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_SEL_PIN); - gpio_init(SCSI_OUT_MSG_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_MSG_PIN); - gpio_init(SCSI_OUT_RST_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_RST_PIN); - gpio_init(SCSI_OUT_BSY_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_BSY_PIN); - - gpio_init(SCSI_IN_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_IN_MASK); - gpio_init(SCSI_ATN_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_ATN_PIN); - gpio_init(SCSI_BSY_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_BSY_PIN); - gpio_init(SCSI_SEL_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_SEL_PIN); - gpio_init(SCSI_ACK_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_ACK_PIN); - gpio_init(SCSI_RST_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_RST_PIN); - - // Terminator enable - gpio_bit_set(SCSI_TERM_EN_PORT, SCSI_TERM_EN_PIN); - gpio_init(SCSI_TERM_EN_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, SCSI_TERM_EN_PIN); - -#ifndef SD_USE_SDIO - // SD card pins using SPI - gpio_init(SD_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SD_CS_PIN); - gpio_init(SD_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SD_CLK_PIN); - gpio_init(SD_PORT, GPIO_MODE_IPU, 0, SD_MISO_PIN); - gpio_init(SD_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SD_MOSI_PIN); -#else - // SD card pins using SDIO - gpio_init(SD_SDIO_DATA_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SD_SDIO_D0 | SD_SDIO_D1 | SD_SDIO_D2 | SD_SDIO_D3); - gpio_init(SD_SDIO_CLK_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SD_SDIO_CLK); - gpio_init(SD_SDIO_CMD_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SD_SDIO_CMD); -#endif - - // DIP switches - gpio_init(DIP_PORT, GPIO_MODE_IPD, 0, DIPSW1_PIN | DIPSW2_PIN | DIPSW3_PIN); - - // LED pins - gpio_bit_set(LED_PORT, LED_PINS); - gpio_init(LED_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, LED_PINS); - - // SWO trace pin on PB3 - gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3); -} - -void bluescsiplatform_late_init() -{ - if (gpio_input_bit_get(DIP_PORT, DIPSW3_PIN)) - { - bluelog("DIPSW3 is ON: Enabling SCSI termination"); - gpio_bit_reset(SCSI_TERM_EN_PORT, SCSI_TERM_EN_PIN); - } - else - { - bluelog("DIPSW3 is OFF: SCSI termination disabled"); - } - - if (gpio_input_bit_get(DIP_PORT, DIPSW2_PIN)) - { - bluelog("DIPSW2 is ON: enabling debug messages"); - g_bluelog_debug = true; - } - else - { - g_bluelog_debug = false; - } - - if (gpio_input_bit_get(DIP_PORT, DIPSW1_PIN)) - { - bluelog("DIPSW1 is ON: enabling Apple quirks by default"); - g_enable_apple_quirks = true; - } - - greenpak_load_firmware(); -} - -/*****************************************/ -/* Crash handlers */ -/*****************************************/ - -extern SdFs SD; - -// Writes log data to the PB3 SWO pin -void bluescsiplatform_log(const char *s) -{ - while (*s) - { - // Write to SWO pin - while (ITM->PORT[0].u32 == 0); - ITM->PORT[0].u8 = *s++; - } -} - -void bluescsiplatform_emergency_log_save() -{ - bluescsiplatform_set_sd_callback(NULL, NULL); - - SD.begin(SD_CONFIG_CRASH); - FsFile crashfile = SD.open(CRASHFILE, O_WRONLY | O_CREAT | O_TRUNC); - - if (!crashfile.isOpen()) - { - // Try to reinitialize - int max_retry = 10; - while (max_retry-- > 0 && !SD.begin(SD_CONFIG_CRASH)); - - crashfile = SD.open(CRASHFILE, O_WRONLY | O_CREAT | O_TRUNC); - } - - uint32_t startpos = 0; - crashfile.write(bluelog_get_buffer(&startpos)); - crashfile.write(bluelog_get_buffer(&startpos)); - crashfile.flush(); - crashfile.close(); -} - -extern uint32_t _estack; - -__attribute__((noinline)) -void show_hardfault(uint32_t *sp) -{ - uint32_t pc = sp[6]; - uint32_t lr = sp[5]; - uint32_t cfsr = SCB->CFSR; - - bluelog("--------------"); - bluelog("CRASH!"); - bluelog("Platform: ", g_bluescsiplatform_name); - bluelog("FW Version: ", g_bluelog_firmwareversion); - bluelog("CFSR: ", cfsr); - bluelog("SP: ", (uint32_t)sp); - bluelog("PC: ", pc); - bluelog("LR: ", lr); - bluelog("R0: ", sp[0]); - bluelog("R1: ", sp[1]); - bluelog("R2: ", sp[2]); - bluelog("R3: ", sp[3]); - - uint32_t *p = (uint32_t*)((uint32_t)sp & ~3); - for (int i = 0; i < 8; i++) - { - if (p == &_estack) break; // End of stack - - bluelog("STACK ", (uint32_t)p, ": ", p[0], " ", p[1], " ", p[2], " ", p[3]); - p += 4; - } - - bluescsiplatform_emergency_log_save(); - - while (1) - { - // Flash the crash address on the LED - // Short pulse means 0, long pulse means 1 - int base_delay = 1000; - for (int i = 31; i >= 0; i--) - { - LED_OFF(); - for (int j = 0; j < base_delay; j++) delay_ns(100000); - - int delay = (pc & (1 << i)) ? (3 * base_delay) : base_delay; - LED_ON(); - for (int j = 0; j < delay; j++) delay_ns(100000); - LED_OFF(); - } - - for (int j = 0; j < base_delay * 10; j++) delay_ns(100000); - } -} - -__attribute__((naked, interrupt)) -void HardFault_Handler(void) -{ - // Copies stack pointer into first argument - asm("mrs r0, msp\n" - "b show_hardfault": : : "r0"); -} - -__attribute__((naked, interrupt)) -void MemManage_Handler(void) -{ - asm("mrs r0, msp\n" - "b show_hardfault": : : "r0"); -} - -__attribute__((naked, interrupt)) -void BusFault_Handler(void) -{ - asm("mrs r0, msp\n" - "b show_hardfault": : : "r0"); -} - -__attribute__((naked, interrupt)) -void UsageFault_Handler(void) -{ - asm("mrs r0, msp\n" - "b show_hardfault": : : "r0"); -} - -void __assert_func(const char *file, int line, const char *func, const char *expr) -{ - uint32_t dummy = 0; - - bluelog("--------------"); - bluelog("ASSERT FAILED!"); - bluelog("Platform: ", g_bluescsiplatform_name); - bluelog("FW Version: ", g_bluelog_firmwareversion); - bluelog("Assert failed: ", file , ":", line, " in ", func, ":", expr); - - uint32_t *p = (uint32_t*)((uint32_t)&dummy & ~3); - for (int i = 0; i < 8; i++) - { - if (p == &_estack) break; // End of stack - - bluelog("STACK ", (uint32_t)p, ": ", p[0], " ", p[1], " ", p[2], " ", p[3]); - p += 4; - } - - bluescsiplatform_emergency_log_save(); - - while(1) - { - LED_OFF(); - for (int j = 0; j < 1000; j++) delay_ns(100000); - LED_ON(); - for (int j = 0; j < 1000; j++) delay_ns(100000); - } -} - -} /* extern "C" */ - -static void watchdog_handler(uint32_t *sp) -{ - bluelog("-------------- WATCHDOG TIMEOUT"); - show_hardfault(sp); -} - -void bluescsiplatform_reset_watchdog() -{ - // This uses a software watchdog based on systick timer interrupt. - // It gives us opportunity to collect better debug info than the - // full hardware reset that would be caused by hardware watchdog. - g_watchdog_timeout = WATCHDOG_CRASH_TIMEOUT; -} - -/***********************/ -/* Flash reprogramming */ -/***********************/ - -bool bluescsiplatform_rewrite_flash_page(uint32_t offset, uint8_t buffer[BLUESCSIPLATFORM_FLASH_PAGE_SIZE]) -{ - if (offset == 0) - { - if (buffer[3] != 0x20 || buffer[7] != 0x08) - { - bluelog("Invalid firmware file, starts with: ", bytearray(buffer, 16)); - return false; - } - } - - bluedbg("Writing flash at offset ", offset, " data ", bytearray(buffer, 4)); - assert(offset % BLUESCSIPLATFORM_FLASH_PAGE_SIZE == 0); - assert(offset >= BLUESCSIPLATFORM_BOOTLOADER_SIZE); - - fmc_unlock(); - fmc_bank0_unlock(); - - fmc_state_enum status; - status = fmc_page_erase(FLASH_BASE + offset); - if (status != FMC_READY) - { - bluelog("Erase failed: ", (int)status); - return false; - } - - uint32_t *buf32 = (uint32_t*)buffer; - uint32_t num_words = BLUESCSIPLATFORM_FLASH_PAGE_SIZE / 4; - for (int i = 0; i < num_words; i++) - { - status = fmc_word_program(FLASH_BASE + offset + i * 4, buf32[i]); - if (status != FMC_READY) - { - bluelog("Flash write failed: ", (int)status); - return false; - } - } - - fmc_lock(); - - for (int i = 0; i < num_words; i++) - { - uint32_t expected = buf32[i]; - uint32_t actual = *(volatile uint32_t*)(FLASH_BASE + offset + i * 4); - if (actual != expected) - { - bluelog("Flash verify failed at offset ", offset + i * 4, " got ", actual, " expected ", expected); - return false; - } - } - return true; -} - -void bluescsiplatform_boot_to_main_firmware() -{ - uint32_t *mainprogram_start = (uint32_t*)(0x08000000 + BLUESCSIPLATFORM_BOOTLOADER_SIZE); - SCB->VTOR = (uint32_t)mainprogram_start; - - __asm__( - "msr msp, %0\n\t" - "bx %1" : : "r" (mainprogram_start[0]), - "r" (mainprogram_start[1]) : "memory"); -} - -/**************************************/ -/* SCSI configuration based on DIPSW1 */ -/**************************************/ - -void bluescsiplatform_config_hook(S2S_TargetCfg *config) -{ - // Enable Apple quirks by dip switch - if (g_enable_apple_quirks) - { - if (config->quirks == S2S_CFG_QUIRKS_NONE) - { - config->quirks = S2S_CFG_QUIRKS_APPLE; - } - } -} - -/**********************************************/ -/* Mapping from data bytes to GPIO BOP values */ -/**********************************************/ - -#define PARITY(n) ((1 ^ (n) ^ ((n)>>1) ^ ((n)>>2) ^ ((n)>>3) ^ ((n)>>4) ^ ((n)>>5) ^ ((n)>>6) ^ ((n)>>7)) & 1) -#define X(n) (\ - ((n & 0x01) ? (SCSI_OUT_DB0 << 16) : SCSI_OUT_DB0) | \ - ((n & 0x02) ? (SCSI_OUT_DB1 << 16) : SCSI_OUT_DB1) | \ - ((n & 0x04) ? (SCSI_OUT_DB2 << 16) : SCSI_OUT_DB2) | \ - ((n & 0x08) ? (SCSI_OUT_DB3 << 16) : SCSI_OUT_DB3) | \ - ((n & 0x10) ? (SCSI_OUT_DB4 << 16) : SCSI_OUT_DB4) | \ - ((n & 0x20) ? (SCSI_OUT_DB5 << 16) : SCSI_OUT_DB5) | \ - ((n & 0x40) ? (SCSI_OUT_DB6 << 16) : SCSI_OUT_DB6) | \ - ((n & 0x80) ? (SCSI_OUT_DB7 << 16) : SCSI_OUT_DB7) | \ - (PARITY(n) ? (SCSI_OUT_DBP << 16) : SCSI_OUT_DBP) | \ - (SCSI_OUT_REQ) \ -) - -const uint32_t g_scsi_out_byte_to_bop[256] = -{ - X(0x00), X(0x01), X(0x02), X(0x03), X(0x04), X(0x05), X(0x06), X(0x07), X(0x08), X(0x09), X(0x0a), X(0x0b), X(0x0c), X(0x0d), X(0x0e), X(0x0f), - X(0x10), X(0x11), X(0x12), X(0x13), X(0x14), X(0x15), X(0x16), X(0x17), X(0x18), X(0x19), X(0x1a), X(0x1b), X(0x1c), X(0x1d), X(0x1e), X(0x1f), - X(0x20), X(0x21), X(0x22), X(0x23), X(0x24), X(0x25), X(0x26), X(0x27), X(0x28), X(0x29), X(0x2a), X(0x2b), X(0x2c), X(0x2d), X(0x2e), X(0x2f), - X(0x30), X(0x31), X(0x32), X(0x33), X(0x34), X(0x35), X(0x36), X(0x37), X(0x38), X(0x39), X(0x3a), X(0x3b), X(0x3c), X(0x3d), X(0x3e), X(0x3f), - X(0x40), X(0x41), X(0x42), X(0x43), X(0x44), X(0x45), X(0x46), X(0x47), X(0x48), X(0x49), X(0x4a), X(0x4b), X(0x4c), X(0x4d), X(0x4e), X(0x4f), - X(0x50), X(0x51), X(0x52), X(0x53), X(0x54), X(0x55), X(0x56), X(0x57), X(0x58), X(0x59), X(0x5a), X(0x5b), X(0x5c), X(0x5d), X(0x5e), X(0x5f), - X(0x60), X(0x61), X(0x62), X(0x63), X(0x64), X(0x65), X(0x66), X(0x67), X(0x68), X(0x69), X(0x6a), X(0x6b), X(0x6c), X(0x6d), X(0x6e), X(0x6f), - X(0x70), X(0x71), X(0x72), X(0x73), X(0x74), X(0x75), X(0x76), X(0x77), X(0x78), X(0x79), X(0x7a), X(0x7b), X(0x7c), X(0x7d), X(0x7e), X(0x7f), - X(0x80), X(0x81), X(0x82), X(0x83), X(0x84), X(0x85), X(0x86), X(0x87), X(0x88), X(0x89), X(0x8a), X(0x8b), X(0x8c), X(0x8d), X(0x8e), X(0x8f), - X(0x90), X(0x91), X(0x92), X(0x93), X(0x94), X(0x95), X(0x96), X(0x97), X(0x98), X(0x99), X(0x9a), X(0x9b), X(0x9c), X(0x9d), X(0x9e), X(0x9f), - X(0xa0), X(0xa1), X(0xa2), X(0xa3), X(0xa4), X(0xa5), X(0xa6), X(0xa7), X(0xa8), X(0xa9), X(0xaa), X(0xab), X(0xac), X(0xad), X(0xae), X(0xaf), - X(0xb0), X(0xb1), X(0xb2), X(0xb3), X(0xb4), X(0xb5), X(0xb6), X(0xb7), X(0xb8), X(0xb9), X(0xba), X(0xbb), X(0xbc), X(0xbd), X(0xbe), X(0xbf), - X(0xc0), X(0xc1), X(0xc2), X(0xc3), X(0xc4), X(0xc5), X(0xc6), X(0xc7), X(0xc8), X(0xc9), X(0xca), X(0xcb), X(0xcc), X(0xcd), X(0xce), X(0xcf), - X(0xd0), X(0xd1), X(0xd2), X(0xd3), X(0xd4), X(0xd5), X(0xd6), X(0xd7), X(0xd8), X(0xd9), X(0xda), X(0xdb), X(0xdc), X(0xdd), X(0xde), X(0xdf), - X(0xe0), X(0xe1), X(0xe2), X(0xe3), X(0xe4), X(0xe5), X(0xe6), X(0xe7), X(0xe8), X(0xe9), X(0xea), X(0xeb), X(0xec), X(0xed), X(0xee), X(0xef), - X(0xf0), X(0xf1), X(0xf2), X(0xf3), X(0xf4), X(0xf5), X(0xf6), X(0xf7), X(0xf8), X(0xf9), X(0xfa), X(0xfb), X(0xfc), X(0xfd), X(0xfe), X(0xff) -}; - -#undef X diff --git a/lib/BlueSCSI_platform_GD32F205/BlueSCSI_platform.h b/lib/BlueSCSI_platform_GD32F205/BlueSCSI_platform.h deleted file mode 100644 index 28118348..00000000 --- a/lib/BlueSCSI_platform_GD32F205/BlueSCSI_platform.h +++ /dev/null @@ -1,151 +0,0 @@ -// Platform-specific definitions for BlueSCSI. -// Can be customized for different microcontrollers, this file is for GD32F205VCT6. - -#pragma once - -#include -#include -#include -#include "BlueSCSI_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const char *g_bluescsiplatform_name; - -#if defined(BlueSCSI_V1_0) -# define PLATFORM_NAME "BlueSCSI v1.0" -# define PLATFORM_REVISION "1.0" -# define PLATFORM_MAX_SCSI_SPEED S2S_CFG_SPEED_ASYNC_50 -# include "BlueSCSI_v1_0_gpio.h" -#elif defined(BlueSCSI_V1_1) -# define PLATFORM_NAME "BlueSCSI v1.1" -# define PLATFORM_REVISION "1.1" -# define PLATFORM_MAX_SCSI_SPEED S2S_CFG_SPEED_SYNC_10 -# define PLATFORM_OPTIMAL_MIN_SD_WRITE_SIZE 4096 -# define PLATFORM_OPTIMAL_MAX_SD_WRITE_SIZE 65536 -# define PLATFORM_OPTIMAL_LAST_SD_WRITE_SIZE 8192 -# include "BlueSCSI_v1_1_gpio.h" -#endif - -// Debug logging functions -void bluescsiplatform_log(const char *s); - -// Minimal millis() implementation as GD32F205 does not -// have an Arduino core yet. -unsigned long millis(void); -void delay(unsigned long ms); - -// Precise nanosecond delays -// Works in interrupt context also, max delay 500 000 ns, min delay about 500 ns -void delay_ns(unsigned long ns); - -static inline void delay_us(unsigned long us) -{ - if (us > 0) - { - delay_ns(us * 1000); - } -} - -// Approximate fast delay -static inline void delay_100ns() -{ - asm volatile ("nop \n nop \n nop \n nop \n nop"); -} - -// Initialize SPI and GPIO configuration -void bluescsiplatform_init(); - -// Initialization for main application, not used for bootloader -void bluescsiplatform_late_init(); - -// Setup soft watchdog -void bluescsiplatform_reset_watchdog(); - -// Reinitialize SD card connection and save log from interrupt context. -// This can be used in crash handlers. -void bluescsiplatform_emergency_log_save(); - -// Set callback that will be called during data transfer to/from SD card. -// This can be used to implement simultaneous transfer to SCSI bus. -typedef void (*sd_callback_t)(uint32_t bytes_complete); -void bluescsiplatform_set_sd_callback(sd_callback_t func, const uint8_t *buffer); - -// This function is called by scsiPhy.cpp. -// It resets the systick counter to give 1 millisecond of uninterrupted transfer time. -// The total number of skips is kept track of to keep the correct time on average. -void SysTick_Handle_PreEmptively(); - -// Reprogram firmware in main program area. -#define BLUESCSIPLATFORM_BOOTLOADER_SIZE 32768 -#define BLUESCSIPLATFORM_FLASH_TOTAL_SIZE (256 * 1024) -#define BLUESCSIPLATFORM_FLASH_PAGE_SIZE 2048 -bool bluescsiplatform_rewrite_flash_page(uint32_t offset, uint8_t buffer[BLUESCSIPLATFORM_FLASH_PAGE_SIZE]); -void bluescsiplatform_boot_to_main_firmware(); - -// Configuration customizations based on DIP switch settings -// When DIPSW1 is on, Apple quirks are enabled by default. -void bluescsiplatform_config_hook(S2S_TargetCfg *config); -#define BLUESCSIPLATFORM_CONFIG_HOOK(cfg) bluescsiplatform_config_hook(cfg) - -// Write a single SCSI pin. -// Example use: SCSI_OUT(ATN, 1) sets SCSI_ATN to low (active) state. -#define SCSI_OUT(pin, state) \ - GPIO_BOP(SCSI_OUT_ ## pin ## _PORT) = (SCSI_OUT_ ## pin ## _PIN) << (state ? 16 : 0) - -// Read a single SCSI pin. -// Example use: SCSI_IN(ATN), returns 1 for active low state. -#define SCSI_IN(pin) \ - ((GPIO_ISTAT(SCSI_ ## pin ## _PORT) & (SCSI_ ## pin ## _PIN)) ? 0 : 1) - -// Write SCSI data bus, also sets REQ to inactive. -extern const uint32_t g_scsi_out_byte_to_bop[256]; -#define SCSI_OUT_DATA(data) \ - GPIO_BOP(SCSI_OUT_PORT) = g_scsi_out_byte_to_bop[(uint8_t)(data)] - -// Release SCSI data bus and REQ signal -#define SCSI_RELEASE_DATA_REQ() \ - GPIO_BOP(SCSI_OUT_PORT) = SCSI_OUT_DATA_MASK | SCSI_OUT_REQ - -// Release all SCSI outputs -#define SCSI_RELEASE_OUTPUTS() \ - GPIO_BOP(SCSI_OUT_PORT) = SCSI_OUT_DATA_MASK | SCSI_OUT_REQ, \ - GPIO_BOP(SCSI_OUT_IO_PORT) = SCSI_OUT_IO_PIN, \ - GPIO_BOP(SCSI_OUT_CD_PORT) = SCSI_OUT_CD_PIN, \ - GPIO_BOP(SCSI_OUT_SEL_PORT) = SCSI_OUT_SEL_PIN, \ - GPIO_BOP(SCSI_OUT_MSG_PORT) = SCSI_OUT_MSG_PIN, \ - GPIO_BOP(SCSI_OUT_RST_PORT) = SCSI_OUT_RST_PIN, \ - GPIO_BOP(SCSI_OUT_BSY_PORT) = SCSI_OUT_BSY_PIN - -// Read SCSI data bus -#define SCSI_IN_DATA(data) \ - (((~GPIO_ISTAT(SCSI_IN_PORT)) & SCSI_IN_MASK) >> SCSI_IN_SHIFT) - -#ifdef __cplusplus -} - -// SD card driver for SdFat -#ifndef SD_USE_SDIO -// SPI interface, BlueSCSI v1.0 -class SdSpiConfig; -extern SdSpiConfig g_sd_spi_config; -#define SD_CONFIG g_sd_spi_config -#define SD_CONFIG_CRASH g_sd_spi_config - -#else -// SDIO interface, BlueSCSI v1.1 -class SdioConfig; -extern SdioConfig g_sd_sdio_config; -extern SdioConfig g_sd_sdio_config_crash; -#define SD_CONFIG g_sd_sdio_config -#define SD_CONFIG_CRASH g_sd_sdio_config_crash - -#endif - -// Check if a DMA request for SD card read has completed. -// This is used to optimize the timing of data transfers on SCSI bus. -bool check_sd_read_done(); - -#endif diff --git a/lib/BlueSCSI_platform_GD32F205/BlueSCSI_v1_0_gpio.h b/lib/BlueSCSI_platform_GD32F205/BlueSCSI_v1_0_gpio.h deleted file mode 100644 index b0886de0..00000000 --- a/lib/BlueSCSI_platform_GD32F205/BlueSCSI_v1_0_gpio.h +++ /dev/null @@ -1,119 +0,0 @@ -// GPIO definitions for BlueSCSI v1.0 - -#pragma once - -// SCSI data output port. -// The output data is written using BSRR mechanism, so all data pins must be on same GPIO port. -// The output pins are open-drain in hardware, using separate buffer chips for driving. -#define SCSI_OUT_PORT GPIOD -#define SCSI_OUT_DB7 GPIO_PIN_0 -#define SCSI_OUT_DB6 GPIO_PIN_1 -#define SCSI_OUT_DB5 GPIO_PIN_2 -#define SCSI_OUT_DB4 GPIO_PIN_3 -#define SCSI_OUT_DB3 GPIO_PIN_4 -#define SCSI_OUT_DB2 GPIO_PIN_5 -#define SCSI_OUT_DB1 GPIO_PIN_6 -#define SCSI_OUT_DB0 GPIO_PIN_7 -#define SCSI_OUT_DBP GPIO_PIN_15 -#define SCSI_OUT_REQ GPIO_PIN_9 -#define SCSI_OUT_DATA_MASK (SCSI_OUT_DB0 | SCSI_OUT_DB1 | SCSI_OUT_DB2 | SCSI_OUT_DB3 | SCSI_OUT_DB4 | SCSI_OUT_DB5 | SCSI_OUT_DB6 | SCSI_OUT_DB7 | SCSI_OUT_DBP) -#define SCSI_OUT_REQ_IDX 9 - -// SCSI input data port -#define SCSI_IN_PORT GPIOE -#define SCSI_IN_DB7 GPIO_PIN_15 -#define SCSI_IN_DB6 GPIO_PIN_14 -#define SCSI_IN_DB5 GPIO_PIN_13 -#define SCSI_IN_DB4 GPIO_PIN_12 -#define SCSI_IN_DB3 GPIO_PIN_11 -#define SCSI_IN_DB2 GPIO_PIN_10 -#define SCSI_IN_DB1 GPIO_PIN_9 -#define SCSI_IN_DB0 GPIO_PIN_8 -#define SCSI_IN_DBP GPIO_PIN_7 -#define SCSI_IN_MASK (SCSI_IN_DB7|SCSI_IN_DB6|SCSI_IN_DB5|SCSI_IN_DB4|SCSI_IN_DB3|SCSI_IN_DB2|SCSI_IN_DB1|SCSI_IN_DB0|SCSI_IN_DBP) -#define SCSI_IN_SHIFT 8 - -// SCSI output status lines -#define SCSI_OUT_IO_PORT GPIOD -#define SCSI_OUT_IO_PIN GPIO_PIN_8 -#define SCSI_OUT_CD_PORT GPIOD -#define SCSI_OUT_CD_PIN GPIO_PIN_10 -#define SCSI_OUT_SEL_PORT GPIOD -#define SCSI_OUT_SEL_PIN GPIO_PIN_11 -#define SCSI_OUT_MSG_PORT GPIOD -#define SCSI_OUT_MSG_PIN GPIO_PIN_12 -#define SCSI_OUT_RST_PORT GPIOD -#define SCSI_OUT_RST_PIN GPIO_PIN_13 -#define SCSI_OUT_BSY_PORT GPIOD -#define SCSI_OUT_BSY_PIN GPIO_PIN_14 -#define SCSI_OUT_REQ_PORT SCSI_OUT_PORT -#define SCSI_OUT_REQ_PIN SCSI_OUT_REQ - -// SCSI input status signals -#define SCSI_ACK_PORT GPIOB -#define SCSI_ACK_PIN GPIO_PIN_12 -#define SCSI_IN_ACK_IDX 12 - -// The SCSI_ATN pin was PB0 in prototype 2022a, but was moved to PC6 for 5V-tolerance -#ifdef BlueSCSI_2022A_REVISION -#define SCSI_ATN_PORT GPIOB -#define SCSI_ATN_PIN GPIO_PIN_0 -#else -#define SCSI_ATN_PORT GPIOC -#define SCSI_ATN_PIN GPIO_PIN_6 -#endif - -// SEL pin uses EXTI interrupt -#define SCSI_SEL_PORT GPIOB -#define SCSI_SEL_PIN GPIO_PIN_11 -#define SCSI_SEL_EXTI EXTI_11 -#define SCSI_SEL_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOB -#define SCSI_SEL_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_11 -#define SCSI_SEL_IRQ EXTI10_15_IRQHandler -#define SCSI_SEL_IRQn EXTI10_15_IRQn - -// BSY pin uses EXTI interrupt -#define SCSI_BSY_PORT GPIOB -#define SCSI_BSY_PIN GPIO_PIN_10 -#define SCSI_BSY_EXTI EXTI_10 -#define SCSI_BSY_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOB -#define SCSI_BSY_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_10 -#define SCSI_BSY_IRQ EXTI10_15_IRQHandler -#define SCSI_BSY_IRQn EXTI10_15_IRQn - -// RST pin uses EXTI interrupt -#define SCSI_RST_PORT GPIOB -#define SCSI_RST_PIN GPIO_PIN_13 -#define SCSI_RST_EXTI EXTI_13 -#define SCSI_RST_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOB -#define SCSI_RST_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_13 -#define SCSI_RST_IRQ EXTI10_15_IRQHandler -#define SCSI_RST_IRQn EXTI10_15_IRQn - -// Terminator enable/disable config, active low -#define SCSI_TERM_EN_PORT GPIOC -#define SCSI_TERM_EN_PIN GPIO_PIN_8 - -// SD card pins -#define SD_PORT GPIOA -#define SD_CS_PIN GPIO_PIN_4 -#define SD_CLK_PIN GPIO_PIN_5 -#define SD_MISO_PIN GPIO_PIN_6 -#define SD_MOSI_PIN GPIO_PIN_7 -#define SD_SPI SPI0 -#define SD_SPI_RX_DMA_CHANNEL DMA_CH1 -#define SD_SPI_TX_DMA_CHANNEL DMA_CH2 - -// DIP switches -#define DIP_PORT GPIOB -#define DIPSW1_PIN GPIO_PIN_4 -#define DIPSW2_PIN GPIO_PIN_5 -#define DIPSW3_PIN GPIO_PIN_6 - -// Status LED pins -#define LED_PORT GPIOC -#define LED_I_PIN GPIO_PIN_4 -#define LED_E_PIN GPIO_PIN_5 -#define LED_PINS (LED_I_PIN | LED_E_PIN) -#define LED_ON() gpio_bit_reset(LED_PORT, LED_PINS) -#define LED_OFF() gpio_bit_set(LED_PORT, LED_PINS) diff --git a/lib/BlueSCSI_platform_GD32F205/BlueSCSI_v1_1_gpio.h b/lib/BlueSCSI_platform_GD32F205/BlueSCSI_v1_1_gpio.h deleted file mode 100644 index 684f61cf..00000000 --- a/lib/BlueSCSI_platform_GD32F205/BlueSCSI_v1_1_gpio.h +++ /dev/null @@ -1,164 +0,0 @@ -// GPIO definitions for BlueSCSI v1.1 - -#pragma once - -// SCSI data output port. -// The output data is written using BSRR mechanism, so all data pins must be on same GPIO port. -// The output pins are open-drain in hardware, using separate buffer chips for driving. -#define SCSI_OUT_PORT GPIOD -#define SCSI_OUT_DB7 GPIO_PIN_9 -#define SCSI_OUT_DB6 GPIO_PIN_10 -#define SCSI_OUT_DB5 GPIO_PIN_11 -#define SCSI_OUT_DB4 GPIO_PIN_12 -#define SCSI_OUT_DB3 GPIO_PIN_13 -#define SCSI_OUT_DB2 GPIO_PIN_14 -#define SCSI_OUT_DB1 GPIO_PIN_0 -#define SCSI_OUT_DB0 GPIO_PIN_1 -#define SCSI_OUT_DBP GPIO_PIN_8 -#define SCSI_OUT_REQ GPIO_PIN_4 -#define SCSI_OUT_DATA_MASK (SCSI_OUT_DB0 | SCSI_OUT_DB1 | SCSI_OUT_DB2 | SCSI_OUT_DB3 | SCSI_OUT_DB4 | SCSI_OUT_DB5 | SCSI_OUT_DB6 | SCSI_OUT_DB7 | SCSI_OUT_DBP) -#define SCSI_OUT_REQ_IDX 4 - -// Control signals to optional PLD device -#define SCSI_OUT_PLD1 GPIO_PIN_15 -#define SCSI_OUT_PLD2 GPIO_PIN_3 -#define SCSI_OUT_PLD3 GPIO_PIN_5 -#define SCSI_OUT_PLD4 GPIO_PIN_7 - -// Control signals for timer based DMA acceleration -#define SCSI_TIMER TIMER7 -#define SCSI_TIMER_RCU RCU_TIMER7 -#define SCSI_TIMER_OUT_PORT GPIOB -#define SCSI_TIMER_OUT_PIN GPIO_PIN_1 -#define SCSI_TIMER_IN_PORT GPIOC -#define SCSI_TIMER_IN_PIN GPIO_PIN_6 -#define SCSI_TIMER_DMA DMA1 -#define SCSI_TIMER_DMA_RCU RCU_DMA1 -#define SCSI_TIMER_DMACHA DMA_CH4 -#define SCSI_TIMER_DMACHB DMA_CH1 -#define SCSI_TIMER_DMACHA_IRQ DMA1_Channel4_IRQHandler -#define SCSI_TIMER_DMACHA_IRQn DMA1_Channel4_IRQn -#define SCSI_TIMER_DMACHB_IRQ DMA1_Channel1_IRQHandler -#define SCSI_TIMER_DMACHB_IRQn DMA1_Channel1_IRQn - -// GreenPAK logic chip pins -#define GREENPAK_I2C_ADDR 0x10 -#define GREENPAK_I2C_PORT GPIOB -#define GREENPAK_I2C_SCL GPIO_PIN_8 -#define GREENPAK_I2C_SDA GPIO_PIN_9 -#define GREENPAK_PLD_IO1 GPIO_PIN_15 -#define GREENPAK_PLD_IO2 GPIO_PIN_3 -#define GREENPAK_PLD_IO3 GPIO_PIN_5 -#define GREENPAK_PLD_IO4 GPIO_PIN_7 -#define GREENPAK_PLD_IO2_EXTI EXTI_3 -#define GREENPAK_PLD_IO2_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOD -#define GREENPAK_PLD_IO2_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_3 -#define GREENPAK_IRQ EXTI3_IRQHandler -#define GREENPAK_IRQn EXTI3_IRQn - -// SCSI input data port -#define SCSI_IN_PORT GPIOE -#define SCSI_IN_DB7 GPIO_PIN_15 -#define SCSI_IN_DB6 GPIO_PIN_14 -#define SCSI_IN_DB5 GPIO_PIN_13 -#define SCSI_IN_DB4 GPIO_PIN_12 -#define SCSI_IN_DB3 GPIO_PIN_11 -#define SCSI_IN_DB2 GPIO_PIN_10 -#define SCSI_IN_DB1 GPIO_PIN_9 -#define SCSI_IN_DB0 GPIO_PIN_8 -#define SCSI_IN_DBP GPIO_PIN_7 -#define SCSI_IN_MASK (SCSI_IN_DB7|SCSI_IN_DB6|SCSI_IN_DB5|SCSI_IN_DB4|SCSI_IN_DB3|SCSI_IN_DB2|SCSI_IN_DB1|SCSI_IN_DB0|SCSI_IN_DBP) -#define SCSI_IN_SHIFT 8 - -// SCSI output status lines -#define SCSI_OUT_IO_PORT GPIOA -#define SCSI_OUT_IO_PIN GPIO_PIN_4 -#define SCSI_OUT_CD_PORT GPIOA -#define SCSI_OUT_CD_PIN GPIO_PIN_5 -#define SCSI_OUT_SEL_PORT GPIOA -#define SCSI_OUT_SEL_PIN GPIO_PIN_6 -#define SCSI_OUT_MSG_PORT GPIOA -#define SCSI_OUT_MSG_PIN GPIO_PIN_7 -#define SCSI_OUT_RST_PORT GPIOB -#define SCSI_OUT_RST_PIN GPIO_PIN_14 -#define SCSI_OUT_BSY_PORT GPIOB -#define SCSI_OUT_BSY_PIN GPIO_PIN_15 -#define SCSI_OUT_REQ_PORT SCSI_OUT_PORT -#define SCSI_OUT_REQ_PIN SCSI_OUT_REQ - -// SCSI input status signals -#define SCSI_ACK_PORT GPIOA -#define SCSI_ACK_PIN GPIO_PIN_0 -#define SCSI_ATN_PORT GPIOB -#define SCSI_ATN_PIN GPIO_PIN_12 -#define SCSI_IN_ACK_IDX 0 - -// Extra signals used with EXMC for synchronous mode -#define SCSI_IN_ACK_EXMC_NWAIT_PORT GPIOD -#define SCSI_IN_ACK_EXMC_NWAIT_PIN GPIO_PIN_6 -#define SCSI_OUT_REQ_EXMC_NOE_PORT GPIOD -#define SCSI_OUT_REQ_EXMC_NOE_PIN GPIO_PIN_4 -#define SCSI_OUT_REQ_EXMC_NOE_IDX 4 -#define SCSI_EXMC_DATA_SHIFT 5 -#define SCSI_EXMC_DMA DMA0 -#define SCSI_EXMC_DMA_RCU RCU_DMA0 -#define SCSI_EXMC_DMACH DMA_CH0 -#define SCSI_SYNC_TIMER TIMER1 -#define SCSI_SYNC_TIMER_RCU RCU_TIMER1 - -// SEL pin uses EXTI interrupt -#define SCSI_SEL_PORT GPIOB -#define SCSI_SEL_PIN GPIO_PIN_11 -#define SCSI_SEL_EXTI EXTI_11 -#define SCSI_SEL_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOB -#define SCSI_SEL_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_11 -#define SCSI_SEL_IRQ EXTI10_15_IRQHandler -#define SCSI_SEL_IRQn EXTI10_15_IRQn - -// BSY pin uses EXTI interrupt -#define SCSI_BSY_PORT GPIOB -#define SCSI_BSY_PIN GPIO_PIN_10 -#define SCSI_BSY_EXTI EXTI_10 -#define SCSI_BSY_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOB -#define SCSI_BSY_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_10 -#define SCSI_BSY_IRQ EXTI10_15_IRQHandler -#define SCSI_BSY_IRQn EXTI10_15_IRQn - -// RST pin uses EXTI interrupt -#define SCSI_RST_PORT GPIOB -#define SCSI_RST_PIN GPIO_PIN_13 -#define SCSI_RST_EXTI EXTI_13 -#define SCSI_RST_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOB -#define SCSI_RST_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_13 -#define SCSI_RST_IRQ EXTI10_15_IRQHandler -#define SCSI_RST_IRQn EXTI10_15_IRQn - -// Terminator enable/disable config, active low -#define SCSI_TERM_EN_PORT GPIOB -#define SCSI_TERM_EN_PIN GPIO_PIN_0 - -// SD card pins -#define SD_USE_SDIO 1 -#define SD_SDIO_DATA_PORT GPIOC -#define SD_SDIO_D0 GPIO_PIN_8 -#define SD_SDIO_D1 GPIO_PIN_9 -#define SD_SDIO_D2 GPIO_PIN_10 -#define SD_SDIO_D3 GPIO_PIN_11 -#define SD_SDIO_CLK_PORT GPIOC -#define SD_SDIO_CLK GPIO_PIN_12 -#define SD_SDIO_CMD_PORT GPIOD -#define SD_SDIO_CMD GPIO_PIN_2 - -// DIP switches -#define DIP_PORT GPIOB -#define DIPSW1_PIN GPIO_PIN_4 -#define DIPSW2_PIN GPIO_PIN_5 -#define DIPSW3_PIN GPIO_PIN_6 - -// Status LED pins -#define LED_PORT GPIOC -#define LED_I_PIN GPIO_PIN_4 -#define LED_E_PIN GPIO_PIN_5 -#define LED_PINS (LED_I_PIN | LED_E_PIN) -#define LED_ON() gpio_bit_reset(LED_PORT, LED_PINS) -#define LED_OFF() gpio_bit_set(LED_PORT, LED_PINS) diff --git a/lib/BlueSCSI_platform_GD32F205/bluescsi_gd32f205.ld b/lib/BlueSCSI_platform_GD32F205/bluescsi_gd32f205.ld deleted file mode 100644 index f7b28b18..00000000 --- a/lib/BlueSCSI_platform_GD32F205/bluescsi_gd32f205.ld +++ /dev/null @@ -1,175 +0,0 @@ -/* - * - * Customized linker script for combining bootloader & main program - * PlatformIO default linker script template for STM32 F1/F2/F3/F4/F7/L0/L1/L4 - * - */ - -/* Entry Point */ -ENTRY(Reset_Handler) - -/* Highest address of the user mode stack */ -_estack = 0x20020000; /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - -/* Specify the memory areas */ -MEMORY -{ - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K - CCRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0K - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K -} - -/* Define output sections */ -SECTIONS -{ - /* If bootloader is included, it goes in first 32 kB */ - .text.bootloader : ALIGN(16) SUBALIGN(16) - { - KEEP(*(.text.btldr*)) - . = ALIGN(32768); - CHECK_BOOTLOADER_SIZE = 1 / (. <= 32768); - } >FLASH - - /* The startup code goes first into FLASH */ - .isr_vector : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >FLASH - - /* The program code and other data goes into FLASH */ - .text : - { - . = ALIGN(4); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) - - KEEP (*(.init)) - KEEP (*(.fini)) - - . = ALIGN(4); - _etext = .; /* define a global symbols at end of code */ - } >FLASH - - /* Constant data goes into FLASH */ - .rodata : - { - . = ALIGN(4); - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - . = ALIGN(4); - } >FLASH - - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH - .ARM : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >FLASH - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - - /* used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections goes into RAM, load LMA copy after code */ - .data : - { - . = ALIGN(4); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - - . = ALIGN(4); - _edata = .; /* define a global symbol at data end */ - } >RAM AT> FLASH - - /* Uninitialized data section */ - . = ALIGN(4); - .bss : - { - /* This is used by the startup in order to initialize the .bss secion */ - _sbss = .; /* define a global symbol at bss start */ - __bss_start__ = _sbss; - *(.bss) - *(.bss*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; /* define a global symbol at bss end */ - __bss_end__ = _ebss; - } >RAM - - /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack : - { - . = ALIGN(4); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; - . = . + _Min_Stack_Size; - . = ALIGN(4); - } >RAM - - /* uninitialized CCRAM objects (like, buffers) */ - .ccram_bss : - { - __ccram_start_bss__ = .; /* define a global symbol at ccram start */ - KEEP(*(.ccram_bss)) - KEEP(*(.ccram_bss*)) - . = ALIGN(4); - __ccram_end_bss__ = .; /* define a global symbol at end of *used* CCRAM (BSS) */ - } >CCRAM - - /* initialized CCRAM objects (like, initialized variables) */ - _si_ccram_data = LOADADDR(.ccram_data); - .ccram_data : - { - . = ALIGN(4); - _ccram_start_data = .; /* create a global symbol at data start */ - *(.ccram_bss) /* .data sections */ - *(.ccram_bss*) /* .data* sections */ - - . = ALIGN(4); - _ccram_end_data = .; /* define a global symbol at data end */ - } >CCRAM AT> FLASH - - - /* Remove information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - .ARM.attributes 0 : { *(.ARM.attributes) } -} - - diff --git a/lib/BlueSCSI_platform_GD32F205/bluescsi_gd32f205_btldr.ld b/lib/BlueSCSI_platform_GD32F205/bluescsi_gd32f205_btldr.ld deleted file mode 100644 index 563afa1d..00000000 --- a/lib/BlueSCSI_platform_GD32F205/bluescsi_gd32f205_btldr.ld +++ /dev/null @@ -1,182 +0,0 @@ -/* - * - * Customized linker script for building bootloader - * - */ - -/* Entry Point */ -ENTRY(Reset_Handler) - -/* Highest address of the user mode stack */ -_estack = 0x20020000; /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - -/* Specify the memory areas */ -MEMORY -{ - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K - CCRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0K - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K -} - -/* Define output sections */ -SECTIONS -{ - /* Discard interrupt vectors that are not needed for bootloader. - * This way unnecessary code doesn't get pulled in. - */ - /DISCARD/ : - { - *(*DMA1_Channel4_IRQHandler*) - *(*DMA1_Channel1_IRQHandler*) - *(*EXTI3_IRQHandler*) - *(*EXTI10_15_IRQHandler*) - } - - DMA1_Channel1_IRQHandler = 0; - DMA1_Channel4_IRQHandler = 0; - EXTI10_15_IRQHandler = 0; - EXTI3_IRQHandler = 0; - - /* The startup code goes first into FLASH */ - .isr_vector : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >FLASH - - /* The program code and other data goes into FLASH */ - .text : - { - . = ALIGN(4); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) - - KEEP (*(.init)) - KEEP (*(.fini)) - - . = ALIGN(4); - _etext = .; /* define a global symbols at end of code */ - } >FLASH - - /* Constant data goes into FLASH */ - .rodata : - { - . = ALIGN(4); - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - . = ALIGN(4); - } >FLASH - - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH - .ARM : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >FLASH - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - - /* used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections goes into RAM, load LMA copy after code */ - .data : - { - . = ALIGN(4); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - - . = ALIGN(4); - _edata = .; /* define a global symbol at data end */ - } >RAM AT> FLASH - - /* Uninitialized data section */ - . = ALIGN(4); - .bss : - { - /* This is used by the startup in order to initialize the .bss secion */ - _sbss = .; /* define a global symbol at bss start */ - __bss_start__ = _sbss; - *(.bss) - *(.bss*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; /* define a global symbol at bss end */ - __bss_end__ = _ebss; - } >RAM - - /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack : - { - . = ALIGN(4); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; - . = . + _Min_Stack_Size; - . = ALIGN(4); - } >RAM - - /* uninitialized CCRAM objects (like, buffers) */ - .ccram_bss : - { - __ccram_start_bss__ = .; /* define a global symbol at ccram start */ - KEEP(*(.ccram_bss)) - KEEP(*(.ccram_bss*)) - . = ALIGN(4); - __ccram_end_bss__ = .; /* define a global symbol at end of *used* CCRAM (BSS) */ - } >CCRAM - - /* initialized CCRAM objects (like, initialized variables) */ - _si_ccram_data = LOADADDR(.ccram_data); - .ccram_data : - { - . = ALIGN(4); - _ccram_start_data = .; /* create a global symbol at data start */ - *(.ccram_bss) /* .data sections */ - *(.ccram_bss*) /* .data* sections */ - - . = ALIGN(4); - _ccram_end_data = .; /* define a global symbol at data end */ - } >CCRAM AT> FLASH - - - /* Remove information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - .ARM.attributes 0 : { *(.ARM.attributes) } -} - - diff --git a/lib/BlueSCSI_platform_GD32F205/bsp.h b/lib/BlueSCSI_platform_GD32F205/bsp.h deleted file mode 100644 index 474d1f8a..00000000 --- a/lib/BlueSCSI_platform_GD32F205/bsp.h +++ /dev/null @@ -1,5 +0,0 @@ -// Dummy file for SCSI2SD. - -#pragma once - -#define S2S_DMA_ALIGN diff --git a/lib/BlueSCSI_platform_GD32F205/gd32_sdio_sdcard.c b/lib/BlueSCSI_platform_GD32F205/gd32_sdio_sdcard.c deleted file mode 100644 index e7a2e8f9..00000000 --- a/lib/BlueSCSI_platform_GD32F205/gd32_sdio_sdcard.c +++ /dev/null @@ -1,2520 +0,0 @@ -/*! - \file sdcard.c - \brief SD card driver - - \version 2015-07-15, V1.0.0, firmware for GD32F20x - \version 2017-06-05, V2.0.0, firmware for GD32F20x - \version 2018-10-31, V2.1.0, firmware for GD32F20x - \version 2020-09-30, V2.2.0, firmware for GD32F20x - \version 2021-07-30, V2.3.0, firmware for GD32F20x -*/ - -/* - Copyright (c) 2021, GigaDevice Semiconductor Inc. - - Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - 3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -#include "gd32_sdio_sdcard.h" -#include "gd32f20x_sdio.h" -#include - -/* card status of R1 definitions */ -#define SD_R1_OUT_OF_RANGE BIT(31) /* command's argument was out of the allowed range */ -#define SD_R1_ADDRESS_ERROR BIT(30) /* misaligned address which did not match the block length */ -#define SD_R1_BLOCK_LEN_ERROR BIT(29) /* transferred block length is not allowed */ -#define SD_R1_ERASE_SEQ_ERROR BIT(28) /* an error in the sequence of erase commands occurred */ -#define SD_R1_ERASE_PARAM BIT(27) /* an invalid selection of write-blocks for erase occurred */ -#define SD_R1_WP_VIOLATION BIT(26) /* the host attempts to write to a protected block or to the temporary or permanent write protected card */ -#define SD_R1_CARD_IS_LOCKED BIT(25) /* the card is locked by the host */ -#define SD_R1_LOCK_UNLOCK_FAILED BIT(24) /* a sequence or password error has been detected in lock/unlock card command */ -#define SD_R1_COM_CRC_ERROR BIT(23) /* CRC check of the previous command failed */ -#define SD_R1_ILLEGAL_COMMAND BIT(22) /* command not legal for the card state */ -#define SD_R1_CARD_ECC_FAILED BIT(21) /* card internal ECC was applied but failed to correct the data */ -#define SD_R1_CC_ERROR BIT(20) /* internal card controller error */ -#define SD_R1_GENERAL_UNKNOWN_ERROR BIT(19) /* a general or an unknown error occurred during the operation */ -#define SD_R1_CSD_OVERWRITE BIT(16) /* read only section of the CSD does not match or attempt to reverse the copy or permanent WP bits */ -#define SD_R1_WP_ERASE_SKIP BIT(15) /* partial address space was erased */ -#define SD_R1_CARD_ECC_DISABLED BIT(14) /* command has been executed without using the internal ECC */ -#define SD_R1_ERASE_RESET BIT(13) /* an erase sequence was cleared before executing */ -#define SD_R1_READY_FOR_DATA BIT(8) /* correspond to buffer empty signaling on the bus */ -#define SD_R1_APP_CMD BIT(5) /* card will expect ACMD */ -#define SD_R1_AKE_SEQ_ERROR BIT(3) /* error in the sequence of the authentication process */ -#define SD_R1_ERROR_BITS (uint32_t)0xFDF9E008 /* all the R1 error bits */ - -/* card status of R6 definitions */ -#define SD_R6_COM_CRC_ERROR BIT(15) /* CRC check of the previous command failed */ -#define SD_R6_ILLEGAL_COMMAND BIT(14) /* command not legal for the card state */ -#define SD_R6_GENERAL_UNKNOWN_ERROR BIT(13) /* a general or an unknown error occurred during the operation */ - -/* card state */ -#define SD_CARDSTATE_IDLE ((uint8_t)0x00) /* card is in idle state */ -#define SD_CARDSTATE_READY ((uint8_t)0x01) /* card is in ready state */ -#define SD_CARDSTATE_IDENTIFICAT ((uint8_t)0x02) /* card is in identificat state */ -#define SD_CARDSTATE_STANDBY ((uint8_t)0x03) /* card is in standby state */ -#define SD_CARDSTATE_TRANSFER ((uint8_t)0x04) /* card is in transfer state */ -#define SD_CARDSTATE_DATA ((uint8_t)0x05) /* card is in data sending state */ -#define SD_CARDSTATE_RECEIVING ((uint8_t)0x06) /* card is in receiving state */ -#define SD_CARDSTATE_PROGRAMMING ((uint8_t)0x07) /* card is in programming state */ -#define SD_CARDSTATE_DISCONNECT ((uint8_t)0x08) /* card is in disconnect state */ -#define SD_CARDSTATE_LOCKED ((uint32_t)0x02000000) /* card is in locked state */ - -#define SD_CHECK_PATTERN ((uint32_t)0x000001AA) /* check pattern for CMD8 */ -#define SD_VOLTAGE_WINDOW ((uint32_t)0x80100000) /* host 3.3V request in ACMD41 */ - -/* parameters for ACMD41(voltage validation) */ -#define SD_HIGH_CAPACITY ((uint32_t)0x40000000) /* high capacity SD memory card */ -#define SD_STD_CAPACITY ((uint32_t)0x00000000) /* standard capacity SD memory card */ - -/* SD bus width, check SCR register */ -#define SD_BUS_WIDTH_4BIT ((uint32_t)0x00040000) /* 4-bit width bus mode */ -#define SD_BUS_WIDTH_1BIT ((uint32_t)0x00010000) /* 1-bit width bus mode */ - -/* masks for SCR register */ -#define SD_MASK_0_7BITS ((uint32_t)0x000000FF) /* mask [7:0] bits */ -#define SD_MASK_8_15BITS ((uint32_t)0x0000FF00) /* mask [15:8] bits */ -#define SD_MASK_16_23BITS ((uint32_t)0x00FF0000) /* mask [23:16] bits */ -#define SD_MASK_24_31BITS ((uint32_t)0xFF000000) /* mask [31:24] bits */ - -#define SDIO_FIFO_ADDR ((uint32_t)SDIO + 0x80U) /* address of SDIO_FIFO */ -#define SD_FIFOHALF_WORDS ((uint32_t)0x00000008) /* words of FIFO half full/empty */ -#define SD_FIFOHALF_BYTES ((uint32_t)0x00000020) /* bytes of FIFO half full/empty */ - -#define SD_DATATIMEOUT ((uint32_t)0xFFFFFFFF) /* DSM data timeout */ -#define SD_MAX_VOLT_VALIDATION ((uint32_t)0x0000FFFF) /* the maximum times of voltage validation */ -#define SD_MAX_DATA_LENGTH ((uint32_t)0x01FFFFFF) /* the maximum length of data */ -#define SD_ALLZERO ((uint32_t)0x00000000) /* all zero */ -#define SD_RCA_SHIFT ((uint8_t)0x10) /* RCA shift bits */ -#define SD_CLK_DIV_INIT ((uint16_t)0x0076) /* SD clock division in initilization phase */ -#define SD_CLK_DIV_TRANS ((uint16_t)0x0002) /* SD clock division in transmission phase */ - -#define SDIO_MASK_INTC_FLAGS ((uint32_t)0x00C007FF) /* mask flags of SDIO_INTC */ - -uint32_t sd_scr[2] = {0, 0}; /* content of SCR register */ - -static sdio_card_type_enum cardtype = SDIO_STD_CAPACITY_SD_CARD_V1_1; /* SD card type */ -static uint32_t sd_csd[4] = {0, 0, 0, 0}; /* content of CSD register */ -static uint32_t sd_cid[4] = {0, 0, 0, 0}; /* content of CID register */ -static uint16_t sd_rca = 0; /* RCA of SD card */ -static uint32_t transmode = SD_POLLING_MODE; -static uint32_t totalnumber_bytes = 0, stopcondition = 0; -static __IO sd_error_enum transerror = SD_OK; -static __IO uint32_t transend = 0, number_bytes = 0; - -/* check if the command sent error occurs */ -static sd_error_enum cmdsent_error_check(void); -/* check if error occurs for R1 response */ -static sd_error_enum r1_error_check(uint8_t cmdindex); -/* check if error type for R1 response */ -static sd_error_enum r1_error_type_check(uint32_t resp); -/* check if error occurs for R2 response */ -static sd_error_enum r2_error_check(void); -/* check if error occurs for R3 response */ -static sd_error_enum r3_error_check(void); -/* check if error occurs for R6 response */ -static sd_error_enum r6_error_check(uint8_t cmdindex, uint16_t *prca); -/* check if error occurs for R7 response */ -static sd_error_enum r7_error_check(void); - -/* get the state which the card is in */ -static sd_error_enum sd_card_state_get(uint8_t *pcardstate); -/* configure the bus width mode */ -static sd_error_enum sd_bus_width_config(uint32_t buswidth); -/* get the SCR of corresponding card */ -static sd_error_enum sd_scr_get(uint16_t rca, uint32_t *pscr); -/* get the data block size */ -static uint32_t sd_datablocksize_get(uint16_t bytesnumber); - -/* configure the DMA for SDIO transfer request */ -static void dma_transfer_config(uint32_t *srcbuf, uint32_t bufsize); -/* configure the DMA for SDIO receive request */ -static void dma_receive_config(uint32_t *dstbuf, uint32_t bufsize); - -unsigned long millis(void); - -/*! - \brief initialize the SD card and make it in standby state - \param[in] none - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_init(void) -{ - sd_error_enum status = SD_OK; - /* configure the RCU and GPIO, deinitialize the SDIO */ - sdio_deinit(); - - /* configure the clock and work voltage */ - status = sd_power_on(); - if(SD_OK != status) { - return status; - } - - /* initialize the card and get CID and CSD of the card */ - status = sd_card_init(); - if(SD_OK != status) { - return status; - } - - /* configure the SDIO peripheral */ - sdio_clock_config(SDIO_SDIOCLKEDGE_RISING, SDIO_CLOCKBYPASS_DISABLE, SDIO_CLOCKPWRSAVE_DISABLE, SD_CLK_DIV_TRANS); - sdio_bus_mode_set(SDIO_BUSMODE_1BIT); - sdio_hardware_clock_disable(); - - return status; -} - -/*! - \brief initialize the card and get CID and CSD of the card - \param[in] none - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_card_init(void) -{ - sd_error_enum status = SD_OK; - uint16_t temp_rca = 0x01; - - if(SDIO_POWER_OFF == sdio_power_state_get()) { - status = SD_OPERATION_IMPROPER; - return status; - } - - /* the card is not I/O only card */ - if(SDIO_SECURE_DIGITAL_IO_CARD != cardtype) { - /* send CMD2(SD_CMD_ALL_SEND_CID) to get the CID numbers */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_ALL_SEND_CID, (uint32_t)0x0, SDIO_RESPONSETYPE_LONG); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r2_error_check(); - if(SD_OK != status) { - return status; - } - - /* store the CID numbers */ - sd_cid[0] = sdio_response_get(SDIO_RESPONSE0); - sd_cid[1] = sdio_response_get(SDIO_RESPONSE1); - sd_cid[2] = sdio_response_get(SDIO_RESPONSE2); - sd_cid[3] = sdio_response_get(SDIO_RESPONSE3); - } - - /* the card is SD memory card or the I/O card has the memory portion */ - if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype) || - (SDIO_HIGH_CAPACITY_SD_CARD == cardtype) || (SDIO_SECURE_DIGITAL_IO_COMBO_CARD == cardtype)) { - /* send CMD3(SEND_RELATIVE_ADDR) to ask the card to publish a new relative address (RCA) */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SEND_RELATIVE_ADDR, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r6_error_check(SD_CMD_SEND_RELATIVE_ADDR, &temp_rca); - if(SD_OK != status) { - return status; - } - } - - if(SDIO_SECURE_DIGITAL_IO_CARD != cardtype) { - /* the card is not I/O only card */ - sd_rca = temp_rca; - - /* send CMD9(SEND_CSD) to get the addressed card's card-specific data (CSD) */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SEND_CSD, (uint32_t)(temp_rca << SD_RCA_SHIFT), SDIO_RESPONSETYPE_LONG); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r2_error_check(); - if(SD_OK != status) { - return status; - } - - /* store the card-specific data (CSD) */ - sd_csd[0] = sdio_response_get(SDIO_RESPONSE0); - sd_csd[1] = sdio_response_get(SDIO_RESPONSE1); - sd_csd[2] = sdio_response_get(SDIO_RESPONSE2); - sd_csd[3] = sdio_response_get(SDIO_RESPONSE3); - } - return status; -} - -/*! - \brief configure the clock and the work voltage, and get the card type - \param[in] none - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_power_on(void) -{ - sd_error_enum status = SD_OK; - uint32_t sdcardtype = SD_STD_CAPACITY, response = 0, count = 0; - uint8_t busyflag = 0; - - /* configure the SDIO peripheral */ - sdio_clock_config(SDIO_SDIOCLKEDGE_RISING, SDIO_CLOCKBYPASS_DISABLE, SDIO_CLOCKPWRSAVE_DISABLE, SD_CLK_DIV_INIT); - sdio_bus_mode_set(SDIO_BUSMODE_1BIT); - sdio_hardware_clock_disable(); - sdio_power_state_set(SDIO_POWER_ON); - /* enable SDIO_CLK clock output */ - sdio_clock_enable(); - - /* send CMD0(GO_IDLE_STATE) to reset the card */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_GO_IDLE_STATE, (uint32_t)0x0, SDIO_RESPONSETYPE_NO); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - /* enable the CSM */ - sdio_csm_enable(); - - /* check if command sent error occurs */ - status = cmdsent_error_check(); - if(SD_OK != status) { - return status; - } - - /* send CMD8(SEND_IF_COND) to get SD memory card interface condition */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SEND_IF_COND, SD_CHECK_PATTERN, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - - if(SD_OK == r7_error_check()) { - /* SD Card 2.0 */ - cardtype = SDIO_STD_CAPACITY_SD_CARD_V2_0; - sdcardtype = SD_HIGH_CAPACITY; - } - - while((!busyflag) && (count < SD_MAX_VOLT_VALIDATION)) { - /* send CMD55(APP_CMD) to indicate next command is application specific command */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - - - /* check if some error occurs */ - /* ignoring return value, SD_ILLEGAL_COMMAND, for v1.x spec SD cards */ - status = r1_error_check(SD_CMD_APP_CMD); - if(SD_OK != status && SD_ILLEGAL_COMMAND != status) { - return status; - } - - /* send ACMD41(SD_SEND_OP_COND) to get host capacity support information (HCS) and OCR content */ - sdio_csm_disable(); - sdio_command_response_config(SD_APPCMD_SD_SEND_OP_COND, (SD_VOLTAGE_WINDOW | sdcardtype), SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - - status = r3_error_check(); - if(SD_OK != status) { - return status; - } - /* get the response and check card power up status bit(busy) */ - response = sdio_response_get(SDIO_RESPONSE0); - busyflag = (uint8_t)((response >> 31) & (uint32_t)0x01); - ++count; - } - if(count >= SD_MAX_VOLT_VALIDATION) { - status = SD_VOLTRANGE_INVALID; - return status; - } - if(response &= SD_HIGH_CAPACITY) { - /* SDHC card */ - cardtype = SDIO_HIGH_CAPACITY_SD_CARD; - } - - return status; -} - -/*! - \brief close the power of SDIO - \param[in] none - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_power_off(void) -{ - sd_error_enum status = SD_OK; - sdio_power_state_set(SDIO_POWER_OFF); - return status; -} - -/*! - \brief configure the bus mode - \param[in] busmode: the bus mode - \arg SDIO_BUSMODE_1BIT: 1-bit SDIO card bus mode - \arg SDIO_BUSMODE_4BIT: 4-bit SDIO card bus mode - \arg SDIO_BUSMODE_8BIT: 8-bit SDIO card bus mode (MMC only) - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_bus_mode_config(uint32_t busmode) -{ - sd_error_enum status = SD_OK; - if(SDIO_MULTIMEDIA_CARD == cardtype) { - /* MMC card doesn't support this function */ - status = SD_FUNCTION_UNSUPPORTED; - return status; - } else if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype) || - (SDIO_HIGH_CAPACITY_SD_CARD == cardtype)) { - if(SDIO_BUSMODE_8BIT == busmode) { - /* 8 bit bus mode doesn't support */ - status = SD_FUNCTION_UNSUPPORTED; - return status; - } else if(SDIO_BUSMODE_4BIT == busmode) { - /* configure SD bus width and the SDIO */ - status = sd_bus_width_config(SD_BUS_WIDTH_4BIT); - if(SD_OK == status) { - sdio_clock_config(SDIO_SDIOCLKEDGE_RISING, SDIO_CLOCKBYPASS_DISABLE, - SDIO_CLOCKPWRSAVE_DISABLE, SD_CLK_DIV_TRANS); - sdio_bus_mode_set(busmode); - sdio_hardware_clock_disable(); - } - } else if(SDIO_BUSMODE_1BIT == busmode) { - /* configure SD bus width and the SDIO */ - status = sd_bus_width_config(SD_BUS_WIDTH_1BIT); - if(SD_OK == status) { - sdio_clock_config(SDIO_SDIOCLKEDGE_RISING, SDIO_CLOCKBYPASS_DISABLE, - SDIO_CLOCKPWRSAVE_DISABLE, SD_CLK_DIV_TRANS); - sdio_bus_mode_set(busmode); - sdio_hardware_clock_disable(); - } - } else { - status = SD_PARAMETER_INVALID; - } - } - return status; -} - -/*! - \brief configure the mode of transmission - \param[in] txmode: transfer mode - \arg SD_DMA_MODE: DMA mode - \arg SD_POLLING_MODE: polling mode - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_transfer_mode_config(uint32_t txmode) -{ - sd_error_enum status = SD_OK; - /* set the transfer mode */ - if((SD_DMA_MODE == txmode) || (SD_POLLING_MODE == txmode)) { - transmode = txmode; - } else { - status = SD_PARAMETER_INVALID; - } - return status; -} - -/*! - \brief read a block data into a buffer from the specified address of a card - \param[out] preadbuffer: a pointer that store a block read data - \param[in] readaddr: the read data address - \param[in] blocksize: the data block size - \retval sd_error_enum -*/ -sd_error_enum sd_block_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t blocksize, sdio_callback_t callback) -{ - /* initialize the variables */ - sd_error_enum status = SD_OK; - uint32_t count = 0, align = 0, datablksize = SDIO_DATABLOCKSIZE_1BYTE, *ptempbuff = preadbuffer; - - if(NULL == preadbuffer) { - status = SD_PARAMETER_INVALID; - return status; - } - - transerror = SD_OK; - transend = 0; - totalnumber_bytes = 0; - /* clear all DSM configuration */ - sdio_data_config(0, 0, SDIO_DATABLOCKSIZE_1BYTE); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOCARD); - sdio_dsm_disable(); - sdio_dma_disable(); - - /* check whether the card is locked */ - if(sdio_response_get(SDIO_RESPONSE0) & SD_CARDSTATE_LOCKED) { - status = SD_LOCK_UNLOCK_FAILED; - return status; - } - - /* blocksize is fixed in 512B for SDHC card */ - if(SDIO_HIGH_CAPACITY_SD_CARD == cardtype) { - blocksize = 512; - readaddr /= 512; - } - - align = blocksize & (blocksize - 1); - if((blocksize > 0) && (blocksize <= 2048) && (0 == align)) { - datablksize = sd_datablocksize_get(blocksize); - /* send CMD16(SET_BLOCKLEN) to set the block length */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)blocksize, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SET_BLOCKLEN); - if(SD_OK != status) { - return status; - } - } else { - status = SD_PARAMETER_INVALID; - return status; - } - - stopcondition = 0; - totalnumber_bytes = blocksize; - - /* configure SDIO data transmission */ - sdio_data_config(SD_DATATIMEOUT, totalnumber_bytes, datablksize); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOSDIO); - sdio_dsm_enable(); - - /* send CMD17(READ_SINGLE_BLOCK) to read a block */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_READ_SINGLE_BLOCK, (uint32_t)readaddr, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_READ_SINGLE_BLOCK); - if(SD_OK != status) { - return status; - } - - if(SD_POLLING_MODE == transmode) { - /* polling mode */ - while(!sdio_flag_get(SDIO_FLAG_DTCRCERR | SDIO_FLAG_DTTMOUT | SDIO_FLAG_RXORE | SDIO_FLAG_DTBLKEND | SDIO_FLAG_STBITE)) { - if(RESET != sdio_flag_get(SDIO_FLAG_RFH)) { - /* at least 8 words can be read in the FIFO */ - for(count = 0; count < SD_FIFOHALF_WORDS; count++) { - *(ptempbuff + count) = sdio_data_read(); - } - ptempbuff += SD_FIFOHALF_WORDS; - } - } - - /* whether some error occurs and return it */ - if(RESET != sdio_flag_get(SDIO_FLAG_DTCRCERR)) { - status = SD_DATA_CRC_ERROR; - sdio_flag_clear(SDIO_FLAG_DTCRCERR); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_DTTMOUT)) { - status = SD_DATA_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_DTTMOUT); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_RXORE)) { - status = SD_RX_OVERRUN_ERROR; - sdio_flag_clear(SDIO_FLAG_RXORE); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_STBITE)) { - status = SD_START_BIT_ERROR; - sdio_flag_clear(SDIO_FLAG_STBITE); - return status; - } - while(RESET != sdio_flag_get(SDIO_FLAG_RXDTVAL)) { - *ptempbuff = sdio_data_read(); - ++ptempbuff; - } - /* clear the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - } else if(SD_DMA_MODE == transmode) { - /* DMA mode */ - /* enable the SDIO corresponding interrupts and DMA function */ - sdio_interrupt_enable(SDIO_INT_CCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_RXORE | SDIO_INT_DTEND | SDIO_INT_STBITE); - sdio_dma_enable(); - dma_receive_config(preadbuffer, blocksize); - uint32_t start = millis(); - while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF))) { - if((uint32_t)(millis() - start) > 1000) { - return SD_ERROR; - } - if (callback) - { - uint32_t complete = (blocksize - DMA_CHCNT(DMA1, DMA_CH3) * 4); - callback(complete); - } - } - } else { - status = SD_PARAMETER_INVALID; - } - return status; -} - -/*! - \brief read multiple blocks data into a buffer from the specified address of a card - \param[out] preadbuffer: a pointer that store multiple blocks read data - \param[in] readaddr: the read data address - \param[in] blocksize: the data block size - \param[in] blocksnumber: number of blocks that will be read - \retval sd_error_enum -*/ -sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t blocksize, uint32_t blocksnumber, sdio_callback_t callback) -{ - /* initialize the variables */ - sd_error_enum status = SD_OK; - uint32_t count = 0, align = 0, datablksize = SDIO_DATABLOCKSIZE_1BYTE, *ptempbuff = preadbuffer; - - if(NULL == preadbuffer) { - status = SD_PARAMETER_INVALID; - return status; - } - - transerror = SD_OK; - transend = 0; - totalnumber_bytes = 0; - /* clear all DSM configuration */ - sdio_data_config(0, 0, SDIO_DATABLOCKSIZE_1BYTE); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOCARD); - sdio_dsm_disable(); - sdio_dma_disable(); - - /* check whether the card is locked */ - if(sdio_response_get(SDIO_RESPONSE0) & SD_CARDSTATE_LOCKED) { - status = SD_LOCK_UNLOCK_FAILED; - return status; - } - - /* blocksize is fixed in 512B for SDHC card */ - if(SDIO_HIGH_CAPACITY_SD_CARD == cardtype) { - blocksize = 512; - readaddr /= 512; - } - - align = blocksize & (blocksize - 1); - if((blocksize > 0) && (blocksize <= 2048) && (0 == align)) { - datablksize = sd_datablocksize_get(blocksize); - /* send CMD16(SET_BLOCKLEN) to set the block length */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)blocksize, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SET_BLOCKLEN); - if(SD_OK != status) { - return status; - } - } else { - status = SD_PARAMETER_INVALID; - return status; - } - - if(blocksnumber >= 1) { - if(blocksnumber * blocksize > SD_MAX_DATA_LENGTH) { - /* exceeds the maximum length */ - status = SD_PARAMETER_INVALID; - return status; - } - - stopcondition = 1; - totalnumber_bytes = blocksnumber * blocksize; - - /* configure the SDIO data transmission */ - sdio_data_config(SD_DATATIMEOUT, totalnumber_bytes, datablksize); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOSDIO); - sdio_dsm_enable(); - - /* send CMD18(READ_MULTIPLE_BLOCK) to read multiple blocks */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_READ_MULTIPLE_BLOCK, readaddr, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_READ_MULTIPLE_BLOCK); - if(SD_OK != status) { - return status; - } - - if(SD_POLLING_MODE == transmode) { - /* polling mode */ - while(!sdio_flag_get(SDIO_FLAG_DTCRCERR | SDIO_FLAG_DTTMOUT | SDIO_FLAG_RXORE | SDIO_FLAG_DTEND | SDIO_FLAG_STBITE)) { - if(RESET != sdio_flag_get(SDIO_FLAG_RFH)) { - /* at least 8 words can be read in the FIFO */ - for(count = 0; count < SD_FIFOHALF_WORDS; count++) { - *(ptempbuff + count) = sdio_data_read(); - } - ptempbuff += SD_FIFOHALF_WORDS; - } - } - - /* whether some error occurs and return it */ - if(RESET != sdio_flag_get(SDIO_FLAG_DTCRCERR)) { - status = SD_DATA_CRC_ERROR; - sdio_flag_clear(SDIO_FLAG_DTCRCERR); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_DTTMOUT)) { - status = SD_DATA_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_DTTMOUT); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_RXORE)) { - status = SD_RX_OVERRUN_ERROR; - sdio_flag_clear(SDIO_FLAG_RXORE); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_STBITE)) { - status = SD_START_BIT_ERROR; - sdio_flag_clear(SDIO_FLAG_STBITE); - return status; - } - while(RESET != sdio_flag_get(SDIO_FLAG_RXDTVAL)) { - *ptempbuff = sdio_data_read(); - ++ptempbuff; - } - - if(RESET != sdio_flag_get(SDIO_FLAG_DTEND)) { - if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype) || - (SDIO_HIGH_CAPACITY_SD_CARD == cardtype)) { - /* send CMD12(STOP_TRANSMISSION) to stop transmission */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_STOP_TRANSMISSION, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_STOP_TRANSMISSION); - if(SD_OK != status) { - return status; - } - } - } - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - } else if(SD_DMA_MODE == transmode) { - /* DMA mode */ - /* enable the SDIO corresponding interrupts and DMA function */ - sdio_interrupt_enable(SDIO_INT_DTCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_RXORE | SDIO_INT_DTEND | SDIO_INT_STBITE); - sdio_dma_enable(); - dma_receive_config(preadbuffer, totalnumber_bytes); - - uint32_t start = millis(); - while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF))) { - if((uint32_t)(millis() - start) > 1000) { - return SD_ERROR; - } - if (callback) - { - uint32_t complete = (totalnumber_bytes - DMA_CHCNT(DMA1, DMA_CH3) * 4); - callback(complete); - } - } - while((0 == transend) && (SD_OK == transerror)) { - if (callback) - { - callback(totalnumber_bytes); - } - } - if(SD_OK != transerror) { - return transerror; - } - } else { - status = SD_PARAMETER_INVALID; - } - } - return status; -} - -/*! - \brief write a block data to the specified address of a card - \param[in] pwritebuffer: a pointer that store a block data to be transferred - \param[in] writeaddr: the read data address - \param[in] blocksize: the data block size - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_t blocksize, sdio_callback_t callback) -{ - /* initialize the variables */ - sd_error_enum status = SD_OK; - uint8_t cardstate = 0; - uint32_t count = 0, align = 0, datablksize = SDIO_DATABLOCKSIZE_1BYTE, *ptempbuff = pwritebuffer; - uint32_t transbytes = 0, restwords = 0, response = 0; - - if(NULL == pwritebuffer) { - status = SD_PARAMETER_INVALID; - return status; - } - - transerror = SD_OK; - transend = 0; - totalnumber_bytes = 0; - /* clear all DSM configuration */ - sdio_data_config(0, 0, SDIO_DATABLOCKSIZE_1BYTE); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOCARD); - sdio_dsm_disable(); - sdio_dma_disable(); - - /* check whether the card is locked */ - if(sdio_response_get(SDIO_RESPONSE0) & SD_CARDSTATE_LOCKED) { - status = SD_LOCK_UNLOCK_FAILED; - return status; - } - - /* blocksize is fixed in 512B for SDHC card */ - if(SDIO_HIGH_CAPACITY_SD_CARD == cardtype) { - blocksize = 512; - writeaddr /= 512; - } - - align = blocksize & (blocksize - 1); - if((blocksize > 0) && (blocksize <= 2048) && (0 == align)) { - datablksize = sd_datablocksize_get(blocksize); - /* send CMD16(SET_BLOCKLEN) to set the block length */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)blocksize, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SET_BLOCKLEN); - if(SD_OK != status) { - return status; - } - } else { - status = SD_PARAMETER_INVALID; - return status; - } - - /* send CMD13(SEND_STATUS), addressed card sends its status registers */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SEND_STATUS); - if(SD_OK != status) { - return status; - } - - response = sdio_response_get(SDIO_RESPONSE0); - - uint32_t start = millis(); - while((0 == (response & SD_R1_READY_FOR_DATA))) { - /* continue to send CMD13 to polling the state of card until buffer empty or timeout */ - if((uint32_t)(millis() - start) > 1000) { - return SD_ERROR; - } - - if (callback) - { - callback(0); - } - - /* send CMD13(SEND_STATUS), addressed card sends its status registers */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SEND_STATUS); - if(SD_OK != status) { - return status; - } - response = sdio_response_get(SDIO_RESPONSE0); - } - - /* send CMD24(WRITE_BLOCK) to write a block */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_WRITE_BLOCK, writeaddr, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_WRITE_BLOCK); - if(SD_OK != status) { - return status; - } - - stopcondition = 0; - totalnumber_bytes = blocksize; - - /* configure the SDIO data transmission */ - sdio_data_config(SD_DATATIMEOUT, totalnumber_bytes, datablksize); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOCARD); - sdio_dsm_enable(); - - if(SD_POLLING_MODE == transmode) { - /* polling mode */ - while(!sdio_flag_get(SDIO_FLAG_DTCRCERR | SDIO_FLAG_DTTMOUT | SDIO_FLAG_TXURE | SDIO_FLAG_DTBLKEND | SDIO_FLAG_STBITE)) { - if(RESET != sdio_flag_get(SDIO_FLAG_TFH)) { - /* at least 8 words can be written into the FIFO */ - if((totalnumber_bytes - transbytes) < SD_FIFOHALF_BYTES) { - restwords = (totalnumber_bytes - transbytes) / 4 + (((totalnumber_bytes - transbytes) % 4 == 0) ? 0 : 1); - for(count = 0; count < restwords; count++) { - sdio_data_write(*ptempbuff); - ++ptempbuff; - transbytes += 4; - } - } else { - for(count = 0; count < SD_FIFOHALF_WORDS; count++) { - sdio_data_write(*(ptempbuff + count)); - } - /* 8 words(32 bytes) has been transferred */ - ptempbuff += SD_FIFOHALF_WORDS; - transbytes += SD_FIFOHALF_BYTES; - } - } - } - - /* whether some error occurs and return it */ - if(RESET != sdio_flag_get(SDIO_FLAG_DTCRCERR)) { - status = SD_DATA_CRC_ERROR; - sdio_flag_clear(SDIO_FLAG_DTCRCERR); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_DTTMOUT)) { - status = SD_DATA_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_DTTMOUT); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_TXURE)) { - status = SD_TX_UNDERRUN_ERROR; - sdio_flag_clear(SDIO_FLAG_TXURE); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_STBITE)) { - status = SD_START_BIT_ERROR; - sdio_flag_clear(SDIO_FLAG_STBITE); - return status; - } - } else if(SD_DMA_MODE == transmode) { - /* DMA mode */ - /* enable the SDIO corresponding interrupts and DMA */ - sdio_interrupt_enable(SDIO_INT_DTCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_TXURE | SDIO_INT_DTEND | SDIO_INT_STBITE); - dma_transfer_config(pwritebuffer, blocksize); - sdio_dma_enable(); - - uint32_t start = millis(); - while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF))) { - if((uint32_t)(millis() - start) > 1000) { - return SD_ERROR; - } - if (callback) - { - uint32_t complete = (blocksize - DMA_CHCNT(DMA1, DMA_CH3) * 4); - callback(complete); - } - } - while((0 == transend) && (SD_OK == transerror)) { - if (callback) - { - callback(blocksize); - } - } - - if(SD_OK != transerror) { - return transerror; - } - } else { - status = SD_PARAMETER_INVALID; - return status; - } - - /* clear the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - /* get the card state and wait the card is out of programming and receiving state */ - status = sd_card_state_get(&cardstate); - while((SD_OK == status) && ((SD_CARDSTATE_PROGRAMMING == cardstate) || (SD_CARDSTATE_RECEIVING == cardstate))) { - if (callback) - { - callback(blocksize); - } - status = sd_card_state_get(&cardstate); - } - return status; -} - -/*! - \brief write multiple blocks data to the specified address of a card - \param[in] pwritebuffer: a pointer that store multiple blocks data to be transferred - \param[in] writeaddr: the read data address - \param[in] blocksize: the data block size - \param[in] blocksnumber: number of blocks that will be written - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_t blocksize, uint32_t blocksnumber, sdio_callback_t callback) -{ - /* initialize the variables */ - sd_error_enum status = SD_OK; - uint8_t cardstate = 0; - uint32_t count = 0, align = 0, datablksize = SDIO_DATABLOCKSIZE_1BYTE, *ptempbuff = pwritebuffer; - uint32_t transbytes = 0, restwords = 0; - - if(NULL == pwritebuffer) { - status = SD_PARAMETER_INVALID; - return status; - } - - transerror = SD_OK; - transend = 0; - totalnumber_bytes = 0; - /* clear all DSM configuration */ - sdio_data_config(0, 0, SDIO_DATABLOCKSIZE_1BYTE); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOCARD); - sdio_dsm_disable(); - sdio_dma_disable(); - - /* check whether the card is locked */ - if(sdio_response_get(SDIO_RESPONSE0) & SD_CARDSTATE_LOCKED) { - status = SD_LOCK_UNLOCK_FAILED; - return status; - } - - /* blocksize is fixed in 512B for SDHC card */ - if(SDIO_HIGH_CAPACITY_SD_CARD == cardtype) { - blocksize = 512; - writeaddr /= 512; - } - - align = blocksize & (blocksize - 1); - if((blocksize > 0) && (blocksize <= 2048) && (0 == align)) { - datablksize = sd_datablocksize_get(blocksize); - /* send CMD16(SET_BLOCKLEN) to set the block length */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)blocksize, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SET_BLOCKLEN); - if(SD_OK != status) { - return status; - } - } else { - status = SD_PARAMETER_INVALID; - return status; - } - - /* send CMD13(SEND_STATUS), addressed card sends its status registers */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SEND_STATUS); - if(SD_OK != status) { - return status; - } - - if(blocksnumber >= 1) { - if(blocksnumber * blocksize > SD_MAX_DATA_LENGTH) { - status = SD_PARAMETER_INVALID; - return status; - } - - if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype) || - (SDIO_HIGH_CAPACITY_SD_CARD == cardtype)) { - /* send CMD55(APP_CMD) to indicate next command is application specific command */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_APP_CMD); - if(SD_OK != status) { - return status; - } - - /* send ACMD23(SET_WR_BLK_ERASE_COUNT) to set the number of write blocks to be preerased before writing */ - sdio_csm_disable(); - sdio_command_response_config(SD_APPCMD_SET_WR_BLK_ERASE_COUNT, blocksnumber, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_APPCMD_SET_WR_BLK_ERASE_COUNT); - if(SD_OK != status) { - return status; - } - } - /* send CMD25(WRITE_MULTIPLE_BLOCK) to continuously write blocks of data */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_WRITE_MULTIPLE_BLOCK, writeaddr, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_WRITE_MULTIPLE_BLOCK); - if(SD_OK != status) { - return status; - } - - stopcondition = 1; - totalnumber_bytes = blocksnumber * blocksize; - - /* configure the SDIO data transmission */ - sdio_data_config(SD_DATATIMEOUT, totalnumber_bytes, datablksize); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOCARD); - sdio_dsm_enable(); - - if(SD_POLLING_MODE == transmode) { - /* polling mode */ - while(!sdio_flag_get(SDIO_FLAG_DTCRCERR | SDIO_FLAG_DTTMOUT | SDIO_FLAG_TXURE | SDIO_FLAG_DTEND | SDIO_FLAG_STBITE)) { - if(RESET != sdio_flag_get(SDIO_FLAG_TFH)) { - /* at least 8 words can be written into the FIFO */ - if(!((totalnumber_bytes - transbytes) < SD_FIFOHALF_BYTES)) { - for(count = 0; count < SD_FIFOHALF_WORDS; count++) { - sdio_data_write(*(ptempbuff + count)); - } - /* 8 words(32 bytes) has been transferred */ - ptempbuff += SD_FIFOHALF_WORDS; - transbytes += SD_FIFOHALF_BYTES; - } else { - restwords = (totalnumber_bytes - transbytes) / 4 + (((totalnumber_bytes - transbytes) % 4 == 0) ? 0 : 1); - for(count = 0; count < restwords; count++) { - sdio_data_write(*ptempbuff); - ++ptempbuff; - transbytes += 4; - } - } - } - } - - /* whether some error occurs and return it */ - if(RESET != sdio_flag_get(SDIO_FLAG_DTCRCERR)) { - status = SD_DATA_CRC_ERROR; - sdio_flag_clear(SDIO_FLAG_DTCRCERR); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_DTTMOUT)) { - status = SD_DATA_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_DTTMOUT); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_TXURE)) { - status = SD_TX_UNDERRUN_ERROR; - sdio_flag_clear(SDIO_FLAG_TXURE); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_STBITE)) { - status = SD_START_BIT_ERROR; - sdio_flag_clear(SDIO_FLAG_STBITE); - return status; - } - - if(RESET != sdio_flag_get(SDIO_FLAG_DTEND)) { - if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype) || - (SDIO_HIGH_CAPACITY_SD_CARD == cardtype)) { - /* send CMD12(STOP_TRANSMISSION) to stop transmission */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_STOP_TRANSMISSION, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_STOP_TRANSMISSION); - if(SD_OK != status) { - return status; - } - } - } - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - } else if(SD_DMA_MODE == transmode) { - /* DMA mode */ - /* enable SDIO corresponding interrupts and DMA */ - sdio_interrupt_enable(SDIO_INT_DTCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_TXURE | SDIO_INT_DTEND | SDIO_INT_STBITE); - sdio_dma_enable(); - dma_transfer_config(pwritebuffer, totalnumber_bytes); - - uint32_t start = millis(); - while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF))) { - if((uint32_t)(millis() - start) > 1000) { - return SD_ERROR; - } - if (callback) - { - uint32_t complete = (totalnumber_bytes - DMA_CHCNT(DMA1, DMA_CH3) * 4); - callback(complete); - } - } - while((0 == transend) && (SD_OK == transerror)) { - if (callback) - { - callback(totalnumber_bytes); - } - } - if(SD_OK != transerror) { - return transerror; - } - } else { - status = SD_PARAMETER_INVALID; - return status; - } - } - - /* clear the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - /* get the card state and wait the card is out of programming and receiving state */ - status = sd_card_state_get(&cardstate); - while((SD_OK == status) && ((SD_CARDSTATE_PROGRAMMING == cardstate) || (SD_CARDSTATE_RECEIVING == cardstate))) { - if (callback) - { - callback(totalnumber_bytes); - } - status = sd_card_state_get(&cardstate); - } - return status; -} - -/*! - \brief erase a continuous area of a card - \param[in] startaddr: the start address - \param[in] endaddr: the end address - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_erase(uint64_t startaddr, uint64_t endaddr) -{ - /* initialize the variables */ - sd_error_enum status = SD_OK; - uint32_t count = 0, clkdiv = 0; - __IO uint32_t delay = 0; - uint8_t cardstate = 0, tempbyte = 0; - uint16_t tempccc = 0; - - /* get the card command classes from CSD */ - tempbyte = (uint8_t)((sd_csd[1] & SD_MASK_24_31BITS) >> 24); - tempccc = (uint16_t)((uint16_t)tempbyte << 4); - tempbyte = (uint8_t)((sd_csd[1] & SD_MASK_16_23BITS) >> 16); - tempccc |= (uint16_t)((uint16_t)(tempbyte & 0xF0) >> 4); - if(0 == (tempccc & SD_CCC_ERASE)) { - /* don't support the erase command */ - status = SD_FUNCTION_UNSUPPORTED; - return status; - } - clkdiv = (SDIO_CLKCTL & SDIO_CLKCTL_DIV); - clkdiv += ((SDIO_CLKCTL & SDIO_CLKCTL_DIV8) >> 31) * 256; - clkdiv += 2; - delay = 120000 / clkdiv; - - /* check whether the card is locked */ - if(sdio_response_get(SDIO_RESPONSE0) & SD_CARDSTATE_LOCKED) { - status = SD_LOCK_UNLOCK_FAILED; - return(status); - } - - /* blocksize is fixed in 512B for SDHC card */ - if(SDIO_HIGH_CAPACITY_SD_CARD == cardtype) { - startaddr /= 512; - endaddr /= 512; - } - - if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype) || - (SDIO_HIGH_CAPACITY_SD_CARD == cardtype)) { - /* send CMD32(ERASE_WR_BLK_START) to set the address of the first write block to be erased */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_ERASE_WR_BLK_START, startaddr, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_ERASE_WR_BLK_START); - if(SD_OK != status) { - return status; - } - - /* send CMD33(ERASE_WR_BLK_END) to set the address of the last write block of the continuous range to be erased */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_ERASE_WR_BLK_END, endaddr, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_ERASE_WR_BLK_END); - if(SD_OK != status) { - return status; - } - } - - /* send CMD38(ERASE) to set the address of the first write block to be erased */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_ERASE, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_ERASE); - if(SD_OK != status) { - return status; - } - /* loop until the counter is reach to the calculated time */ - for(count = 0; count < delay; count++) { - } - /* get the card state and wait the card is out of programming and receiving state */ - status = sd_card_state_get(&cardstate); - while((SD_OK == status) && ((SD_CARDSTATE_PROGRAMMING == cardstate) || (SD_CARDSTATE_RECEIVING == cardstate))) { - status = sd_card_state_get(&cardstate); - } - return status; -} - -/*! - \brief process all the interrupts which the corresponding flags are set - \param[in] none - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_interrupts_process(void) -{ - transerror = SD_OK; - if(RESET != sdio_interrupt_flag_get(SDIO_INT_FLAG_DTEND)) { - /* send CMD12 to stop data transfer in multiple blocks operation */ - if(1 == stopcondition) { - transerror = sd_transfer_stop(); - } else { - transerror = SD_OK; - } - sdio_interrupt_flag_clear(SDIO_INT_DTEND); - /* disable all the interrupts */ - sdio_interrupt_disable(SDIO_INT_DTCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_DTEND | SDIO_INT_STBITE | - SDIO_INT_TFH | SDIO_INT_RFH | SDIO_INT_TXURE | SDIO_INT_RXORE); - transend = 1; - number_bytes = 0; - return transerror; - } - - if(RESET != sdio_interrupt_flag_get(SDIO_INT_FLAG_DTCRCERR)) { - sdio_interrupt_flag_clear(SDIO_INT_DTCRCERR); - /* disable all the interrupts */ - sdio_interrupt_disable(SDIO_INT_DTCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_DTEND | SDIO_INT_STBITE | - SDIO_INT_TFH | SDIO_INT_RFH | SDIO_INT_TXURE | SDIO_INT_RXORE); - number_bytes = 0; - transerror = SD_DATA_CRC_ERROR; - return transerror; - } - - if(RESET != sdio_interrupt_flag_get(SDIO_INT_FLAG_DTTMOUT)) { - sdio_interrupt_flag_clear(SDIO_INT_DTTMOUT); - /* disable all the interrupts */ - sdio_interrupt_disable(SDIO_INT_DTCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_DTEND | SDIO_INT_STBITE | - SDIO_INT_TFH | SDIO_INT_RFH | SDIO_INT_TXURE | SDIO_INT_RXORE); - number_bytes = 0; - transerror = SD_DATA_TIMEOUT; - return transerror; - } - - if(RESET != sdio_interrupt_flag_get(SDIO_INT_FLAG_STBITE)) { - sdio_interrupt_flag_clear(SDIO_INT_STBITE); - /* disable all the interrupts */ - sdio_interrupt_disable(SDIO_INT_DTCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_DTEND | SDIO_INT_STBITE | - SDIO_INT_TFH | SDIO_INT_RFH | SDIO_INT_TXURE | SDIO_INT_RXORE); - number_bytes = 0; - transerror = SD_START_BIT_ERROR; - return transerror; - } - - if(RESET != sdio_interrupt_flag_get(SDIO_INT_FLAG_TXURE)) { - sdio_interrupt_flag_clear(SDIO_INT_TXURE); - /* disable all the interrupts */ - sdio_interrupt_disable(SDIO_INT_DTCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_DTEND | SDIO_INT_STBITE | - SDIO_INT_TFH | SDIO_INT_RFH | SDIO_INT_TXURE | SDIO_INT_RXORE); - number_bytes = 0; - transerror = SD_TX_UNDERRUN_ERROR; - return transerror; - } - - if(RESET != sdio_interrupt_flag_get(SDIO_INT_FLAG_RXORE)) { - sdio_interrupt_flag_clear(SDIO_INT_RXORE); - /* disable all the interrupts */ - sdio_interrupt_disable(SDIO_INT_DTCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_DTEND | SDIO_INT_STBITE | - SDIO_INT_TFH | SDIO_INT_RFH | SDIO_INT_TXURE | SDIO_INT_RXORE); - number_bytes = 0; - transerror = SD_RX_OVERRUN_ERROR; - return transerror; - } - return transerror; -} - -/*! - \brief select or deselect a card - \param[in] cardrca: the RCA of a card - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_card_select_deselect(uint16_t cardrca) -{ - sd_error_enum status = SD_OK; - /* send CMD7(SELECT/DESELECT_CARD) to select or deselect the card */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SELECT_DESELECT_CARD, (uint32_t)(cardrca << SD_RCA_SHIFT), SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - - status = r1_error_check(SD_CMD_SELECT_DESELECT_CARD); - return status; -} - -/*! - \brief get the card status - \param[in] none - \param[out] pcardstatus: a pointer that store card status - \retval sd_error_enum -*/ -sd_error_enum sd_cardstatus_get(uint32_t *pcardstatus) -{ - sd_error_enum status = SD_OK; - if(NULL == pcardstatus) { - status = SD_PARAMETER_INVALID; - return status; - } - - /* send CMD13(SEND_STATUS), addressed card sends its status register */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SEND_STATUS); - if(SD_OK != status) { - return status; - } - - *pcardstatus = sdio_response_get(SDIO_RESPONSE0); - return status; -} - -/*! - \brief get the SD card status - \param[in] none - \param[out] psdstatus: a pointer that store SD card status - \retval sd_error_enum -*/ -sd_error_enum sd_sdstatus_get(uint32_t *psdstatus) -{ - sd_error_enum status = SD_OK; - uint32_t count = 0; - - /* check whether the card is locked */ - if(sdio_response_get(SDIO_RESPONSE0) & SD_CARDSTATE_LOCKED) { - status = SD_LOCK_UNLOCK_FAILED; - return(status); - } - - /* send CMD16(SET_BLOCKLEN) to set the block length */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)64, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SET_BLOCKLEN); - if(SD_OK != status) { - return status; - } - - /* send CMD55(APP_CMD) to indicate next command is application specific command */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_APP_CMD); - if(SD_OK != status) { - return status; - } - - /* configure the SDIO data transmission */ - sdio_data_config(SD_DATATIMEOUT, (uint32_t)64, SDIO_DATABLOCKSIZE_64BYTES); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOSDIO); - sdio_dsm_enable(); - - /* send ACMD13(SD_STATUS) to get the SD status */ - sdio_csm_disable(); - sdio_command_response_config(SD_APPCMD_SD_STATUS, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_APPCMD_SD_STATUS); - if(SD_OK != status) { - return status; - } - - while(!sdio_flag_get(SDIO_FLAG_DTCRCERR | SDIO_FLAG_DTTMOUT | SDIO_FLAG_RXORE | SDIO_FLAG_DTBLKEND | SDIO_FLAG_STBITE)) { - if(RESET != sdio_flag_get(SDIO_FLAG_RFH)) { - for(count = 0; count < SD_FIFOHALF_WORDS; count++) { - *(psdstatus + count) = sdio_data_read(); - } - psdstatus += SD_FIFOHALF_WORDS; - } - } - - /* whether some error occurs and return it */ - if(RESET != sdio_flag_get(SDIO_FLAG_DTCRCERR)) { - status = SD_DATA_CRC_ERROR; - sdio_flag_clear(SDIO_FLAG_DTCRCERR); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_DTTMOUT)) { - status = SD_DATA_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_DTTMOUT); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_RXORE)) { - status = SD_RX_OVERRUN_ERROR; - sdio_flag_clear(SDIO_FLAG_RXORE); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_STBITE)) { - status = SD_START_BIT_ERROR; - sdio_flag_clear(SDIO_FLAG_STBITE); - return status; - } - while(RESET != sdio_flag_get(SDIO_FLAG_RXDTVAL)) { - *psdstatus = sdio_data_read(); - ++psdstatus; - } - - /* clear the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - psdstatus -= 16; - for(count = 0; count < 16; count++) { - psdstatus[count] = ((psdstatus[count] & SD_MASK_0_7BITS) << 24) | ((psdstatus[count] & SD_MASK_8_15BITS) << 8) | - ((psdstatus[count] & SD_MASK_16_23BITS) >> 8) | ((psdstatus[count] & SD_MASK_24_31BITS) >> 24); - } - return status; -} - -/*! - \brief stop an ongoing data transfer - \param[in] none - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_transfer_stop(void) -{ - sd_error_enum status = SD_OK; - /* send CMD12(STOP_TRANSMISSION) to stop transmission */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_STOP_TRANSMISSION, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_STOP_TRANSMISSION); - return status; -} - -/*! - \brief lock or unlock a card - \param[in] lockstate: the lock state - \arg SD_LOCK: lock the SD card - \arg SD_UNLOCK: unlock the SD card - \param[out] none - \retval sd_error_enum -*/ -sd_error_enum sd_lock_unlock(uint8_t lockstate) -{ - sd_error_enum status = SD_OK; - uint8_t cardstate = 0, tempbyte = 0; - uint32_t pwd1 = 0, pwd2 = 0, response = 0; - __IO uint32_t timeout = 0; - uint16_t tempccc = 0; - - /* get the card command classes from CSD */ - tempbyte = (uint8_t)((sd_csd[1] & SD_MASK_24_31BITS) >> 24); - tempccc = (uint16_t)((uint16_t)tempbyte << 4); - tempbyte = (uint8_t)((sd_csd[1] & SD_MASK_16_23BITS) >> 16); - tempccc |= (uint16_t)((uint16_t)(tempbyte & 0xF0) >> 4); - - if(0 == (tempccc & SD_CCC_LOCK_CARD)) { - /* don't support the lock command */ - status = SD_FUNCTION_UNSUPPORTED; - return status; - } - /* password pattern */ - pwd1 = (0x01020600 | lockstate); - pwd2 = 0x03040506; - - /* clear all DSM configuration */ - sdio_data_config(0, 0, SDIO_DATABLOCKSIZE_1BYTE); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOCARD); - sdio_dsm_disable(); - sdio_dma_disable(); - - /* send CMD16(SET_BLOCKLEN) to set the block length */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)8, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SET_BLOCKLEN); - if(SD_OK != status) { - return status; - } - - /* send CMD13(SEND_STATUS), addressed card sends its status register */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SEND_STATUS); - if(SD_OK != status) { - return status; - } - - response = sdio_response_get(SDIO_RESPONSE0); - timeout = 100000; - while((0 == (response & SD_R1_READY_FOR_DATA)) && (timeout > 0)) { - /* continue to send CMD13 to polling the state of card until buffer empty or timeout */ - --timeout; - /* send CMD13(SEND_STATUS), addressed card sends its status registers */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SEND_STATUS); - if(SD_OK != status) { - return status; - } - response = sdio_response_get(SDIO_RESPONSE0); - } - if(0 == timeout) { - return SD_ERROR; - } - - /* send CMD42(LOCK_UNLOCK) to set/reset the password or lock/unlock the card */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_LOCK_UNLOCK, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_LOCK_UNLOCK); - if(SD_OK != status) { - return status; - } - - response = sdio_response_get(SDIO_RESPONSE0); - - /* configure the SDIO data transmission */ - sdio_data_config(SD_DATATIMEOUT, (uint32_t)8, SDIO_DATABLOCKSIZE_8BYTES); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOCARD); - sdio_dsm_enable(); - - /* write password pattern */ - sdio_data_write(pwd1); - sdio_data_write(pwd2); - - /* whether some error occurs and return it */ - if(RESET != sdio_flag_get(SDIO_FLAG_DTCRCERR)) { - status = SD_DATA_CRC_ERROR; - sdio_flag_clear(SDIO_FLAG_DTCRCERR); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_DTTMOUT)) { - status = SD_DATA_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_DTTMOUT); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_TXURE)) { - status = SD_TX_UNDERRUN_ERROR; - sdio_flag_clear(SDIO_FLAG_TXURE); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_STBITE)) { - status = SD_START_BIT_ERROR; - sdio_flag_clear(SDIO_FLAG_STBITE); - return status; - } - - /* clear the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - /* get the card state and wait the card is out of programming and receiving state */ - status = sd_card_state_get(&cardstate); - while((SD_OK == status) && ((SD_CARDSTATE_PROGRAMMING == cardstate) || (SD_CARDSTATE_RECEIVING == cardstate))) { - status = sd_card_state_get(&cardstate); - } - return status; -} - -/*! - \brief get the data transfer state - \param[in] none - \param[out] none - \retval sd_error_enum -*/ -sd_transfer_state_enum sd_transfer_state_get(void) -{ - sd_transfer_state_enum transtate = SD_NO_TRANSFER; - if(RESET != sdio_flag_get(SDIO_FLAG_TXRUN | SDIO_FLAG_RXRUN)) { - transtate = SD_TRANSFER_IN_PROGRESS; - } - return transtate; -} - -/*! - \brief get SD card capacity - \param[in] none - \param[out] none - \retval capacity of the card(KB) -*/ -uint32_t sd_card_capacity_get(void) -{ - uint8_t tempbyte = 0, devicesize_mult = 0, readblklen = 0; - uint32_t capacity = 0, devicesize = 0; - if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype)) { - /* calculate the c_size(device size) */ - tempbyte = (uint8_t)((sd_csd[1] & SD_MASK_8_15BITS) >> 8); - devicesize = (uint32_t)((uint32_t)(tempbyte & 0x03) << 10); - tempbyte = (uint8_t)(sd_csd[1] & SD_MASK_0_7BITS); - devicesize |= (uint32_t)((uint32_t)tempbyte << 2); - tempbyte = (uint8_t)((sd_csd[2] & SD_MASK_24_31BITS) >> 24); - devicesize |= (uint32_t)((uint32_t)(tempbyte & 0xC0) >> 6); - - /* calculate the c_size_mult(device size multiplier) */ - tempbyte = (uint8_t)((sd_csd[2] & SD_MASK_16_23BITS) >> 16); - devicesize_mult = (tempbyte & 0x03) << 1; - tempbyte = (uint8_t)((sd_csd[2] & SD_MASK_8_15BITS) >> 8); - devicesize_mult |= (tempbyte & 0x80) >> 7; - - /* calculate the read_bl_len */ - tempbyte = (uint8_t)((sd_csd[1] & SD_MASK_16_23BITS) >> 16); - readblklen = tempbyte & 0x0F; - - /* capacity = BLOCKNR*BLOCK_LEN, BLOCKNR = (C_SIZE+1)*MULT, MULT = 2^(C_SIZE_MULT+2), BLOCK_LEN = 2^READ_BL_LEN */ - capacity = (devicesize + 1) * (1 << (devicesize_mult + 2)); - capacity *= (1 << readblklen); - - /* change the unit of capacity to KByte */ - capacity /= 1024; - } else if(SDIO_HIGH_CAPACITY_SD_CARD == cardtype) { - /* calculate the c_size */ - tempbyte = (uint8_t)(sd_csd[1] & SD_MASK_0_7BITS); - devicesize = (uint32_t)((uint32_t)(tempbyte & 0x3F) << 16); - tempbyte = (uint8_t)((sd_csd[2] & SD_MASK_24_31BITS) >> 24); - devicesize |= (uint32_t)((uint32_t)tempbyte << 8); - tempbyte = (uint8_t)((sd_csd[2] & SD_MASK_16_23BITS) >> 16); - devicesize |= (uint32_t)tempbyte; - - /* capacity = (c_size+1)*512KByte */ - capacity = (devicesize + 1) * 512; - } - return capacity; -} - -sd_error_enum sd_card_information_get_short(sdio_card_type_enum *card_type, uint16_t *card_rca) -{ - *card_type = cardtype; - *card_rca = sd_rca; - return SD_OK; -} - -/*! - \brief get the detailed information of the SD card based on received CID and CSD - \param[in] none - \param[out] pcardinfo: a pointer that store the detailed card information - \retval sd_error_enum -*/ -sd_error_enum sd_card_information_get(sd_card_info_struct *pcardinfo) -{ - sd_error_enum status = SD_OK; - uint8_t tempbyte = 0; - - if(NULL == pcardinfo) { - status = SD_PARAMETER_INVALID; - return status; - } - - /* store the card type and RCA */ - pcardinfo->card_type = cardtype; - pcardinfo->card_rca = sd_rca; - - /* CID byte 0 */ - tempbyte = (uint8_t)((sd_cid[0] & SD_MASK_24_31BITS) >> 24); - pcardinfo->card_cid.mid = tempbyte; - - /* CID byte 1 */ - tempbyte = (uint8_t)((sd_cid[0] & SD_MASK_16_23BITS) >> 16); - pcardinfo->card_cid.oid = (uint16_t)((uint16_t)tempbyte << 8); - - /* CID byte 2 */ - tempbyte = (uint8_t)((sd_cid[0] & SD_MASK_8_15BITS) >> 8); - pcardinfo->card_cid.oid |= (uint16_t)tempbyte; - - /* CID byte 3 */ - tempbyte = (uint8_t)(sd_cid[0] & SD_MASK_0_7BITS); - pcardinfo->card_cid.pnm0 = (uint32_t)((uint32_t)tempbyte << 24); - - /* CID byte 4 */ - tempbyte = (uint8_t)((sd_cid[1] & SD_MASK_24_31BITS) >> 24); - pcardinfo->card_cid.pnm0 |= (uint32_t)((uint32_t)tempbyte << 16); - - /* CID byte 5 */ - tempbyte = (uint8_t)((sd_cid[1] & SD_MASK_16_23BITS) >> 16); - pcardinfo->card_cid.pnm0 |= (uint32_t)((uint32_t)tempbyte << 8); - - /* CID byte 6 */ - tempbyte = (uint8_t)((sd_cid[1] & SD_MASK_8_15BITS) >> 8); - pcardinfo->card_cid.pnm0 |= (uint32_t)(tempbyte); - - /* CID byte 7 */ - tempbyte = (uint8_t)(sd_cid[1] & SD_MASK_0_7BITS); - pcardinfo->card_cid.pnm1 = tempbyte; - - /* CID byte 8 */ - tempbyte = (uint8_t)((sd_cid[2] & SD_MASK_24_31BITS) >> 24); - pcardinfo->card_cid.prv = tempbyte; - - /* CID byte 9 */ - tempbyte = (uint8_t)((sd_cid[2] & SD_MASK_16_23BITS) >> 16); - pcardinfo->card_cid.psn = (uint32_t)((uint32_t)tempbyte << 24); - - /* CID byte 10 */ - tempbyte = (uint8_t)((sd_cid[2] & SD_MASK_8_15BITS) >> 8); - pcardinfo->card_cid.psn |= (uint32_t)((uint32_t)tempbyte << 16); - - /* CID byte 11 */ - tempbyte = (uint8_t)(sd_cid[2] & SD_MASK_0_7BITS); - pcardinfo->card_cid.psn |= (uint32_t)tempbyte; - - /* CID byte 12 */ - tempbyte = (uint8_t)((sd_cid[3] & SD_MASK_24_31BITS) >> 24); - pcardinfo->card_cid.psn |= (uint32_t)tempbyte; - - /* CID byte 13 */ - tempbyte = (uint8_t)((sd_cid[3] & SD_MASK_16_23BITS) >> 16); - pcardinfo->card_cid.mdt = (uint16_t)((uint16_t)(tempbyte & 0x0F) << 8); - - /* CID byte 14 */ - tempbyte = (uint8_t)((sd_cid[3] & SD_MASK_8_15BITS) >> 8); - pcardinfo->card_cid.mdt |= (uint16_t)tempbyte; - - /* CID byte 15 */ - tempbyte = (uint8_t)(sd_cid[3] & SD_MASK_0_7BITS); - pcardinfo->card_cid.cid_crc = (tempbyte & 0xFE) >> 1; - - /* CSD byte 0 */ - tempbyte = (uint8_t)((sd_csd[0] & SD_MASK_24_31BITS) >> 24); - pcardinfo->card_csd.csd_struct = (tempbyte & 0xC0) >> 6; - - /* CSD byte 1 */ - tempbyte = (uint8_t)((sd_csd[0] & SD_MASK_16_23BITS) >> 16); - pcardinfo->card_csd.taac = tempbyte; - - /* CSD byte 2 */ - tempbyte = (uint8_t)((sd_csd[0] & SD_MASK_8_15BITS) >> 8); - pcardinfo->card_csd.nsac = tempbyte; - - /* CSD byte 3 */ - tempbyte = (uint8_t)(sd_csd[0] & SD_MASK_0_7BITS); - pcardinfo->card_csd.tran_speed = tempbyte; - - /* CSD byte 4 */ - tempbyte = (uint8_t)((sd_csd[1] & SD_MASK_24_31BITS) >> 24); - pcardinfo->card_csd.ccc = (uint16_t)((uint16_t)tempbyte << 4); - - /* CSD byte 5 */ - tempbyte = (uint8_t)((sd_csd[1] & SD_MASK_16_23BITS) >> 16); - pcardinfo->card_csd.ccc |= (uint16_t)((uint16_t)(tempbyte & 0xF0) >> 4); - pcardinfo->card_csd.read_bl_len = tempbyte & 0x0F; - - /* CSD byte 6 */ - tempbyte = (uint8_t)((sd_csd[1] & SD_MASK_8_15BITS) >> 8); - pcardinfo->card_csd.read_bl_partial = (tempbyte & 0x80) >> 7; - pcardinfo->card_csd.write_blk_misalign = (tempbyte & 0x40) >> 6; - pcardinfo->card_csd.read_blk_misalign = (tempbyte & 0x20) >> 5; - pcardinfo->card_csd.dsp_imp = (tempbyte & 0x10) >> 4; - - if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype)) { - /* card is SDSC card, CSD version 1.0 */ - pcardinfo->card_csd.c_size = (uint32_t)((uint32_t)(tempbyte & 0x03) << 10); - - /* CSD byte 7 */ - tempbyte = (uint8_t)(sd_csd[1] & SD_MASK_0_7BITS); - pcardinfo->card_csd.c_size |= (uint32_t)((uint32_t)tempbyte << 2); - - /* CSD byte 8 */ - tempbyte = (uint8_t)((sd_csd[2] & SD_MASK_24_31BITS) >> 24); - pcardinfo->card_csd.c_size |= (uint32_t)((uint32_t)(tempbyte & 0xC0) >> 6); - pcardinfo->card_csd.vdd_r_curr_min = (tempbyte & 0x38) >> 3; - pcardinfo->card_csd.vdd_r_curr_max = tempbyte & 0x07; - - /* CSD byte 9 */ - tempbyte = (uint8_t)((sd_csd[2] & SD_MASK_16_23BITS) >> 16); - pcardinfo->card_csd.vdd_w_curr_min = (tempbyte & 0xE0) >> 5; - pcardinfo->card_csd.vdd_w_curr_max = (tempbyte & 0x1C) >> 2; - pcardinfo->card_csd.c_size_mult = (tempbyte & 0x03) << 1; - - /* CSD byte 10 */ - tempbyte = (uint8_t)((sd_csd[2] & SD_MASK_8_15BITS) >> 8); - pcardinfo->card_csd.c_size_mult |= (tempbyte & 0x80) >> 7; - - /* calculate the card block size and capacity */ - pcardinfo->card_blocksize = 1 << (pcardinfo->card_csd.read_bl_len); - pcardinfo->card_capacity = pcardinfo->card_csd.c_size + 1; - pcardinfo->card_capacity *= (1 << (pcardinfo->card_csd.c_size_mult + 2)); - pcardinfo->card_capacity *= pcardinfo->card_blocksize; - } else if(SDIO_HIGH_CAPACITY_SD_CARD == cardtype) { - /* card is SDHC card, CSD version 2.0 */ - /* CSD byte 7 */ - tempbyte = (uint8_t)(sd_csd[1] & SD_MASK_0_7BITS); - pcardinfo->card_csd.c_size = (uint32_t)((uint32_t)(tempbyte & 0x3F) << 16); - - /* CSD byte 8 */ - tempbyte = (uint8_t)((sd_csd[2] & SD_MASK_24_31BITS) >> 24); - pcardinfo->card_csd.c_size |= (uint32_t)((uint32_t)tempbyte << 8); - - /* CSD byte 9 */ - tempbyte = (uint8_t)((sd_csd[2] & SD_MASK_16_23BITS) >> 16); - pcardinfo->card_csd.c_size |= (uint32_t)tempbyte; - - /* calculate the card block size and capacity */ - pcardinfo->card_blocksize = 512; - pcardinfo->card_capacity = (pcardinfo->card_csd.c_size + 1) * 512 * 1024; - } - - pcardinfo->card_csd.erase_blk_en = (tempbyte & 0x40) >> 6; - pcardinfo->card_csd.sector_size = (tempbyte & 0x3F) << 1; - - /* CSD byte 11 */ - tempbyte = (uint8_t)(sd_csd[2] & SD_MASK_0_7BITS); - pcardinfo->card_csd.sector_size |= (tempbyte & 0x80) >> 7; - pcardinfo->card_csd.wp_grp_size = (tempbyte & 0x7F); - - /* CSD byte 12 */ - tempbyte = (uint8_t)((sd_csd[3] & SD_MASK_24_31BITS) >> 24); - pcardinfo->card_csd.wp_grp_enable = (tempbyte & 0x80) >> 7; - pcardinfo->card_csd.r2w_factor = (tempbyte & 0x1C) >> 2; - pcardinfo->card_csd.write_bl_len = (tempbyte & 0x03) << 2; - - /* CSD byte 13 */ - tempbyte = (uint8_t)((sd_csd[3] & SD_MASK_16_23BITS) >> 16); - pcardinfo->card_csd.write_bl_len |= (tempbyte & 0xC0) >> 6; - pcardinfo->card_csd.write_bl_partial = (tempbyte & 0x20) >> 5; - - /* CSD byte 14 */ - tempbyte = (uint8_t)((sd_csd[3] & SD_MASK_8_15BITS) >> 8); - pcardinfo->card_csd.file_format_grp = (tempbyte & 0x80) >> 7; - pcardinfo->card_csd.copy_flag = (tempbyte & 0x40) >> 6; - pcardinfo->card_csd.perm_write_protect = (tempbyte & 0x20) >> 5; - pcardinfo->card_csd.tmp_write_protect = (tempbyte & 0x10) >> 4; - pcardinfo->card_csd.file_format = (tempbyte & 0x0C) >> 2; - - /* CSD byte 15 */ - tempbyte = (uint8_t)(sd_csd[3] & SD_MASK_0_7BITS); - pcardinfo->card_csd.csd_crc = (tempbyte & 0xFE) >> 1; - - return status; -} - -void sd_cid_get(uint8_t *cid) -{ - // SdFat expects the data in big endian format. - for (int i = 0; i < 16; i++) - { - cid[i] = (sd_cid[i / 4] >> (24 - (i % 4) * 8)) & 0xFF; - } -} - -void sd_csd_get(uint8_t *csd) -{ - for (int i = 0; i < 16; i++) - { - csd[i] = (sd_csd[i / 4] >> (24 - (i % 4) * 8)) & 0xFF; - } -} - -/*! - \brief check if the command sent error occurs - \param[in] none - \param[out] none - \retval sd_error_enum -*/ -static sd_error_enum cmdsent_error_check(void) -{ - sd_error_enum status = SD_OK; - __IO uint32_t timeout = 100000; - /* check command sent flag */ - while((RESET == sdio_flag_get(SDIO_FLAG_CMDSEND)) && (timeout > 0)) { - --timeout; - } - /* command response is timeout */ - if(0 == timeout) { - status = SD_CMD_RESP_TIMEOUT; - return status; - } - /* if the command is sent, clear the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - return status; -} - -/*! - \brief check if error type for R1 response - \param[in] resp: content of response - \param[out] none - \retval sd_error_enum -*/ -static sd_error_enum r1_error_type_check(uint32_t resp) -{ - sd_error_enum status = SD_ERROR; - /* check which error occurs */ - if(resp & SD_R1_OUT_OF_RANGE) { - status = SD_OUT_OF_RANGE; - } else if(resp & SD_R1_ADDRESS_ERROR) { - status = SD_ADDRESS_ERROR; - } else if(resp & SD_R1_BLOCK_LEN_ERROR) { - status = SD_BLOCK_LEN_ERROR; - } else if(resp & SD_R1_ERASE_SEQ_ERROR) { - status = SD_ERASE_SEQ_ERROR; - } else if(resp & SD_R1_ERASE_PARAM) { - status = SD_ERASE_PARAM; - } else if(resp & SD_R1_WP_VIOLATION) { - status = SD_WP_VIOLATION; - } else if(resp & SD_R1_LOCK_UNLOCK_FAILED) { - status = SD_LOCK_UNLOCK_FAILED; - } else if(resp & SD_R1_COM_CRC_ERROR) { - status = SD_COM_CRC_ERROR; - } else if(resp & SD_R1_ILLEGAL_COMMAND) { - status = SD_ILLEGAL_COMMAND; - } else if(resp & SD_R1_CARD_ECC_FAILED) { - status = SD_CARD_ECC_FAILED; - } else if(resp & SD_R1_CC_ERROR) { - status = SD_CC_ERROR; - } else if(resp & SD_R1_GENERAL_UNKNOWN_ERROR) { - status = SD_GENERAL_UNKNOWN_ERROR; - } else if(resp & SD_R1_CSD_OVERWRITE) { - status = SD_CSD_OVERWRITE; - } else if(resp & SD_R1_WP_ERASE_SKIP) { - status = SD_WP_ERASE_SKIP; - } else if(resp & SD_R1_CARD_ECC_DISABLED) { - status = SD_CARD_ECC_DISABLED; - } else if(resp & SD_R1_ERASE_RESET) { - status = SD_ERASE_RESET; - } else if(resp & SD_R1_AKE_SEQ_ERROR) { - status = SD_AKE_SEQ_ERROR; - } - return status; -} - -/*! - \brief check if error occurs for R1 response - \param[in] cmdindex: the index of command - \param[out] none - \retval sd_error_enum -*/ -static sd_error_enum r1_error_check(uint8_t cmdindex) -{ - sd_error_enum status = SD_OK; - uint32_t reg_status = 0, resp_r1 = 0; - __IO uint32_t timeout = 100000; - - /* store the content of SDIO_STAT */ - reg_status = SDIO_STAT; - while(!(reg_status & (SDIO_FLAG_CCRCERR | SDIO_FLAG_CMDTMOUT | SDIO_FLAG_CMDRECV)) && (timeout > 0)) { - reg_status = SDIO_STAT; - --timeout; - } - /* check whether an error or timeout occurs or command response received */ - if(reg_status & SDIO_FLAG_CCRCERR) { - status = SD_CMD_CRC_ERROR; - sdio_flag_clear(SDIO_FLAG_CCRCERR); - return status; - } else if((reg_status & SDIO_FLAG_CMDTMOUT) || (0 == timeout)) { - status = SD_CMD_RESP_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_CMDTMOUT); - return status; - } - - /* check whether the last response command index is the desired one */ - if(sdio_command_index_get() != cmdindex) { - status = SD_ILLEGAL_COMMAND; - return status; - } - /* clear all the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - /* get the SDIO response register 0 for checking */ - resp_r1 = sdio_response_get(SDIO_RESPONSE0); - if(SD_ALLZERO == (resp_r1 & SD_R1_ERROR_BITS)) { - /* no error occurs, return SD_OK */ - status = SD_OK; - return status; - } - - /* if some error occurs, return the error type */ - status = r1_error_type_check(resp_r1); - return status; -} - -/*! - \brief check if error occurs for R2 response - \param[in] none - \param[out] none - \retval sd_error_enum -*/ -static sd_error_enum r2_error_check(void) -{ - sd_error_enum status = SD_OK; - uint32_t reg_status = 0; - __IO uint32_t timeout = 100000; - - /* store the content of SDIO_STAT */ - reg_status = SDIO_STAT; - while(!(reg_status & (SDIO_FLAG_CCRCERR | SDIO_FLAG_CMDTMOUT | SDIO_FLAG_CMDRECV)) && (timeout > 0)) { - reg_status = SDIO_STAT; - --timeout; - } - /* check whether an error or timeout occurs or command response received */ - if(reg_status & SDIO_FLAG_CCRCERR) { - status = SD_CMD_CRC_ERROR; - sdio_flag_clear(SDIO_FLAG_CCRCERR); - return status; - } else if((reg_status & SDIO_FLAG_CMDTMOUT) || (0 == timeout)) { - status = SD_CMD_RESP_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_CMDTMOUT); - return status; - } - /* clear all the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - return status; -} - -/*! - \brief check if error occurs for R3 response - \param[in] none - \param[out] none - \retval sd_error_enum -*/ -static sd_error_enum r3_error_check(void) -{ - sd_error_enum status = SD_OK; - uint32_t reg_status = 0; - __IO uint32_t timeout = 100000; - - /* store the content of SDIO_STAT */ - reg_status = SDIO_STAT; - while(!(reg_status & (SDIO_FLAG_CCRCERR | SDIO_FLAG_CMDTMOUT | SDIO_FLAG_CMDRECV)) && (timeout > 0)) { - reg_status = SDIO_STAT; - --timeout; - } - if((reg_status & SDIO_FLAG_CMDTMOUT) || (0 == timeout)) { - status = SD_CMD_RESP_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_CMDTMOUT); - return status; - } - /* clear all the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - return status; -} - -/*! - \brief check if error occurs for R6 response - \param[in] cmdindex: the index of command - \param[out] prca: a pointer that store the RCA of card - \retval sd_error_enum -*/ -static sd_error_enum r6_error_check(uint8_t cmdindex, uint16_t *prca) -{ - sd_error_enum status = SD_OK; - uint32_t reg_status = 0, response = 0; - __IO uint32_t timeout = 100000; - - /* store the content of SDIO_STAT */ - reg_status = SDIO_STAT; - while(!(reg_status & (SDIO_FLAG_CCRCERR | SDIO_FLAG_CMDTMOUT | SDIO_FLAG_CMDRECV)) && (timeout > 0)) { - reg_status = SDIO_STAT; - --timeout; - } - /* check whether an error or timeout occurs or command response received */ - if(reg_status & SDIO_FLAG_CCRCERR) { - status = SD_CMD_CRC_ERROR; - sdio_flag_clear(SDIO_FLAG_CCRCERR); - return status; - } else if((reg_status & SDIO_FLAG_CMDTMOUT) || (0 == timeout)) { - status = SD_CMD_RESP_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_CMDTMOUT); - return status; - } - - /* check whether the last response command index is the desired one */ - if(sdio_command_index_get() != cmdindex) { - status = SD_ILLEGAL_COMMAND; - return status; - } - /* clear all the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - /* get the SDIO response register 0 for checking */ - response = sdio_response_get(SDIO_RESPONSE0); - - if(SD_ALLZERO == (response & (SD_R6_COM_CRC_ERROR | SD_R6_ILLEGAL_COMMAND | SD_R6_GENERAL_UNKNOWN_ERROR))) { - *prca = (uint16_t)(response >> 16); - return status; - } - /* if some error occurs, return the error type */ - if(response & SD_R6_COM_CRC_ERROR) { - status = SD_COM_CRC_ERROR; - } else if(response & SD_R6_ILLEGAL_COMMAND) { - status = SD_ILLEGAL_COMMAND; - } else if(response & SD_R6_GENERAL_UNKNOWN_ERROR) { - status = SD_GENERAL_UNKNOWN_ERROR; - } - return status; -} - -/*! - \brief check if error occurs for R7 response - \param[in] none - \param[out] none - \retval sd_error_enum -*/ -static sd_error_enum r7_error_check(void) -{ - sd_error_enum status = SD_ERROR; - uint32_t reg_status = 0; - __IO uint32_t timeout = 100000; - - /* store the content of SDIO_STAT */ - reg_status = SDIO_STAT; - while(!(reg_status & (SDIO_FLAG_CCRCERR | SDIO_FLAG_CMDTMOUT | SDIO_FLAG_CMDRECV)) && (timeout > 0)) { - reg_status = SDIO_STAT; - --timeout; - } - - /* check the flags */ - if((reg_status & SDIO_FLAG_CMDTMOUT) || (0 == timeout)) { - status = SD_CMD_RESP_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_CMDTMOUT); - return status; - } - if(reg_status & SDIO_FLAG_CMDRECV) { - status = SD_OK; - sdio_flag_clear(SDIO_FLAG_CMDRECV); - return status; - } - return status; -} - -/*! - \brief get the state which the card is in - \param[in] none - \param[out] pcardstate: a pointer that store the card state - \arg SD_CARDSTATE_IDLE: card is in idle state - \arg SD_CARDSTATE_READY: card is in ready state - \arg SD_CARDSTATE_IDENTIFICAT: card is in identification state - \arg SD_CARDSTATE_STANDBY: card is in standby state - \arg SD_CARDSTATE_TRANSFER: card is in transfer state - \arg SD_CARDSTATE_DATA: card is in data state - \arg SD_CARDSTATE_RECEIVING: card is in receiving state - \arg SD_CARDSTATE_PROGRAMMING: card is in programming state - \arg SD_CARDSTATE_DISCONNECT: card is in disconnect state - \arg SD_CARDSTATE_LOCKED: card is in locked state - \retval sd_error_enum -*/ -static sd_error_enum sd_card_state_get(uint8_t *pcardstate) -{ - sd_error_enum status = SD_OK; - __IO uint32_t reg_status = 0, response = 0; - __IO uint32_t timeout = 100000; - - /* send CMD13(SEND_STATUS), addressed card sends its status register */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - - /* store the content of SDIO_STAT */ - reg_status = SDIO_STAT; - while(!(reg_status & (SDIO_FLAG_CCRCERR | SDIO_FLAG_CMDTMOUT | SDIO_FLAG_CMDRECV)) && (timeout > 0)) { - reg_status = SDIO_STAT; - --timeout; - } - /* check whether an error or timeout occurs or command response received */ - if(reg_status & SDIO_FLAG_CCRCERR) { - status = SD_CMD_CRC_ERROR; - sdio_flag_clear(SDIO_FLAG_CCRCERR); - return status; - } else if((reg_status & SDIO_FLAG_CMDTMOUT) || (0 == timeout)) { - status = SD_CMD_RESP_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_CMDTMOUT); - return status; - } - - /* command response received, store the response command index */ - reg_status = (uint32_t)sdio_command_index_get(); - if(reg_status != (uint32_t)SD_CMD_SEND_STATUS) { - status = SD_ILLEGAL_COMMAND; - return status; - } - /* clear all the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - /* get the SDIO response register 0 for checking */ - response = sdio_response_get(SDIO_RESPONSE0); - *pcardstate = (uint8_t)((response >> 9) & 0x0000000F); - - if(SD_ALLZERO == (response & SD_R1_ERROR_BITS)) { - /* no error occurs, return SD_OK */ - status = SD_OK; - return status; - } - - /* if some error occurs, return the error type */ - status = r1_error_type_check(response); - return status; -} - -/*! - \brief configure the bus width mode - \param[in] buswidth: the bus width - \arg SD_BUS_WIDTH_1BIT: 1-bit bus width - \arg SD_BUS_WIDTH_4BIT: 4-bit bus width - \param[out] none - \retval sd_error_enum -*/ -static sd_error_enum sd_bus_width_config(uint32_t buswidth) -{ - sd_error_enum status = SD_OK; - /* check whether the card is locked */ - if(sdio_response_get(SDIO_RESPONSE0) & SD_CARDSTATE_LOCKED) { - status = SD_LOCK_UNLOCK_FAILED; - return status; - } - /* get the SCR register */ - status = sd_scr_get(sd_rca, sd_scr); - if(SD_OK != status) { - return status; - } - - if(SD_BUS_WIDTH_1BIT == buswidth) { - if(SD_ALLZERO != (sd_scr[1] & buswidth)) { - /* send CMD55(APP_CMD) to indicate next command is application specific command */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_APP_CMD); - if(SD_OK != status) { - return status; - } - - /* send ACMD6(SET_BUS_WIDTH) to define the data bus width */ - sdio_csm_disable(); - sdio_command_response_config(SD_APPCMD_SET_BUS_WIDTH, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_APPCMD_SET_BUS_WIDTH); - if(SD_OK != status) { - return status; - } - } else { - status = SD_OPERATION_IMPROPER; - } - return status; - } else if(SD_BUS_WIDTH_4BIT == buswidth) { - if(SD_ALLZERO != (sd_scr[1] & buswidth)) { - /* send CMD55(APP_CMD) to indicate next command is application specific command */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_APP_CMD); - if(SD_OK != status) { - return status; - } - - /* send ACMD6(SET_BUS_WIDTH) to define the data bus width */ - sdio_csm_disable(); - sdio_command_response_config(SD_APPCMD_SET_BUS_WIDTH, (uint32_t)0x2, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_APPCMD_SET_BUS_WIDTH); - if(SD_OK != status) { - return status; - } - } else { - status = SD_OPERATION_IMPROPER; - } - return status; - } else { - status = SD_PARAMETER_INVALID; - return status; - } -} - -/*! - \brief get the SCR of corresponding card - \param[in] rca: RCA of a card - \param[out] pscr: a pointer that store the SCR content - \retval sd_error_enum -*/ -static sd_error_enum sd_scr_get(uint16_t rca, uint32_t *pscr) -{ - sd_error_enum status = SD_OK; - uint32_t temp_scr[2] = {0, 0}, idx_scr = 0; - /* send CMD16(SET_BLOCKLEN) to set block length */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)8, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_SET_BLOCKLEN); - if(SD_OK != status) { - return status; - } - - /* send CMD55(APP_CMD) to indicate next command is application specific command */ - sdio_csm_disable(); - sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_CMD_APP_CMD); - if(SD_OK != status) { - return status; - } - - /* configure SDIO data */ - sdio_data_config(SD_DATATIMEOUT, (uint32_t)8, SDIO_DATABLOCKSIZE_8BYTES); - sdio_data_transfer_config(SDIO_TRANSMODE_BLOCK, SDIO_TRANSDIRECTION_TOSDIO); - sdio_dsm_enable(); - - /* send ACMD51(SEND_SCR) to read the SD configuration register */ - sdio_csm_disable(); - sdio_command_response_config(SD_APPCMD_SEND_SCR, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT); - sdio_wait_type_set(SDIO_WAITTYPE_NO); - sdio_csm_enable(); - /* check if some error occurs */ - status = r1_error_check(SD_APPCMD_SEND_SCR); - if(SD_OK != status) { - return status; - } - - /* store the received SCR */ - while(!sdio_flag_get(SDIO_FLAG_DTCRCERR | SDIO_FLAG_DTTMOUT | SDIO_FLAG_RXORE | SDIO_FLAG_DTBLKEND | SDIO_FLAG_STBITE)) { - if(RESET != sdio_flag_get(SDIO_FLAG_RXDTVAL)) { - *(temp_scr + idx_scr) = sdio_data_read(); - ++idx_scr; - } - } - - /* check whether some error occurs */ - if(RESET != sdio_flag_get(SDIO_FLAG_DTCRCERR)) { - status = SD_DATA_CRC_ERROR; - sdio_flag_clear(SDIO_FLAG_DTCRCERR); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_DTTMOUT)) { - status = SD_DATA_TIMEOUT; - sdio_flag_clear(SDIO_FLAG_DTTMOUT); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_RXORE)) { - status = SD_RX_OVERRUN_ERROR; - sdio_flag_clear(SDIO_FLAG_RXORE); - return status; - } else if(RESET != sdio_flag_get(SDIO_FLAG_STBITE)) { - status = SD_START_BIT_ERROR; - sdio_flag_clear(SDIO_FLAG_STBITE); - return status; - } - - /* clear all the SDIO_INTC flags */ - sdio_flag_clear(SDIO_MASK_INTC_FLAGS); - /* readjust the temp SCR value */ - *(pscr) = ((temp_scr[1] & SD_MASK_0_7BITS) << 24) | ((temp_scr[1] & SD_MASK_8_15BITS) << 8) | - ((temp_scr[1] & SD_MASK_16_23BITS) >> 8) | ((temp_scr[1] & SD_MASK_24_31BITS) >> 24); - *(pscr + 1) = ((temp_scr[0] & SD_MASK_0_7BITS) << 24) | ((temp_scr[0] & SD_MASK_8_15BITS) << 8) | - ((temp_scr[0] & SD_MASK_16_23BITS) >> 8) | ((temp_scr[0] & SD_MASK_24_31BITS) >> 24); - return status; -} - -/*! - \brief get the data block size - \param[in] bytesnumber: the number of bytes - \param[out] none - \retval data block size - \arg SDIO_DATABLOCKSIZE_1BYTE: block size = 1 byte - \arg SDIO_DATABLOCKSIZE_2BYTES: block size = 2 bytes - \arg SDIO_DATABLOCKSIZE_4BYTES: block size = 4 bytes - \arg SDIO_DATABLOCKSIZE_8BYTES: block size = 8 bytes - \arg SDIO_DATABLOCKSIZE_16BYTES: block size = 16 bytes - \arg SDIO_DATABLOCKSIZE_32BYTES: block size = 32 bytes - \arg SDIO_DATABLOCKSIZE_64BYTES: block size = 64 bytes - \arg SDIO_DATABLOCKSIZE_128BYTES: block size = 128 bytes - \arg SDIO_DATABLOCKSIZE_256BYTES: block size = 256 bytes - \arg SDIO_DATABLOCKSIZE_512BYTES: block size = 512 bytes - \arg SDIO_DATABLOCKSIZE_1024BYTES: block size = 1024 bytes - \arg SDIO_DATABLOCKSIZE_2048BYTES: block size = 2048 bytes - \arg SDIO_DATABLOCKSIZE_4096BYTES: block size = 4096 bytes - \arg SDIO_DATABLOCKSIZE_8192BYTES: block size = 8192 bytes - \arg SDIO_DATABLOCKSIZE_16384BYTES: block size = 16384 bytes -*/ -static uint32_t sd_datablocksize_get(uint16_t bytesnumber) -{ - uint8_t exp_val = 0; - /* calculate the exponent of 2 */ - while(1 != bytesnumber) { - bytesnumber >>= 1; - ++exp_val; - } - return DATACTL_BLKSZ(exp_val); -} - -/*! - \brief configure the DMA1 channel 3 for transferring data - \param[in] srcbuf: a pointer point to a buffer which will be transferred - \param[in] bufsize: the size of buffer(not used in flow controller is peripheral) - \param[out] none - \retval none -*/ -static void dma_transfer_config(uint32_t *srcbuf, uint32_t bufsize) -{ - dma_parameter_struct dma_struct; - /* clear all the interrupt flags */ - dma_flag_clear(DMA1, DMA_CH3, DMA_FLAG_G); - dma_flag_clear(DMA1, DMA_CH3, DMA_FLAG_FTF); - dma_flag_clear(DMA1, DMA_CH3, DMA_FLAG_HTF); - dma_flag_clear(DMA1, DMA_CH3, DMA_FLAG_ERR); - dma_channel_disable(DMA1, DMA_CH3); - dma_deinit(DMA1, DMA_CH3); - - /* configure the DMA1 channel3 */ - dma_struct.periph_addr = (uint32_t)SDIO_FIFO_ADDR; - dma_struct.memory_addr = (uint32_t)srcbuf; - dma_struct.direction = DMA_MEMORY_TO_PERIPHERAL; - dma_struct.number = bufsize / 4; - dma_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; - dma_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; - dma_struct.periph_width = DMA_PERIPHERAL_WIDTH_32BIT; - dma_struct.memory_width = DMA_MEMORY_WIDTH_32BIT; - dma_struct.priority = DMA_PRIORITY_MEDIUM; - dma_init(DMA1, DMA_CH3, &dma_struct); - - dma_circulation_disable(DMA1, DMA_CH3); - dma_channel_enable(DMA1, DMA_CH3); -} - -/*! - \brief configure the DMA1 channel 3 for receiving data - \param[in] dstbuf: a pointer point to a buffer which will receive data - \param[in] bufsize: the size of buffer(not used in flow controller is peripheral) - \param[out] none - \retval none -*/ -static void dma_receive_config(uint32_t *dstbuf, uint32_t bufsize) -{ - dma_parameter_struct dma_struct; - /* clear all the interrupt flags */ - dma_flag_clear(DMA1, DMA_CH3, DMA_FLAG_G); - dma_flag_clear(DMA1, DMA_CH3, DMA_FLAG_FTF); - dma_flag_clear(DMA1, DMA_CH3, DMA_FLAG_HTF); - dma_flag_clear(DMA1, DMA_CH3, DMA_FLAG_ERR); - dma_channel_disable(DMA1, DMA_CH3); - dma_deinit(DMA1, DMA_CH3); - - /* configure the DMA1 channel 3 */ - dma_struct.periph_addr = (uint32_t)SDIO_FIFO_ADDR; - dma_struct.memory_addr = (uint32_t)dstbuf; - dma_struct.direction = DMA_PERIPHERAL_TO_MEMORY; - dma_struct.number = bufsize / 4; - dma_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; - dma_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; - dma_struct.periph_width = DMA_PERIPHERAL_WIDTH_32BIT; - dma_struct.memory_width = DMA_MEMORY_WIDTH_32BIT; - dma_struct.priority = DMA_PRIORITY_ULTRA_HIGH; - dma_init(DMA1, DMA_CH3, &dma_struct); - - dma_circulation_disable(DMA1, DMA_CH3); - dma_channel_enable(DMA1, DMA_CH3); -} diff --git a/lib/BlueSCSI_platform_GD32F205/gd32_sdio_sdcard.h b/lib/BlueSCSI_platform_GD32F205/gd32_sdio_sdcard.h deleted file mode 100644 index 67966db5..00000000 --- a/lib/BlueSCSI_platform_GD32F205/gd32_sdio_sdcard.h +++ /dev/null @@ -1,271 +0,0 @@ -/*! - \file sdcard.h - \brief the header file of SD card driver - - \version 2015-07-15, V1.0.0, firmware for GD32F20x - \version 2017-06-05, V2.0.0, firmware for GD32F20x - \version 2018-10-31, V2.1.0, firmware for GD32F20x - \version 2020-09-30, V2.2.0, firmware for GD32F20x - \version 2021-07-30, V2.3.0, firmware for GD32F20x -*/ - -/* - Copyright (c) 2021, GigaDevice Semiconductor Inc. - - Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - 3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -#ifndef SDCARD_H -#define SDCARD_H - -#include "gd32f20x.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* SD memory card bus commands index */ -#define SD_CMD_GO_IDLE_STATE ((uint8_t)0) /* CMD0, GO_IDLE_STATE */ -#define SD_CMD_ALL_SEND_CID ((uint8_t)2) /* CMD2, ALL_SEND_CID */ -#define SD_CMD_SEND_RELATIVE_ADDR ((uint8_t)3) /* CMD3, SEND_RELATIVE_ADDR */ -#define SD_CMD_SET_DSR ((uint8_t)4) /* CMD4, SET_DSR */ -#define SD_CMD_SWITCH_FUNC ((uint8_t)6) /* CMD6, SWITCH_FUNC */ -#define SD_CMD_SELECT_DESELECT_CARD ((uint8_t)7) /* CMD7, SELECT_DESELECT_CARD */ -#define SD_CMD_SEND_IF_COND ((uint8_t)8) /* CMD8, SEND_IF_COND */ -#define SD_CMD_SEND_CSD ((uint8_t)9) /* CMD9, SEND_CSD */ -#define SD_CMD_SEND_CID ((uint8_t)10) /* CMD10, SEND_CID */ -#define SD_CMD_STOP_TRANSMISSION ((uint8_t)12) /* CMD12, STOP_TRANSMISSION */ -#define SD_CMD_SEND_STATUS ((uint8_t)13) /* CMD13, SEND_STATUS */ -#define SD_CMD_GO_INACTIVE_STATE ((uint8_t)15) /* CMD15, GO_INACTIVE_STATE */ -#define SD_CMD_SET_BLOCKLEN ((uint8_t)16) /* CMD16, SET_BLOCKLEN */ -#define SD_CMD_READ_SINGLE_BLOCK ((uint8_t)17) /* CMD17, READ_SINGLE_BLOCK */ -#define SD_CMD_READ_MULTIPLE_BLOCK ((uint8_t)18) /* CMD18, READ_MULTIPLE_BLOCK */ -#define SD_CMD_WRITE_BLOCK ((uint8_t)24) /* CMD24, WRITE_BLOCK */ -#define SD_CMD_WRITE_MULTIPLE_BLOCK ((uint8_t)25) /* CMD25, WRITE_MULTIPLE_BLOCK */ -#define SD_CMD_PROG_CSD ((uint8_t)27) /* CMD27, PROG_CSD */ -#define SD_CMD_SET_WRITE_PROT ((uint8_t)28) /* CMD28, SET_WRITE_PROT */ -#define SD_CMD_CLR_WRITE_PROT ((uint8_t)29) /* CMD29, CLR_WRITE_PROT */ -#define SD_CMD_SEND_WRITE_PROT ((uint8_t)30) /* CMD30, SEND_WRITE_PROT */ -#define SD_CMD_ERASE_WR_BLK_START ((uint8_t)32) /* CMD32, ERASE_WR_BLK_START */ -#define SD_CMD_ERASE_WR_BLK_END ((uint8_t)33) /* CMD33, ERASE_WR_BLK_END */ -#define SD_CMD_ERASE ((uint8_t)38) /* CMD38, ERASE */ -#define SD_CMD_LOCK_UNLOCK ((uint8_t)42) /* CMD42, LOCK_UNLOCK */ -#define SD_CMD_APP_CMD ((uint8_t)55) /* CMD55, APP_CMD */ -#define SD_CMD_GEN_CMD ((uint8_t)56) /* CMD56, GEN_CMD */ - -/* SD memory card application specific commands index */ -#define SD_APPCMD_SET_BUS_WIDTH ((uint8_t)6) /* ACMD6, SET_BUS_WIDTH */ -#define SD_APPCMD_SD_STATUS ((uint8_t)13) /* ACMD13, SD_STATUS */ -#define SD_APPCMD_SEND_NUM_WR_BLOCKS ((uint8_t)22) /* ACMD22, SEND_NUM_WR_BLOCKS */ -#define SD_APPCMD_SET_WR_BLK_ERASE_COUNT ((uint8_t)23) /* ACMD23, SET_WR_BLK_ERASE_COUNT */ -#define SD_APPCMD_SD_SEND_OP_COND ((uint8_t)41) /* ACMD41, SD_SEND_OP_COND */ -#define SD_APPCMD_SET_CLR_CARD_DETECT ((uint8_t)42) /* ACMD42, SET_CLR_CARD_DETECT */ -#define SD_APPCMD_SEND_SCR ((uint8_t)51) /* ACMD51, SEND_SCR */ - -/* card command class */ -#define SD_CCC_SWITCH BIT(10) /* class 10 */ -#define SD_CCC_IO_MODE BIT(9) /* class 9 */ -#define SD_CCC_APPLICATION_SPECIFIC BIT(8) /* class 8 */ -#define SD_CCC_LOCK_CARD BIT(7) /* class 7 */ -#define SD_CCC_WRITE_PROTECTION BIT(6) /* class 6 */ -#define SD_CCC_ERASE BIT(5) /* class 5 */ -#define SD_CCC_BLOCK_WRITE BIT(4) /* class 4 */ -#define SD_CCC_BLOCK_READ BIT(2) /* class 2 */ -#define SD_CCC_BASIC BIT(0) /* class 0 */ - -/* SD card data transmission mode */ -#define SD_DMA_MODE ((uint32_t)0x00000000) /* DMA mode */ -#define SD_POLLING_MODE ((uint32_t)0x00000001) /* polling mode */ - -/* lock unlock status */ -#define SD_LOCK ((uint8_t)0x05) /* lock the SD card */ -#define SD_UNLOCK ((uint8_t)0x02) /* unlock the SD card */ - -/* supported memory cards types */ -typedef enum { - SDIO_STD_CAPACITY_SD_CARD_V1_1 = 0, /* standard capacity SD card version 1.1 */ - SDIO_STD_CAPACITY_SD_CARD_V2_0, /* standard capacity SD card version 2.0 */ - SDIO_HIGH_CAPACITY_SD_CARD, /* high capacity SD card */ - SDIO_SECURE_DIGITAL_IO_CARD, /* secure digital IO card */ - SDIO_SECURE_DIGITAL_IO_COMBO_CARD, /* secure digital IO combo card */ - SDIO_MULTIMEDIA_CARD, /* multimedia card */ - SDIO_HIGH_CAPACITY_MULTIMEDIA_CARD, /* high capacity multimedia card */ - SDIO_HIGH_SPEED_MULTIMEDIA_CARD /* high speed multimedia card */ -} sdio_card_type_enum; - -/* card identification (CID) register */ -typedef struct { - __IO uint8_t mid; /* manufacturer ID */ - __IO uint16_t oid; /* OEM/application ID */ - __IO uint32_t pnm0; /* product name */ - __IO uint8_t pnm1; /* product name */ - __IO uint8_t prv; /* product revision */ - __IO uint32_t psn; /* product serial number */ - __IO uint16_t mdt; /* manufacturing date */ - __IO uint8_t cid_crc; /* CID CRC7 checksum */ -} sd_cid_struct; - -/* CSD register (CSD version 1.0 and 2.0) */ -typedef struct { - __IO uint8_t csd_struct; /* CSD struct */ - __IO uint8_t taac; /* data read access-time */ - __IO uint8_t nsac; /* data read access-time in CLK cycles */ - __IO uint8_t tran_speed; /* max. data transfer rate */ - __IO uint16_t ccc; /* card command classes */ - __IO uint8_t read_bl_len; /* max. read data block length */ - __IO uint8_t read_bl_partial; /* partial blocks for read allowed */ - __IO uint8_t write_blk_misalign; /* write block misalignment */ - __IO uint8_t read_blk_misalign; /* read block misalignment */ - __IO uint8_t dsp_imp; /* DSR implemented */ - __IO uint32_t c_size; /* device size, 12 bits in CSD version 1.0, 22 bits in CSD version 2.0 */ - __IO uint8_t vdd_r_curr_min; /* max. read current @VDD min, CSD version 1.0 */ - __IO uint8_t vdd_r_curr_max; /* max. read current @VDD max, CSD version 1.0 */ - __IO uint8_t vdd_w_curr_min; /* max. write current @VDD min, CSD version 1.0 */ - __IO uint8_t vdd_w_curr_max; /* max. write current @VDD max, CSD version 1.0 */ - __IO uint8_t c_size_mult; /* device size multiplier, CSD version 1.0 */ - __IO uint8_t erase_blk_en; /* erase single block enable */ - __IO uint8_t sector_size; /* erase sector size */ - __IO uint8_t wp_grp_size; /* write protect group size */ - __IO uint8_t wp_grp_enable; /* write protect group enable */ - __IO uint8_t r2w_factor; /* write speed factor */ - __IO uint8_t write_bl_len; /* max. write data block length */ - __IO uint8_t write_bl_partial; /* partial blocks for write allowed */ - __IO uint8_t file_format_grp; /* file format group */ - __IO uint8_t copy_flag; /* copy flag (OTP) */ - __IO uint8_t perm_write_protect; /* permanent write protection */ - __IO uint8_t tmp_write_protect; /* temporary write protection */ - __IO uint8_t file_format; /* file format */ - __IO uint8_t csd_crc; /* CSD CRC checksum */ -} sd_csd_struct; - -/* information of card */ -typedef struct { - sd_cid_struct card_cid; /* CID register */ - sd_csd_struct card_csd; /* CSD register */ - sdio_card_type_enum card_type; /* card tpye */ - uint32_t card_capacity; /* card capacity */ - uint32_t card_blocksize; /* card block size */ - uint16_t card_rca; /* card relative card address */ -} sd_card_info_struct; - -/* SD error flags */ -typedef enum { - SD_OUT_OF_RANGE = 0, /* command's argument was out of range */ - SD_ADDRESS_ERROR, /* misaligned address which did not match the block length */ - SD_BLOCK_LEN_ERROR, /* transferred block length is not allowed for the card or the number of transferred bytes does not match the block length */ - SD_ERASE_SEQ_ERROR, /* an error in the sequence of erase command occurs */ - SD_ERASE_PARAM, /* an invalid selection of write-blocks for erase occurred */ - SD_WP_VIOLATION, /* attempt to program a write protect block or permanent write protected card */ - SD_LOCK_UNLOCK_FAILED, /* sequence or password error has been detected in lock/unlock card command */ - SD_COM_CRC_ERROR, /* CRC check of the previous command failed */ - SD_ILLEGAL_COMMAND, /* command not legal for the card state */ - SD_CARD_ECC_FAILED, /* card internal ECC was applied but failed to correct the data */ - SD_CC_ERROR, /* internal card controller error */ - SD_GENERAL_UNKNOWN_ERROR, /* general or unknown error occurred during the operation */ - SD_CSD_OVERWRITE, /* read only section of the CSD does not match the card content or an attempt to reverse the copy or permanent WP bits was made */ - SD_WP_ERASE_SKIP, /* only partial address space was erased or the temporary or permanent write protected card was erased */ - SD_CARD_ECC_DISABLED, /* command has been executed without using internal ECC */ - SD_ERASE_RESET, /* erase sequence was cleared before executing because an out of erase sequence command was received */ - SD_AKE_SEQ_ERROR, /* error in the sequence of the authentication process */ - - SD_CMD_CRC_ERROR, /* command response received (CRC check failed) */ - SD_DATA_CRC_ERROR, /* data block sent/received (CRC check failed) */ - SD_CMD_RESP_TIMEOUT, /* command response timeout */ - SD_DATA_TIMEOUT, /* data timeout */ - SD_TX_UNDERRUN_ERROR, /* transmit FIFO underrun error occurs */ - SD_RX_OVERRUN_ERROR, /* received FIFO overrun error occurs */ - SD_START_BIT_ERROR, /* start bit error in the bus */ - - SD_VOLTRANGE_INVALID, /* the voltage range is invalid */ - SD_PARAMETER_INVALID, /* the parameter is invalid */ - SD_OPERATION_IMPROPER, /* the operation is improper */ - SD_FUNCTION_UNSUPPORTED, /* the function is unsupported */ - SD_ERROR, /* an error occurred */ - SD_OK /* no error occurred */ -} sd_error_enum; - -typedef enum { - SD_NO_TRANSFER = 0, /* no data transfer is acting */ - SD_TRANSFER_IN_PROGRESS /* data transfer is in progress */ -} sd_transfer_state_enum; - -extern uint32_t sd_scr[2]; /* SD card SCR */ - -/* function declarations */ -/* initialize the SD card and make it in standby state */ -sd_error_enum sd_init(void); -/* initialize the card and get CID and CSD of the card */ -sd_error_enum sd_card_init(void); -/* configure the clock and the work voltage, and get the card type */ -sd_error_enum sd_power_on(void); -/* close the power of SDIO */ -sd_error_enum sd_power_off(void); - -/* configure the bus mode */ -sd_error_enum sd_bus_mode_config(uint32_t busmode); -/* configure the mode of transmission */ -sd_error_enum sd_transfer_mode_config(uint32_t txmode); - -typedef void (*sdio_callback_t)(uint32_t bytes_done); -/* read a block data into a buffer from the specified address of a card */ -sd_error_enum sd_block_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t blocksize, sdio_callback_t callback); -/* read multiple blocks data into a buffer from the specified address of a card */ -sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t blocksize, uint32_t blocksnumber, sdio_callback_t callback); -/* write a block data to the specified address of a card */ -sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_t blocksize, sdio_callback_t callback); -/* write multiple blocks data to the specified address of a card */ -sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_t blocksize, uint32_t blocksnumber, sdio_callback_t callback); -/* erase a continuous area of a card */ -sd_error_enum sd_erase(uint64_t startaddr, uint64_t endaddr); -/* process all the interrupts which the corresponding flags are set */ -sd_error_enum sd_interrupts_process(void); - -/* select or deselect a card */ -sd_error_enum sd_card_select_deselect(uint16_t cardrca); -/* get the card status */ -sd_error_enum sd_cardstatus_get(uint32_t *pcardstatus); -/* get the SD card status */ -sd_error_enum sd_sdstatus_get(uint32_t *psdstatus); -/* stop an ongoing data transfer */ -sd_error_enum sd_transfer_stop(void); -/* lock or unlock a card */ -sd_error_enum sd_lock_unlock(uint8_t lockstate); - -/* get the data transfer state */ -sd_transfer_state_enum sd_transfer_state_get(void); -/* get SD card capacity(KB) */ -uint32_t sd_card_capacity_get(void); -/* get the detailed information of the SD card based on received CID and CSD */ -sd_error_enum sd_card_information_get(sd_card_info_struct *pcardinfo); -sd_error_enum sd_card_information_get_short(sdio_card_type_enum *card_type, uint16_t *card_rca); - -/* Get card information in raw format */ -void sd_cid_get(uint8_t *cid); -void sd_csd_get(uint8_t *csd); - -#ifdef __cplusplus -} -#endif - -#endif /* SDCARD_H */ diff --git a/lib/BlueSCSI_platform_GD32F205/greenpak.cpp b/lib/BlueSCSI_platform_GD32F205/greenpak.cpp deleted file mode 100644 index 2f24e319..00000000 --- a/lib/BlueSCSI_platform_GD32F205/greenpak.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// I2C communication with GreenPAK. -// This uses bitbanging for I2C so that internal GPIO pull-up can be used -// and to avoid the bugs that are present in STM32F2 I2C peripheral, -// it is uncertain if the same bugs apply to GD32F2. - -#include "BlueSCSI_platform.h" -#include "BlueSCSI_log.h" -#include "greenpak.h" -#include "greenpak_fw.h" - -#ifndef GREENPAK_I2C_PORT - -bool greenpak_write(uint16_t regaddr, const uint8_t *data, int length) { return false; } -bool greenpak_read(uint16_t regaddr, uint8_t *data, int length) { return false; } -bool greenpak_load_firmware() { return false; } -bool greenpak_is_ready() { return false; } - -#else - -bool g_greenpak_is_ready; - -// SCL is driven as push-pull, SDA is driven as IPU / OUT_OD -#define I2C_SCL_HI() GPIO_BOP(GREENPAK_I2C_PORT) = GREENPAK_I2C_SCL -#define I2C_SCL_LO() GPIO_BC(GREENPAK_I2C_PORT) = GREENPAK_I2C_SCL -#define I2C_SDA_HI() gpio_init(GREENPAK_I2C_PORT, GPIO_MODE_IPU, 0, GREENPAK_I2C_SDA) -#define I2C_SDA_LO() gpio_init(GREENPAK_I2C_PORT, GPIO_MODE_OUT_OD, GPIO_OSPEED_2MHZ, GREENPAK_I2C_SDA), GPIO_BC(GREENPAK_I2C_PORT) = GREENPAK_I2C_SDA -#define I2C_SDA_READ() (GPIO_ISTAT(GREENPAK_I2C_PORT) & GREENPAK_I2C_SDA) -#define I2C_DELAY() delay_ns(10000); - -static void greenpak_gpio_init() -{ - gpio_bit_set(GREENPAK_I2C_PORT, GREENPAK_I2C_SCL | GREENPAK_I2C_SDA); - gpio_init(GREENPAK_I2C_PORT, GPIO_MODE_IPU, 0, GREENPAK_I2C_SDA); - gpio_init(GREENPAK_I2C_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, GREENPAK_I2C_SCL); - - // Data bits used for communication - uint32_t greenpak_io = GREENPAK_PLD_IO1 | GREENPAK_PLD_IO2 | GREENPAK_PLD_IO3; - gpio_bit_reset(SCSI_OUT_PORT, greenpak_io); - gpio_init(SCSI_OUT_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, greenpak_io); -} - -static void i2c_writebit(bool bit) -{ - if (bit) - I2C_SDA_HI(); - else - I2C_SDA_LO(); - - I2C_DELAY(); - I2C_SCL_HI(); - I2C_DELAY(); - I2C_SCL_LO(); -} - -static bool i2c_readbit() -{ - I2C_SDA_HI(); // Pull-up - I2C_DELAY(); - I2C_SCL_HI(); - I2C_DELAY(); - bool result = I2C_SDA_READ(); - I2C_SCL_LO(); - return result; -} - -// Write byte to I2C bus, return ACK bit status -static bool i2c_writebyte(uint8_t byte) -{ - for (int i = 0; i < 8; i++) - { - i2c_writebit(byte & (0x80 >> i)); - } - return !i2c_readbit(); -} - -// Read byte from I2C bus -static uint8_t i2c_readbyte(bool ack) -{ - uint8_t result = 0; - for (int i = 0; i < 8; i++) - { - result |= i2c_readbit() << (7 - i); - } - - i2c_writebyte(!ack); - return result; -} - -static bool i2c_start(uint8_t device_addr) -{ - // Initial signal state - I2C_SCL_HI(); - I2C_SDA_HI(); - I2C_DELAY(); - - // Start condition - I2C_SDA_LO(); - I2C_DELAY(); - - I2C_SCL_LO(); - I2C_DELAY(); - - // Device address - return i2c_writebyte(device_addr); -} - -static void i2c_stop() -{ - I2C_SDA_LO(); - I2C_DELAY(); - I2C_SCL_HI(); - I2C_DELAY(); - I2C_SDA_HI(); - I2C_DELAY(); -} - -bool greenpak_write(uint16_t regaddr, const uint8_t *data, int length) -{ - bool status = true; - uint16_t blockaddr = regaddr >> 8; - status &= i2c_start(GREENPAK_I2C_ADDR | (blockaddr << 1)); - status &= i2c_writebyte(regaddr & 0xFF); - - for (int i = 0; i < length; i++) - { - status &= i2c_writebyte(data[i]); - } - - i2c_stop(); - return status; -} - -bool greenpak_read(uint16_t regaddr, uint8_t *data, int length) -{ - bool status = true; - uint16_t blockaddr = (regaddr >> 8) & 7; - status &= i2c_start(GREENPAK_I2C_ADDR | (blockaddr << 1)); - status &= i2c_writebyte(regaddr & 0xFF); - - status &= i2c_start(GREENPAK_I2C_ADDR | (blockaddr << 1) | 1); - - for (int i = 0; i < length; i++) - { - data[i] = i2c_readbyte(i < length - 1); - } - - i2c_stop(); - return status; -} - -bool greenpak_load_firmware() -{ - uint8_t dummy; - greenpak_gpio_init(); - - if (!greenpak_read(0, &dummy, 1)) - { - bluelog("Optional GreenPAK not detected"); - return false; - } - else - { - bluelog("Optional GreenPAK detected, loading firmware"); - } - - if (!greenpak_write(0, g_greenpak_fw, sizeof(g_greenpak_fw))) - { - bluelog("GreenPAK firmware loading failed"); - return false; - } - else - { - bluelog("GreenPAK firmware successfully loaded"); - LED_ON(); - delay(10); - LED_OFF(); - delay(100); - g_greenpak_is_ready = true; - return true; - } -} - -bool greenpak_is_ready() -{ - return g_greenpak_is_ready; -} - -#endif diff --git a/lib/BlueSCSI_platform_GD32F205/greenpak.h b/lib/BlueSCSI_platform_GD32F205/greenpak.h deleted file mode 100644 index 91da6c67..00000000 --- a/lib/BlueSCSI_platform_GD32F205/greenpak.h +++ /dev/null @@ -1,13 +0,0 @@ -// External GreenPAK SLG46824 programmable logic can optionally be used to -// accelerate SCSI communications. This module contains code to load firmware -// to the GreenPAK through I2C. - -#pragma once - -#include - -bool greenpak_write(uint16_t regaddr, const uint8_t *data, int length); -bool greenpak_read(uint16_t regaddr, uint8_t *data, int length); - -bool greenpak_load_firmware(); -bool greenpak_is_ready(); \ No newline at end of file diff --git a/lib/BlueSCSI_platform_GD32F205/greenpak_fw.h b/lib/BlueSCSI_platform_GD32F205/greenpak_fw.h deleted file mode 100644 index 78ef8f58..00000000 --- a/lib/BlueSCSI_platform_GD32F205/greenpak_fw.h +++ /dev/null @@ -1,24 +0,0 @@ -const uint8_t g_greenpak_fw[] = { - 0xc4, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xc2, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x08, - 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x70, 0x00, 0x30, 0x20, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, - 0x30, 0x00, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x14, 0x22, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, 0x14, 0x20, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x02, 0x01, - 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, - 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xa5 -}; diff --git a/lib/BlueSCSI_platform_GD32F205/scsi2sd_time.h b/lib/BlueSCSI_platform_GD32F205/scsi2sd_time.h deleted file mode 100644 index f6cb5794..00000000 --- a/lib/BlueSCSI_platform_GD32F205/scsi2sd_time.h +++ /dev/null @@ -1,14 +0,0 @@ -// Timing functions for SCSI2SD. -// This file is derived from time.h in SCSI2SD-V6. - -#pragma once - -#include -#include "BlueSCSI_platform.h" - -#define s2s_getTime_ms() millis() -#define s2s_elapsedTime_ms(since) ((uint32_t)(millis() - (since))) -#define s2s_delay_ms(x) delay_ns(x * 1000000) -#define s2s_delay_us(x) delay_ns(x * 1000) -#define s2s_delay_ns(x) delay_ns(x) - diff --git a/lib/BlueSCSI_platform_GD32F205/scsiPhy.cpp b/lib/BlueSCSI_platform_GD32F205/scsiPhy.cpp deleted file mode 100644 index 59ab47a2..00000000 --- a/lib/BlueSCSI_platform_GD32F205/scsiPhy.cpp +++ /dev/null @@ -1,600 +0,0 @@ -// Implements the low level interface to SCSI bus -// Partially derived from scsiPhy.c from SCSI2SD-V6 - -#include "scsiPhy.h" -#include "BlueSCSI_platform.h" -#include "scsi_accel_asm.h" -#include "scsi_accel_dma.h" -#include "scsi_accel_greenpak.h" -#include "scsi_accel_sync.h" -#include "BlueSCSI_log.h" -#include "BlueSCSI_log_trace.h" -#include "BlueSCSI_config.h" -#include - -#include -extern "C" { -#include -#include -} - -// Acceleration mode in use -static enum { - PHY_MODE_BEST_AVAILABLE = 0, - PHY_MODE_PIO = 1, - PHY_MODE_DMA_TIMER = 2, - PHY_MODE_GREENPAK_PIO = 3, - PHY_MODE_GREENPAK_DMA = 4 -} g_scsi_phy_mode; -static const char *g_scsi_phy_mode_names[] = { - "Unknown", "PIO", "DMA_TIMER", "GREENPAK_PIO", "GREENPAK_DMA" -}; - -// State of polling write request -static struct { - const uint8_t *data; - uint32_t count; - bool use_sync_mode; -} g_scsi_writereq; - -static void init_irqs(); - -/***********************/ -/* SCSI status signals */ -/***********************/ - -extern "C" bool scsiStatusATN() -{ - return SCSI_IN(ATN); -} - -extern "C" bool scsiStatusBSY() -{ - return SCSI_IN(BSY); -} - -/************************/ -/* SCSI selection logic */ -/************************/ - -volatile uint8_t g_scsi_sts_selection; -volatile uint8_t g_scsi_ctrl_bsy; - -static void scsi_bsy_deassert_interrupt() -{ - if (SCSI_IN(SEL) && !SCSI_IN(BSY)) - { - uint8_t sel_bits = SCSI_IN_DATA(); - int sel_id = -1; - for (int i = 0; i < S2S_MAX_TARGETS; i++) - { - if (scsiDev.targets[i].targetId <= 7 && scsiDev.targets[i].cfg) - { - if (sel_bits & (1 << scsiDev.targets[i].targetId)) - { - sel_id = scsiDev.targets[i].targetId; - break; - } - } - } - - if (sel_id >= 0) - { - uint8_t atn_flag = SCSI_IN(ATN) ? SCSI_STS_SELECTION_ATN : 0; - g_scsi_sts_selection = SCSI_STS_SELECTION_SUCCEEDED | atn_flag | sel_id; - } - - // selFlag is required for Philips P2000C which releases it after 600ns - // without waiting for BSY. - // Also required for some early Mac Plus roms - scsiDev.selFlag = *SCSI_STS_SELECTED; - } -} - -extern "C" bool scsiStatusSEL() -{ - if (g_scsi_ctrl_bsy) - { - // We don't have direct register access to BSY bit like SCSI2SD scsi.c expects. - // Instead update the state here. - // Releasing happens with bus release. - g_scsi_ctrl_bsy = 0; - SCSI_OUT(BSY, 1); - } - - return SCSI_IN(SEL); -} - -/************************/ -/* SCSI bus reset logic */ -/************************/ - -static void scsi_rst_assert_interrupt() -{ - bool rst1 = SCSI_IN(RST); - delay_ns(500); - bool rst2 = SCSI_IN(RST); - - if (rst1 && rst2) - { - bluedbg("BUS RESET"); - scsiDev.resetFlag = 1; - } -} - -static void selectPhyMode() -{ - int oldmode = g_scsi_phy_mode; - - int default_mode = PHY_MODE_BEST_AVAILABLE; - - // Read overriding setting from configuration file - int wanted_mode = ini_getl("SCSI", "PhyMode", default_mode, CONFIGFILE); - - // Default: software GPIO bitbang, available on all revisions - g_scsi_phy_mode = PHY_MODE_PIO; - - // Timer based DMA bitbang, available on V1.1, 2.8 MB/s -#ifdef SCSI_ACCEL_DMA_AVAILABLE - if (wanted_mode == PHY_MODE_BEST_AVAILABLE || wanted_mode == PHY_MODE_DMA_TIMER) - { - g_scsi_phy_mode = PHY_MODE_DMA_TIMER; - } -#endif - - // GreenPAK with software write, available on V1.1 with extra chip, 3.5 MB/s - if (wanted_mode == PHY_MODE_BEST_AVAILABLE || wanted_mode == PHY_MODE_GREENPAK_PIO) - { - if (greenpak_is_ready()) - { - g_scsi_phy_mode = PHY_MODE_GREENPAK_PIO; - } - } - - // GreenPAK with DMA write, available on V1.1 with extra chip -#ifdef SCSI_ACCEL_DMA_AVAILABLE - if (wanted_mode == PHY_MODE_BEST_AVAILABLE || wanted_mode == PHY_MODE_GREENPAK_DMA) - { - if (greenpak_is_ready()) - { - g_scsi_phy_mode = PHY_MODE_GREENPAK_DMA; - } - } -#endif - - if (g_scsi_phy_mode != oldmode) - { - bluelog("SCSI PHY operating mode: ", g_scsi_phy_mode_names[g_scsi_phy_mode]); - } -} - -extern "C" void scsiPhyReset(void) -{ - SCSI_RELEASE_OUTPUTS(); - scsi_accel_dma_stopWrite(); - - g_scsi_sts_selection = 0; - g_scsi_ctrl_bsy = 0; - g_scsi_writereq.count = 0; - init_irqs(); - -#ifdef SCSI_SYNC_MODE_AVAILABLE - scsi_accel_sync_init(); -#endif - - selectPhyMode(); - - if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER) - { - scsi_accel_timer_dma_init(); - } - else if (g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA) - { - scsi_accel_greenpak_dma_init(); - } -} - -/************************/ -/* SCSI bus phase logic */ -/************************/ - -static SCSI_PHASE g_scsi_phase; - -extern "C" void scsiEnterPhase(int phase) -{ - int delay = scsiEnterPhaseImmediate(phase); - if (delay > 0) - { - s2s_delay_ns(delay); - } -} - -// Change state and return nanosecond delay to wait -extern "C" uint32_t scsiEnterPhaseImmediate(int phase) -{ - if (phase != g_scsi_phase) - { - // ANSI INCITS 362-2002 SPI-3 10.7.1: - // Phase changes are not allowed while REQ or ACK is asserted. - while (likely(!scsiDev.resetFlag) && SCSI_IN(ACK)) {} - - if (scsiDev.compatMode < COMPAT_SCSI2 && (phase == DATA_IN || phase == DATA_OUT)) - { - // Akai S1000/S3000 seems to need extra delay before changing to data phase - // after a command. The code in BlueSCSI_disk.cpp tries to do this while waiting - // for SD card, to avoid any extra latency. - s2s_delay_ns(400000); - } - - int oldphase = g_scsi_phase; - g_scsi_phase = (SCSI_PHASE)phase; - scsiLogPhaseChange(phase); - - if (phase < 0) - { - // Other communication on bus or reset state - SCSI_RELEASE_OUTPUTS(); - return 0; - } - else - { - SCSI_OUT(MSG, phase & __scsiphase_msg); - SCSI_OUT(CD, phase & __scsiphase_cd); - SCSI_OUT(IO, phase & __scsiphase_io); - - int delayNs = 400; // Bus settle delay - if ((oldphase & __scsiphase_io) != (phase & __scsiphase_io)) - { - delayNs += 400; // Data release delay - } - - if (scsiDev.compatMode < COMPAT_SCSI2) - { - // EMU EMAX needs 100uS ! 10uS is not enough. - delayNs += 100000; - } - - return delayNs; - } - } - else - { - return 0; - } -} - -// Release all signals -void scsiEnterBusFree(void) -{ - g_scsi_phase = BUS_FREE; - g_scsi_sts_selection = 0; - g_scsi_ctrl_bsy = 0; - scsiDev.cdbLen = 0; - - SCSI_RELEASE_OUTPUTS(); -} - -/********************/ -/* Transmit to host */ -/********************/ - -#define SCSI_WAIT_ACTIVE(pin) \ - if (!SCSI_IN(pin)) { \ - if (!SCSI_IN(pin)) { \ - while(!SCSI_IN(pin) && !scsiDev.resetFlag); \ - } \ - } - -#define SCSI_WAIT_INACTIVE(pin) \ - if (SCSI_IN(pin)) { \ - if (SCSI_IN(pin)) { \ - while(SCSI_IN(pin) && !scsiDev.resetFlag); \ - } \ - } - -static inline void scsiWriteOneByte(uint8_t value) -{ - SCSI_OUT_DATA(value); - delay_100ns(); // DB setup time before REQ - SCSI_OUT(REQ, 1); - SCSI_WAIT_ACTIVE(ACK); - SCSI_RELEASE_DATA_REQ(); // Release data and REQ - SCSI_WAIT_INACTIVE(ACK); -} - -extern "C" void scsiWriteByte(uint8_t value) -{ - scsiLogDataIn(&value, 1); - scsiWriteOneByte(value); -} - -extern "C" void scsiWrite(const uint8_t* data, uint32_t count) -{ - scsiStartWrite(data, count); - scsiFinishWrite(); -} - -extern "C" void scsiStartWrite(const uint8_t* data, uint32_t count) -{ - scsiLogDataIn(data, count); - - g_scsi_writereq.use_sync_mode = (g_scsi_phase == DATA_IN && scsiDev.target->syncOffset > 0); - - if (g_scsi_phy_mode == PHY_MODE_PIO - || g_scsi_phy_mode == PHY_MODE_GREENPAK_PIO - || g_scsi_writereq.use_sync_mode) - { - // Software based bit-banging. - // Write requests are queued and then executed in isWriteFinished() callback. - // This allows better parallelism with SD card transfers. - - if (g_scsi_writereq.count) - { - if (data == g_scsi_writereq.data + g_scsi_writereq.count) - { - // Combine with previous one - g_scsi_writereq.count += count; - return; - } - else - { - // Actually execute previous request - scsiFinishWrite(); - } - } - - g_scsi_writereq.data = data; - g_scsi_writereq.count = count; - } - else if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER || g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA) - { - // Accelerated writes using DMA and timers - scsi_accel_dma_startWrite(data, count, &scsiDev.resetFlag); - } - else - { - bluelog("Unknown SCSI PHY mode: ", (int)g_scsi_phy_mode); - } -} - -static void processPollingWrite(uint32_t count) -{ - if (count > g_scsi_writereq.count) - count = g_scsi_writereq.count; - - const uint8_t *data = g_scsi_writereq.data; - uint32_t count_words = count / 4; - - if (g_scsi_writereq.use_sync_mode) - { - // Synchronous mode transfer - scsi_accel_sync_send(data, count, &scsiDev.resetFlag); - } - else if (count_words * 4 == count) - { - if (g_scsi_phy_mode == PHY_MODE_GREENPAK_PIO) - { - // GreenPAK PIO accelerated asynchronous transfer - scsi_accel_greenpak_send((const uint32_t*)data, count_words, &scsiDev.resetFlag); - } - else - { - // Assembler optimized asynchronous transfer - scsi_accel_asm_send((const uint32_t*)data, count_words, &scsiDev.resetFlag); - } - } - else - { - // Use simple loop for unaligned transfers - for (uint32_t i = 0; i < count; i++) - { - if (scsiDev.resetFlag) break; - scsiWriteOneByte(data[i]); - } - } - - g_scsi_writereq.count -= count; - if (g_scsi_writereq.count) - { - g_scsi_writereq.data += count; - } - else - { - g_scsi_writereq.data = NULL; - } -} - -static bool isPollingWriteFinished(const uint8_t *data) -{ - if (g_scsi_writereq.count) - { - if (data == NULL) - { - return false; - } - else if (data >= g_scsi_writereq.data && - data < g_scsi_writereq.data + g_scsi_writereq.count) - { - return false; - } - } - return true; -} - -extern "C" bool scsiIsWriteFinished(const uint8_t *data) -{ - // Check if there is still a polling transfer in progress - if (!isPollingWriteFinished(data) && !check_sd_read_done()) - { - // Process the transfer piece-by-piece while waiting - // for SD card to react. - int max_count = g_scsi_writereq.count / 8; - - // Always transfer whole sectors without pause to avoid problems with some SCSI hosts. - int bytesPerSector = 512; - if (scsiDev.target) - { - bytesPerSector = scsiDev.target->liveCfg.bytesPerSector; - } - if (max_count % bytesPerSector != 0) max_count -= (max_count % bytesPerSector); - if (max_count < bytesPerSector) max_count = bytesPerSector; - - // Avoid SysTick interrupt pauses during the transfer - SysTick_Handle_PreEmptively(); - - processPollingWrite(max_count); - return isPollingWriteFinished(data); - } - - if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER || g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA) - { - return scsi_accel_dma_isWriteFinished(data); - } - else - { - return true; - } -} - -extern "C" void scsiFinishWrite() -{ - if (g_scsi_writereq.count) - { - // Finish previously started polling write request. - processPollingWrite(g_scsi_writereq.count); - } - - if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER || g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA) - { - scsi_accel_dma_finishWrite(&scsiDev.resetFlag); - } -} - -/*********************/ -/* Receive from host */ -/*********************/ - -static inline uint8_t scsiReadOneByte(void) -{ - SCSI_OUT(REQ, 1); - SCSI_WAIT_ACTIVE(ACK); - delay_100ns(); - uint8_t r = SCSI_IN_DATA(); - SCSI_OUT(REQ, 0); - SCSI_WAIT_INACTIVE(ACK); - - return r; -} - -extern "C" uint8_t scsiReadByte(void) -{ - uint8_t r = scsiReadOneByte(); - scsiLogDataOut(&r, 1); - return r; -} - -extern "C" void scsiRead(uint8_t* data, uint32_t count, int* parityError) -{ - *parityError = 0; - - uint32_t count_words = count / 4; - bool use_greenpak = (g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA || g_scsi_phy_mode == PHY_MODE_GREENPAK_PIO); - - SysTick_Handle_PreEmptively(); - - if (g_scsi_phase == DATA_OUT && scsiDev.target->syncOffset > 0) - { - // Synchronous data transfer - scsi_accel_sync_recv(data, count, parityError, &scsiDev.resetFlag); - } - else if (count_words * 4 == count && count_words >= 2 && use_greenpak) - { - // GreenPAK accelerated receive can handle a multiple of 4 bytes with minimum of 8 bytes. - scsi_accel_greenpak_recv((uint32_t*)data, count_words, &scsiDev.resetFlag); - } - else if (count_words * 4 == count && count_words >= 1) - { - // Optimized ASM subroutine can handle multiple of 4 bytes with minimum of 4 bytes. - scsi_accel_asm_recv((uint32_t*)data, count_words, &scsiDev.resetFlag); - } - else - { - // Use a simple loop for short and unaligned transfers - for (uint32_t i = 0; i < count; i++) - { - if (scsiDev.resetFlag) break; - - data[i] = scsiReadOneByte(); - } - } - - scsiLogDataOut(data, count); -} - -/**********************/ -/* Interrupt handlers */ -/**********************/ - -extern "C" -void SCSI_RST_IRQ (void) -{ - if (exti_interrupt_flag_get(SCSI_RST_EXTI)) - { - exti_interrupt_flag_clear(SCSI_RST_EXTI); - scsi_rst_assert_interrupt(); - } - - if (exti_interrupt_flag_get(SCSI_BSY_EXTI)) - { - exti_interrupt_flag_clear(SCSI_BSY_EXTI); - scsi_bsy_deassert_interrupt(); - } - - if (exti_interrupt_flag_get(SCSI_SEL_EXTI)) - { - // Check BSY line status when SEL goes active. - // This is needed to handle SCSI-1 hosts that use the single initiator mode. - // The host will just assert the SEL directly, without asserting BSY first. - exti_interrupt_flag_clear(SCSI_SEL_EXTI); - scsi_bsy_deassert_interrupt(); - } -} - -#if SCSI_RST_IRQn != SCSI_BSY_IRQn -extern "C" -void SCSI_BSY_IRQ (void) -{ - SCSI_RST_IRQ(); -} -#endif - -#if (SCSI_SEL_IRQn != SCSI_RST_IRQn) && (SCSI_SEL_IRQn != SCSI_BSY_IRQn) -extern "C" -void SCSI_SEL_IRQ (void) -{ - SCSI_RST_IRQ(); -} -#endif - -static void init_irqs() -{ - // Falling edge of RST pin - gpio_exti_source_select(SCSI_RST_EXTI_SOURCE_PORT, SCSI_RST_EXTI_SOURCE_PIN); - exti_init(SCSI_RST_EXTI, EXTI_INTERRUPT, EXTI_TRIG_FALLING); - NVIC_SetPriority(SCSI_RST_IRQn, 1); - NVIC_EnableIRQ(SCSI_RST_IRQn); - - // Rising edge of BSY pin - gpio_exti_source_select(SCSI_BSY_EXTI_SOURCE_PORT, SCSI_BSY_EXTI_SOURCE_PIN); - exti_init(SCSI_BSY_EXTI, EXTI_INTERRUPT, EXTI_TRIG_RISING); - NVIC_SetPriority(SCSI_BSY_IRQn, 1); - NVIC_EnableIRQ(SCSI_BSY_IRQn); - - // Falling edge of SEL pin - gpio_exti_source_select(SCSI_SEL_EXTI_SOURCE_PORT, SCSI_SEL_EXTI_SOURCE_PIN); - exti_init(SCSI_SEL_EXTI, EXTI_INTERRUPT, EXTI_TRIG_FALLING); - NVIC_SetPriority(SCSI_SEL_IRQn, 1); - NVIC_EnableIRQ(SCSI_SEL_IRQn); -} - - diff --git a/lib/BlueSCSI_platform_GD32F205/scsiPhy.h b/lib/BlueSCSI_platform_GD32F205/scsiPhy.h deleted file mode 100644 index 2841298f..00000000 --- a/lib/BlueSCSI_platform_GD32F205/scsiPhy.h +++ /dev/null @@ -1,67 +0,0 @@ -// Interface to SCSI physical interface. -// This file is derived from scsiPhy.h in SCSI2SD-V6. - -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// Read SCSI status signals -bool scsiStatusATN(); -bool scsiStatusBSY(); -bool scsiStatusSEL(); - -// Parity not yet implemented -#define scsiParityError() 0 - -// Get SCSI selection status. -// This is latched by interrupt when BSY is deasserted while SEL is asserted. -// Lowest 3 bits are the selected target id. -// Highest bits are status information. -#define SCSI_STS_SELECTION_SUCCEEDED 0x40 -#define SCSI_STS_SELECTION_ATN 0x80 -extern volatile uint8_t g_scsi_sts_selection; -#define SCSI_STS_SELECTED (&g_scsi_sts_selection) -extern volatile uint8_t g_scsi_ctrl_bsy; -#define SCSI_CTRL_BSY (&g_scsi_ctrl_bsy) - -// Called when SCSI RST signal has been asserted, should release bus. -void scsiPhyReset(void); - -// Change MSG / CD / IO signal states and wait for necessary transition time. -// Phase argument is one of SCSI_PHASE enum values. -void scsiEnterPhase(int phase); - -// Change state and return nanosecond delay to wait -uint32_t scsiEnterPhaseImmediate(int phase); - -// Release all signals -void scsiEnterBusFree(void); - -// Blocking data transfer -void scsiWrite(const uint8_t* data, uint32_t count); -void scsiRead(uint8_t* data, uint32_t count, int* parityError); -void scsiWriteByte(uint8_t value); -uint8_t scsiReadByte(void); - -// Non-blocking data transfer. -// Depending on platform support the start() function may block. -// The start function can be called multiple times, it may internally -// either combine transfers or block until previous transfer completes. -void scsiStartWrite(const uint8_t* data, uint32_t count); -void scsiFinishWrite(); - -// Query whether the data at pointer has already been read, i.e. buffer can be reused. -// If data is NULL, checks if all writes have completed. -bool scsiIsWriteFinished(const uint8_t *data); - - -#define s2s_getScsiRateKBs() 0 - -#ifdef __cplusplus -} -#endif diff --git a/lib/BlueSCSI_platform_GD32F205/scsi_accel_asm.cpp b/lib/BlueSCSI_platform_GD32F205/scsi_accel_asm.cpp deleted file mode 100644 index 9199e554..00000000 --- a/lib/BlueSCSI_platform_GD32F205/scsi_accel_asm.cpp +++ /dev/null @@ -1,152 +0,0 @@ -#include "scsi_accel_asm.h" -#include "BlueSCSI_platform.h" - -// Optimized ASM blocks for the SCSI communication subroutine - -// Take 8 bits from d and format them for writing -// d is name of data operand, b is bit offset, x is unique label -#define ASM_LOAD_DATA(d, b, x) \ -" load_data1_" x "_%=: \n" \ -" ubfx %[tmp1], %[" d "], #" b ", #8 \n" \ -" ldr %[tmp1], [%[byte_lookup], %[tmp1], lsl #2] \n" - -// Write data to SCSI port and set REQ high -#define ASM_SEND_DATA(x) \ -" send_data" x "_%=: \n" \ -" str %[tmp1], [%[out_port_bop]] \n" - -// Read data from SCSI port, set REQ high, store data to d at bit offset b -#define ASM_RECV_DATA(d, b, x) \ -" recv_data" x "_%=: \n" \ -" ldr %[tmp1], [%[in_port_istat]] \n" \ -" mov %[tmp2], %[req_high_bop] \n" \ -" str %[tmp2], [%[out_port_bop]] \n" \ -" ubfx %[tmp1], %[tmp1], %[data_in_shift], #8 \n" \ -" bfi %[" d "], %[tmp1], #" b ", #8 \n" - -// Wait for ACK to be high, set REQ low, wait ACK low -#define ASM_HANDSHAKE(x) \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" str %[tmp2], [%[req_pin_bb]] \n" \ -" cbnz %[tmp2], req_is_low_now" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" str %[tmp2], [%[req_pin_bb]] \n" \ -" cbnz %[tmp2], req_is_low_now" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" str %[tmp2], [%[req_pin_bb]] \n" \ -" cbnz %[tmp2], req_is_low_now" x "_%= \n" \ -" wait_ack_inactive" x "_%=: \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" str %[tmp2], [%[req_pin_bb]] \n" \ -" cbnz %[tmp2], req_is_low_now" x "_%= \n" \ -" ldr %[tmp2], [%[reset_flag]] \n" \ -" cbnz %[tmp2], req_is_low_now" x "_%= \n" \ -" b.n wait_ack_inactive" x "_%= \n" \ -" req_is_low_now" x "_%=: \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], over_ack_active" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], over_ack_active" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], over_ack_active" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], over_ack_active" x "_%= \n" \ -" wait_ack_active" x "_%=: \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], over_ack_active" x "_%= \n" \ -" ldr %[tmp2], [%[reset_flag]] \n" \ -" cbnz %[tmp2], over_ack_active" x "_%= \n" \ -" b.n wait_ack_active" x "_%= \n" \ -" over_ack_active" x "_%=: \n" \ - -// Send bytes to SCSI bus using the asynchronous handshake mechanism -// Takes 4 bytes at a time for sending from buf. -void scsi_accel_asm_send(const uint32_t *buf, uint32_t num_words, volatile int *resetFlag) -{ - volatile uint32_t *out_port_bop = (volatile uint32_t*)&GPIO_BOP(SCSI_OUT_PORT); - const uint32_t *byte_lookup = g_scsi_out_byte_to_bop; - uint32_t ack_pin_bb = PERIPH_BB_BASE + (((uint32_t)&GPIO_ISTAT(SCSI_ACK_PORT)) - APB1_BUS_BASE) * 32 + SCSI_IN_ACK_IDX * 4; - uint32_t req_pin_bb = PERIPH_BB_BASE + (((uint32_t)out_port_bop) - APB1_BUS_BASE) * 32 + (SCSI_OUT_REQ_IDX + 16) * 4; - register uint32_t tmp1 = 0; - register uint32_t tmp2 = 0; - register uint32_t data = 0; - - asm volatile ( - " ldr %[data], [%[buf]], #4 \n" \ - ASM_LOAD_DATA("data", "0", "first") - - "inner_loop_%=: \n" \ - ASM_SEND_DATA("0") - ASM_LOAD_DATA("data", "8", "8") - ASM_HANDSHAKE("0") - - ASM_SEND_DATA("8") - ASM_LOAD_DATA("data", "16", "16") - ASM_HANDSHAKE("8") - - ASM_SEND_DATA("16") - ASM_LOAD_DATA("data", "24", "24") - ASM_HANDSHAKE("16") - - ASM_SEND_DATA("24") - " ldr %[data], [%[buf]], #4 \n" \ - ASM_LOAD_DATA("data", "0", "0") - ASM_HANDSHAKE("24") - - " subs %[num_words], %[num_words], #1 \n" \ - " bne inner_loop_%= \n" - : /* Output */ [tmp1] "+l" (tmp1), [tmp2] "+l" (tmp2), [data] "+r" (data), - [buf] "+r" (buf), [num_words] "+r" (num_words) - : /* Input */ [ack_pin_bb] "r" (ack_pin_bb), - [req_pin_bb] "r" (req_pin_bb), - [out_port_bop] "r"(out_port_bop), - [byte_lookup] "r" (byte_lookup), - [reset_flag] "r" (resetFlag) - : /* Clobber */ ); - - SCSI_RELEASE_DATA_REQ(); -} - -// Read bytes from SCSI bus using asynchronous handshake mechanism -// Takes 4 bytes at a time. -void scsi_accel_asm_recv(uint32_t *buf, uint32_t num_words, volatile int *resetFlag) -{ - volatile uint32_t *out_port_bop = (volatile uint32_t*)&GPIO_BOP(SCSI_OUT_PORT); - volatile uint32_t *in_port_istat = (volatile uint32_t*)&GPIO_ISTAT(SCSI_IN_PORT); - uint32_t ack_pin_bb = PERIPH_BB_BASE + (((uint32_t)&GPIO_ISTAT(SCSI_ACK_PORT)) - APB1_BUS_BASE) * 32 + SCSI_IN_ACK_IDX * 4; - uint32_t req_pin_bb = PERIPH_BB_BASE + (((uint32_t)out_port_bop) - APB1_BUS_BASE) * 32 + (SCSI_OUT_REQ_IDX + 16) * 4; - register uint32_t tmp1 = 0; - register uint32_t tmp2 = 0; - register uint32_t data = 0; - - asm volatile ( - "inner_loop_%=: \n" \ - ASM_HANDSHAKE("0") - ASM_RECV_DATA("data", "0", "0") - - ASM_HANDSHAKE("8") - ASM_RECV_DATA("data", "8", "8") - - ASM_HANDSHAKE("16") - ASM_RECV_DATA("data", "16", "16") - - ASM_HANDSHAKE("24") - ASM_RECV_DATA("data", "24", "24") - - " mvn %[data], %[data] \n" \ - " str %[data], [%[buf]], #4 \n" \ - " subs %[num_words], %[num_words], #1 \n" \ - " bne inner_loop_%= \n" - : /* Output */ [tmp1] "+l" (tmp1), [tmp2] "+l" (tmp2), [data] "+r" (data), - [buf] "+r" (buf), [num_words] "+r" (num_words) - : /* Input */ [ack_pin_bb] "r" (ack_pin_bb), - [req_pin_bb] "r" (req_pin_bb), - [out_port_bop] "r"(out_port_bop), - [in_port_istat] "r" (in_port_istat), - [reset_flag] "r" (resetFlag), - [data_in_shift] "I" (SCSI_IN_SHIFT), - [req_high_bop] "I" (SCSI_OUT_REQ) - : /* Clobber */ ); - - SCSI_RELEASE_DATA_REQ(); -} diff --git a/lib/BlueSCSI_platform_GD32F205/scsi_accel_asm.h b/lib/BlueSCSI_platform_GD32F205/scsi_accel_asm.h deleted file mode 100644 index 6445b428..00000000 --- a/lib/BlueSCSI_platform_GD32F205/scsi_accel_asm.h +++ /dev/null @@ -1,8 +0,0 @@ -// SCSI subroutines using hand-optimized assembler - -#pragma once - -#include - -void scsi_accel_asm_send(const uint32_t *buf, uint32_t num_words, volatile int *resetFlag); -void scsi_accel_asm_recv(uint32_t *buf, uint32_t num_words, volatile int *resetFlag); \ No newline at end of file diff --git a/lib/BlueSCSI_platform_GD32F205/scsi_accel_dma.cpp b/lib/BlueSCSI_platform_GD32F205/scsi_accel_dma.cpp deleted file mode 100644 index 7d405a6a..00000000 --- a/lib/BlueSCSI_platform_GD32F205/scsi_accel_dma.cpp +++ /dev/null @@ -1,659 +0,0 @@ -#include "scsi_accel_dma.h" -#include -#include -#include -#include -#include - -#ifndef SCSI_ACCEL_DMA_AVAILABLE - -void scsi_accel_timer_dma_init() {} -void scsi_accel_greenpak_dma_init() {} -void scsi_accel_dma_startWrite(const uint8_t* data, uint32_t count, volatile int *resetFlag) {} -void scsi_accel_dma_stopWrite() {} -void scsi_accel_dma_finishWrite(volatile int *resetFlag) {} -bool scsi_accel_dma_isWriteFinished(const uint8_t* data) { return true; } - - -#else - -static void greenpak_refill_dmabuf(); -static void greenpak_start_dma(); -static void greenpak_stop_dma(); - -enum greenpak_state_t { GREENPAK_IO1_LOW = 0, GREENPAK_IO1_HIGH, GREENPAK_STOP}; - -#define DMA_BUF_SIZE 256 -#define DMA_BUF_MASK (DMA_BUF_SIZE - 1) -static struct { - uint8_t *app_buf; // Buffer provided by application - uint32_t dma_buf[DMA_BUF_SIZE]; // Buffer of data formatted for GPIO BOP register - uint32_t dma_idx; // Write index to DMA buffer - uint32_t dma_fillto; // Point up to which DMA buffer is available for refilling - uint32_t timer_buf; // Control value for timer SWEVG register - uint32_t bytes_app; // Bytes available in application buffer - uint32_t bytes_dma; // Bytes (words) written so far to DMA buffer - uint32_t scheduled_dma; // Bytes (words) that DMA data count was last set to - greenpak_state_t greenpak_state; // Toggle signal state for greenpak - - uint8_t *next_app_buf; // Next buffer from application after current one finishes - uint32_t next_app_bytes; // Bytes in next buffer -} g_scsi_dma; - -enum scsidma_state_t { SCSIDMA_IDLE = 0, SCSIDMA_WRITE }; -static volatile scsidma_state_t g_scsi_dma_state; -static bool g_scsi_dma_use_greenpak; - -void scsi_accel_timer_dma_init() -{ - g_scsi_dma_state = SCSIDMA_IDLE; - g_scsi_dma_use_greenpak = false; - rcu_periph_clock_enable(SCSI_TIMER_RCU); - rcu_periph_clock_enable(SCSI_TIMER_DMA_RCU); - - // DMA Channel A: data copy - // GPIO DMA copies data from memory buffer to GPIO BOP register. - // The memory buffer is filled by interrupt routine. - dma_parameter_struct gpio_dma_config = - { - .periph_addr = (uint32_t)&GPIO_BOP(SCSI_OUT_PORT), - .periph_width = DMA_PERIPHERAL_WIDTH_32BIT, - .memory_addr = 0, // Filled before transfer - .memory_width = DMA_MEMORY_WIDTH_32BIT, - .number = DMA_BUF_SIZE, - .priority = DMA_PRIORITY_ULTRA_HIGH, - .periph_inc = DMA_PERIPH_INCREASE_DISABLE, - .memory_inc = DMA_MEMORY_INCREASE_ENABLE, - .direction = DMA_MEMORY_TO_PERIPHERAL - }; - dma_init(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, &gpio_dma_config); - dma_circulation_enable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA); - NVIC_SetPriority(SCSI_TIMER_DMACHA_IRQn, 1); - NVIC_EnableIRQ(SCSI_TIMER_DMACHA_IRQn); - - // DMA Channel B: timer update - // Timer DMA causes update event to restart timer after - // GPIO DMA operation is done. - dma_parameter_struct timer_dma_config = - { - .periph_addr = (uint32_t)&TIMER_SWEVG(SCSI_TIMER), - .periph_width = DMA_PERIPHERAL_WIDTH_32BIT, - .memory_addr = (uint32_t)&g_scsi_dma.timer_buf, - .memory_width = DMA_MEMORY_WIDTH_32BIT, - .number = DMA_BUF_SIZE, - .priority = DMA_PRIORITY_HIGH, - .periph_inc = DMA_PERIPH_INCREASE_DISABLE, - .memory_inc = DMA_PERIPH_INCREASE_DISABLE, - .direction = DMA_MEMORY_TO_PERIPHERAL - }; - dma_init(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, &timer_dma_config); - NVIC_SetPriority(SCSI_TIMER_DMACHB_IRQn, 2); - NVIC_EnableIRQ(SCSI_TIMER_DMACHB_IRQn); - - g_scsi_dma.timer_buf = TIMER_SWEVG_UPG; - - // Timer is used to toggle the request signal based on external trigger input. - // OUT_REQ is driven by timer output. - // 1. On timer update event, REQ is set low. - // 2. When ACK goes low, timer counts and OUT_REQ is set high. - // Simultaneously a DMA request is triggered to write next data to GPIO. - // 3. When ACK goes high, a DMA request is triggered to cause timer update event. - // The DMA request priority is set so that 2. always completes before it. - TIMER_CTL0(SCSI_TIMER) = 0; - TIMER_SMCFG(SCSI_TIMER) = TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_CI0F_ED; - TIMER_CAR(SCSI_TIMER) = 65535; - TIMER_PSC(SCSI_TIMER) = 0; - TIMER_DMAINTEN(SCSI_TIMER) = 0; - TIMER_CHCTL0(SCSI_TIMER) = 0x6001; // CH0 as input, CH1 as DMA trigger - TIMER_CHCTL1(SCSI_TIMER) = 0x6074; // CH2 as fast PWM output, CH3 as DMA trigger - TIMER_CHCTL2(SCSI_TIMER) = TIMER_CHCTL2_CH2NEN; - TIMER_CCHP(SCSI_TIMER) = TIMER_CCHP_POEN; - TIMER_CH1CV(SCSI_TIMER) = 1; // Copy data when ACK goes low - TIMER_CH2CV(SCSI_TIMER) = 1; // REQ is low until ACK goes low - TIMER_CH3CV(SCSI_TIMER) = 2; // Reset timer after ACK goes high & previous DMA is complete - gpio_init(SCSI_TIMER_IN_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_TIMER_IN_PIN); - - scsi_accel_dma_stopWrite(); -} - -// Select whether OUT_REQ is connected to timer or GPIO port -static void scsi_dma_gpio_config(bool enable) -{ - if (enable) - { - gpio_init(SCSI_OUT_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, SCSI_OUT_REQ); - - if (g_scsi_dma_use_greenpak) - { - GPIO_BC(SCSI_OUT_PORT) = GREENPAK_PLD_IO1; - GPIO_BOP(SCSI_OUT_PORT) = GREENPAK_PLD_IO2; - } - else - { - gpio_init(SCSI_TIMER_OUT_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SCSI_TIMER_OUT_PIN); - } - } - else - { - GPIO_BC(SCSI_OUT_PORT) = GREENPAK_PLD_IO2; - gpio_init(SCSI_TIMER_OUT_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, SCSI_TIMER_OUT_PIN); - gpio_init(SCSI_OUT_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_REQ); - } -} - -// Convert input bytes into BOP values in the DMA buffer -static void refill_dmabuf() -{ - if (g_scsi_dma_use_greenpak) - { - greenpak_refill_dmabuf(); - return; - } - - // Check how many bytes we have available from the application - uint32_t count = g_scsi_dma.bytes_app - g_scsi_dma.bytes_dma; - - // Check amount of free space in DMA buffer - uint32_t max = g_scsi_dma.dma_fillto - g_scsi_dma.dma_idx; - if (count > max) count = max; - if (count == 0) return; - - uint8_t *src = g_scsi_dma.app_buf + g_scsi_dma.bytes_dma; - uint32_t *dst = g_scsi_dma.dma_buf; - uint32_t pos = g_scsi_dma.dma_idx; - uint32_t end = pos + count; - g_scsi_dma.dma_idx = end; - g_scsi_dma.bytes_dma += count; - - while (pos + 4 <= end) - { - uint32_t input = *(uint32_t*)src; - src += 4; - - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop[(input >> 0) & 0xFF]; - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop[(input >> 8) & 0xFF]; - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop[(input >> 16) & 0xFF]; - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop[(input >> 24) & 0xFF]; - } - - while (pos < end) - { - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop[*src++]; - } - - if (end < g_scsi_dma.dma_fillto) - { - // Partial buffer fill, this will get refilled from interrupt if we - // get more data. Set next byte to an invalid parity value so that - // any race conditions will get caught as parity error. - dst[pos & DMA_BUF_MASK] = g_scsi_out_byte_to_bop[0] ^ SCSI_OUT_DBP; - } -} - -// Start DMA transfer -static void start_dma() -{ - if (g_scsi_dma_use_greenpak) - { - greenpak_start_dma(); - return; - } - - // Disable channels while configuring - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) &= ~DMA_CHXCTL_CHEN; - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_CHEN; - TIMER_CTL0(SCSI_TIMER) = 0; - - // Set new buffer address and size - // CHA / Data channel is in circular mode and always has DMA_BUF_SIZE buffer size. - // CHB / Update channel limits the number of data. - DMA_CHMADDR(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) = (uint32_t)g_scsi_dma.dma_buf; - DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) = DMA_BUF_SIZE; - uint32_t dma_to_schedule = g_scsi_dma.bytes_app - g_scsi_dma.scheduled_dma; - DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) = dma_to_schedule; - g_scsi_dma.scheduled_dma += dma_to_schedule; - - // Clear pending DMA events - TIMER_DMAINTEN(SCSI_TIMER) = 0; - TIMER_DMAINTEN(SCSI_TIMER) = TIMER_DMAINTEN_CH1DEN | TIMER_DMAINTEN_CH3DEN; - - // Clear and enable interrupt - DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_ERR, SCSI_TIMER_DMACHA); - DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_ERR, SCSI_TIMER_DMACHB); - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) |= DMA_CHXCTL_FTFIE | DMA_CHXCTL_HTFIE; - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) |= DMA_CHXCTL_FTFIE; - - // Enable channels - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) |= DMA_CHXCTL_CHEN; - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) |= DMA_CHXCTL_CHEN; - - // Make sure REQ is initially high - TIMER_CNT(SCSI_TIMER) = 16; - TIMER_CHCTL1(SCSI_TIMER) = 0x6050; - TIMER_CHCTL1(SCSI_TIMER) = 0x6074; - - // Enable timer - TIMER_CTL0(SCSI_TIMER) |= TIMER_CTL0_CEN; - - // Generate first events - TIMER_SWEVG(SCSI_TIMER) = TIMER_SWEVG_CH1G; - TIMER_SWEVG(SCSI_TIMER) = TIMER_SWEVG_CH3G; -} - -// Stop DMA transfer -static void stop_dma() -{ - greenpak_stop_dma(); - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) &= ~DMA_CHXCTL_CHEN; - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_CHEN; - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) &= ~(DMA_CHXCTL_FTFIE | DMA_CHXCTL_HTFIE); - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_FTFIE; - TIMER_CTL0(SCSI_TIMER) &= ~TIMER_CTL0_CEN; - g_scsi_dma_state = SCSIDMA_IDLE; - SCSI_RELEASE_DATA_REQ(); -} - -static void check_dma_next_buffer() -{ - // Check if we are at the end of the application buffer - if (g_scsi_dma.next_app_buf && g_scsi_dma.bytes_dma == g_scsi_dma.bytes_app) - { - // Switch to next buffer - assert(g_scsi_dma.scheduled_dma == g_scsi_dma.bytes_app); - g_scsi_dma.app_buf = g_scsi_dma.next_app_buf; - g_scsi_dma.bytes_app = g_scsi_dma.next_app_bytes; - g_scsi_dma.bytes_dma = 0; - g_scsi_dma.scheduled_dma = 0; - g_scsi_dma.next_app_buf = 0; - g_scsi_dma.next_app_bytes = 0; - refill_dmabuf(); - } -} - -// Convert new data from application buffer to DMA buffer -extern "C" void SCSI_TIMER_DMACHA_IRQ() -{ - // bluedbg("DMA irq A, counts: ", DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA), " ", - // DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB), " ", - // TIMER_CNT(SCSI_TIMER)); - - uint32_t intf = DMA_INTF(SCSI_TIMER_DMA); - const uint32_t half_flag = DMA_FLAG_ADD(DMA_FLAG_HTF, SCSI_TIMER_DMACHA); - const uint32_t full_flag = DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHA); - if (intf & half_flag) - { - if (intf & full_flag) - { - bluelog("ERROR: SCSI DMA overrun: ", intf, - " bytes_app: ", g_scsi_dma.bytes_app, - " bytes_dma: ", g_scsi_dma.bytes_dma, - " dma_idx: ", g_scsi_dma.dma_idx, - " sched_dma: ", g_scsi_dma.scheduled_dma); - stop_dma(); - return; - } - - DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF, SCSI_TIMER_DMACHA); - g_scsi_dma.dma_fillto += DMA_BUF_SIZE / 2; - } - else if (intf & full_flag) - { - DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHA); - g_scsi_dma.dma_fillto += DMA_BUF_SIZE / 2; - } - - // Fill DMA buffer with data from current application buffer - refill_dmabuf(); - - check_dma_next_buffer(); -} - -// Check if enough data is available to continue DMA transfer -extern "C" void SCSI_TIMER_DMACHB_IRQ() -{ - // bluedbg("DMA irq B, counts: ", DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA), " ", - // DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB), " ", - // TIMER_CNT(SCSI_TIMER)); - uint32_t intf = DMA_INTF(SCSI_TIMER_DMA); - if (intf & DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHB)) - { - DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHB); - - if (g_scsi_dma.bytes_app > g_scsi_dma.scheduled_dma) - { - if (g_scsi_dma.dma_idx < g_scsi_dma.dma_fillto) - { - // Previous request didn't have a complete buffer worth of data. - // Refill the buffer and ensure that the first byte of the new data gets - // written to outputs. - __disable_irq(); - refill_dmabuf(); - __enable_irq(); - } - - // Verify the first byte of the new data has been written to outputs - // It may have been updated after the DMA write occurred. - __disable_irq(); - uint32_t first_data_idx = g_scsi_dma.dma_idx - (g_scsi_dma.bytes_dma - g_scsi_dma.scheduled_dma); - uint32_t first_data = g_scsi_dma.dma_buf[first_data_idx & DMA_BUF_MASK]; - GPIO_BOP(SCSI_OUT_PORT) = first_data; - __enable_irq(); - - // Update the total number of bytes available for DMA - uint32_t dma_to_schedule = g_scsi_dma.bytes_app - g_scsi_dma.scheduled_dma; - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_CHEN; - DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) = dma_to_schedule; - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) |= DMA_CHXCTL_CHEN; - g_scsi_dma.scheduled_dma += dma_to_schedule; - } - else - { - // No more data available - stop_dma(); - } - } -} - -void scsi_accel_dma_startWrite(const uint8_t* data, uint32_t count, volatile int *resetFlag) -{ - __disable_irq(); - if (g_scsi_dma_state == SCSIDMA_WRITE) - { - if (!g_scsi_dma.next_app_buf && data == g_scsi_dma.app_buf + g_scsi_dma.bytes_app) - { - // Combine with currently running request - g_scsi_dma.bytes_app += count; - count = 0; - } - else if (data == g_scsi_dma.next_app_buf + g_scsi_dma.next_app_bytes) - { - // Combine with queued request - g_scsi_dma.next_app_bytes += count; - count = 0; - } - else if (!g_scsi_dma.next_app_buf) - { - // Add as queued request - g_scsi_dma.next_app_buf = (uint8_t*)data; - g_scsi_dma.next_app_bytes = count; - count = 0; - } - } - __enable_irq(); - - // Check if the request was combined - if (count == 0) return; - - if (g_scsi_dma_state != SCSIDMA_IDLE) - { - // Wait for previous request to finish - scsi_accel_dma_finishWrite(resetFlag); - if (*resetFlag) - { - return; - } - } - - // bluedbg("Starting DMA write of ", (int)count, " bytes"); - scsi_dma_gpio_config(true); - g_scsi_dma_state = SCSIDMA_WRITE; - g_scsi_dma.app_buf = (uint8_t*)data; - g_scsi_dma.dma_idx = 0; - g_scsi_dma.dma_fillto = DMA_BUF_SIZE; - g_scsi_dma.bytes_app = count; - g_scsi_dma.bytes_dma = 0; - g_scsi_dma.scheduled_dma = 0; - g_scsi_dma.next_app_buf = NULL; - g_scsi_dma.next_app_bytes = 0; - g_scsi_dma.greenpak_state = GREENPAK_IO1_LOW; - refill_dmabuf(); - start_dma(); -} - -bool scsi_accel_dma_isWriteFinished(const uint8_t* data) -{ - // Check if everything has completed - if (g_scsi_dma_state == SCSIDMA_IDLE) - { - return true; - } - - if (!data) - return false; - - // Check if this data item is still in queue. - __disable_irq(); - bool finished = true; - if (data >= g_scsi_dma.app_buf + g_scsi_dma.bytes_dma && - data < g_scsi_dma.app_buf + g_scsi_dma.bytes_app) - { - finished = false; // In current transfer - } - else if (data >= g_scsi_dma.next_app_buf && - data < g_scsi_dma.next_app_buf + g_scsi_dma.next_app_bytes) - { - finished = false; // In queued transfer - } - __enable_irq(); - - return finished; -} - -void scsi_accel_dma_stopWrite() -{ - stop_dma(); - scsi_dma_gpio_config(false); -} - -void scsi_accel_dma_finishWrite(volatile int *resetFlag) -{ - uint32_t start = millis(); - while (g_scsi_dma_state != SCSIDMA_IDLE && !*resetFlag) - { - if ((uint32_t)(millis() - start) > 5000) - { - bluelog("scsi_accel_dma_finishWrite() timeout, DMA counts ", - DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA), " ", - DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB), " ", - TIMER_CNT(SCSI_TIMER)); - *resetFlag = 1; - break; - } - } - - scsi_accel_dma_stopWrite(); -} - -/************************************************/ -/* Functions using external GreenPAK logic chip */ -/************************************************/ - -void scsi_accel_greenpak_dma_init() -{ - g_scsi_dma_state = SCSIDMA_IDLE; - g_scsi_dma_use_greenpak = true; - rcu_periph_clock_enable(SCSI_TIMER_RCU); - rcu_periph_clock_enable(SCSI_TIMER_DMA_RCU); - - // DMA Channel A: data copy - // GPIO DMA copies data from memory buffer to GPIO BOP register. - // The memory buffer is filled by interrupt routine. - dma_parameter_struct gpio_dma_config = - { - .periph_addr = (uint32_t)&GPIO_BOP(SCSI_OUT_PORT), - .periph_width = DMA_PERIPHERAL_WIDTH_32BIT, - .memory_addr = (uint32_t)g_scsi_dma.dma_buf, - .memory_width = DMA_MEMORY_WIDTH_32BIT, - .number = DMA_BUF_SIZE, - .priority = DMA_PRIORITY_ULTRA_HIGH, - .periph_inc = DMA_PERIPH_INCREASE_DISABLE, - .memory_inc = DMA_MEMORY_INCREASE_ENABLE, - .direction = DMA_MEMORY_TO_PERIPHERAL - }; - dma_init(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, &gpio_dma_config); - dma_circulation_enable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA); - NVIC_SetPriority(SCSI_TIMER_DMACHA_IRQn, 2); - NVIC_EnableIRQ(SCSI_TIMER_DMACHA_IRQn); - NVIC_DisableIRQ(SCSI_TIMER_DMACHB_IRQn); - - // EXTI channel is used to trigger when we reach end of the transfer. - // Because the main DMA is circular and transfer size may not be even - // multiple of it, we cannot trigger the end at the DMA interrupt. - gpio_exti_source_select(GREENPAK_PLD_IO2_EXTI_SOURCE_PORT, GREENPAK_PLD_IO2_EXTI_SOURCE_PIN); - exti_init(GREENPAK_PLD_IO2_EXTI, EXTI_INTERRUPT, EXTI_TRIG_FALLING); - exti_interrupt_flag_clear(GREENPAK_PLD_IO2_EXTI); - exti_interrupt_disable(GREENPAK_PLD_IO2_EXTI); - NVIC_SetPriority(GREENPAK_IRQn, 1); - NVIC_EnableIRQ(GREENPAK_IRQn); - - // Timer is used to trigger DMA requests - // OUT_REQ is driven by timer output. - // 1. On timer update event, REQ is set low. - // 2. When ACK goes low, timer counts and OUT_REQ is set high. - // Simultaneously a DMA request is triggered to write next data to GPIO. - // 3. When ACK goes high, a DMA request is triggered to cause timer update event. - // The DMA request priority is set so that 2. always completes before it. - TIMER_CTL0(SCSI_TIMER) = 0; - TIMER_SMCFG(SCSI_TIMER) = TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_CI0F_ED; - TIMER_CAR(SCSI_TIMER) = 1; - TIMER_PSC(SCSI_TIMER) = 0; - TIMER_DMAINTEN(SCSI_TIMER) = 0; - TIMER_CHCTL0(SCSI_TIMER) = 0x6001; // CH0 as input, CH1 as DMA trigger - TIMER_CHCTL1(SCSI_TIMER) = 0; - TIMER_CHCTL2(SCSI_TIMER) = 0; - TIMER_CCHP(SCSI_TIMER) = 0; - TIMER_CH1CV(SCSI_TIMER) = 1; // Copy data when ACK goes low - gpio_init(SCSI_TIMER_IN_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_TIMER_IN_PIN); -} - -extern const uint32_t g_scsi_out_byte_to_bop_pld1hi[256]; -extern const uint32_t g_scsi_out_byte_to_bop_pld1lo[256]; - -static void greenpak_refill_dmabuf() -{ - if (g_scsi_dma.greenpak_state == GREENPAK_STOP) - { - // Wait for previous DMA block to end first - return; - } - - // Check how many bytes we have available from the application - uint32_t count = g_scsi_dma.bytes_app - g_scsi_dma.bytes_dma; - - // Check amount of free space in DMA buffer - uint32_t max = g_scsi_dma.dma_fillto - g_scsi_dma.dma_idx; - if (count > max) count = max; - - uint8_t *src = g_scsi_dma.app_buf + g_scsi_dma.bytes_dma; - uint32_t *dst = g_scsi_dma.dma_buf; - uint32_t pos = g_scsi_dma.dma_idx; - uint32_t end = pos + count; - g_scsi_dma.dma_idx = end; - g_scsi_dma.bytes_dma += count; - g_scsi_dma.scheduled_dma = g_scsi_dma.bytes_dma; - - if (pos < end && g_scsi_dma.greenpak_state == GREENPAK_IO1_HIGH) - { - // Fix alignment so that main loop begins with PLD1HI - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1lo[*src++]; - g_scsi_dma.greenpak_state = GREENPAK_IO1_LOW; - } - - while (pos + 4 <= end) - { - uint32_t input = *(uint32_t*)src; - src += 4; - - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1hi[(input >> 0) & 0xFF]; - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1lo[(input >> 8) & 0xFF]; - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1hi[(input >> 16) & 0xFF]; - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1lo[(input >> 24) & 0xFF]; - } - - while (pos < end) - { - if (g_scsi_dma.greenpak_state == GREENPAK_IO1_HIGH) - { - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1lo[*src++]; - g_scsi_dma.greenpak_state = GREENPAK_IO1_LOW; - } - else - { - dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1hi[*src++]; - g_scsi_dma.greenpak_state = GREENPAK_IO1_HIGH; - } - } - - uint32_t remain = g_scsi_dma.dma_fillto - g_scsi_dma.dma_idx; - if (!g_scsi_dma.next_app_buf && remain > 0) - { - // Mark the end of transfer by turning PD2 off - dst[(pos++) & DMA_BUF_MASK] = (GREENPAK_PLD_IO2 << 16) | (GREENPAK_PLD_IO1 << 16); - g_scsi_dma.dma_idx = pos; - g_scsi_dma.greenpak_state = GREENPAK_STOP; - } -} - -extern "C" void GREENPAK_IRQ() -{ - if (EXTI_PD & GREENPAK_PLD_IO2_EXTI) - { - EXTI_PD = GREENPAK_PLD_IO2_EXTI; - - if (g_scsi_dma.bytes_app > g_scsi_dma.bytes_dma || g_scsi_dma.next_app_buf) - { - assert(g_scsi_dma.greenpak_state == GREENPAK_STOP); - g_scsi_dma.greenpak_state = GREENPAK_IO1_LOW; - // More data is available - check_dma_next_buffer(); - refill_dmabuf(); - - // Continue transferring - GPIO_BOP(SCSI_OUT_PORT) = GREENPAK_PLD_IO2; - TIMER_SWEVG(SCSI_TIMER) = TIMER_SWEVG_CH1G; - } - else - { - stop_dma(); - } - } -} - -static void greenpak_start_dma() -{ - // Disable channels while configuring - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) &= ~DMA_CHXCTL_CHEN; - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_CHEN; - TIMER_CTL0(SCSI_TIMER) = 0; - - // Set buffer address and size - DMA_CHMADDR(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) = (uint32_t)g_scsi_dma.dma_buf; - DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) = DMA_BUF_SIZE; - - // Clear pending DMA events - TIMER_DMAINTEN(SCSI_TIMER) = 0; - TIMER_DMAINTEN(SCSI_TIMER) = TIMER_DMAINTEN_CH1DEN | TIMER_DMAINTEN_CH3DEN; - - // Clear and enable interrupt - DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_ERR, SCSI_TIMER_DMACHA); - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) |= DMA_CHXCTL_FTFIE | DMA_CHXCTL_HTFIE; - exti_interrupt_flag_clear(GREENPAK_PLD_IO2_EXTI); - exti_interrupt_enable(GREENPAK_PLD_IO2_EXTI); - - // Enable channels - DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) |= DMA_CHXCTL_CHEN; - - // Enable timer - TIMER_CNT(SCSI_TIMER) = 0; - TIMER_CTL0(SCSI_TIMER) |= TIMER_CTL0_CEN; - - // Generate first event - TIMER_SWEVG(SCSI_TIMER) = TIMER_SWEVG_CH1G; -} - -static void greenpak_stop_dma() -{ - exti_interrupt_disable(GREENPAK_PLD_IO2_EXTI); -} - -#endif diff --git a/lib/BlueSCSI_platform_GD32F205/scsi_accel_dma.h b/lib/BlueSCSI_platform_GD32F205/scsi_accel_dma.h deleted file mode 100644 index 49f63dff..00000000 --- a/lib/BlueSCSI_platform_GD32F205/scsi_accel_dma.h +++ /dev/null @@ -1,27 +0,0 @@ -// SCSI subroutines that use hardware DMA for transfer in the background. -// Uses either GD32 timer or external GreenPAK to implement REQ pin toggling. - -#pragma once - -#include -#include "BlueSCSI_platform.h" -#include "greenpak.h" - -#ifdef SCSI_TIMER -#define SCSI_ACCEL_DMA_AVAILABLE 1 -#endif - -/* Initialization function decides whether to use timer or GreenPAK */ -void scsi_accel_greenpak_dma_init(); -void scsi_accel_timer_dma_init(); - -/* Common functions */ -void scsi_accel_dma_startWrite(const uint8_t* data, uint32_t count, volatile int *resetFlag); -void scsi_accel_dma_stopWrite(); -void scsi_accel_dma_finishWrite(volatile int *resetFlag); - -// Query whether the data at pointer has already been read, i.e. buffer can be reused. -// If data is NULL, checks if all writes have completed. -bool scsi_accel_dma_isWriteFinished(const uint8_t* data); - - diff --git a/lib/BlueSCSI_platform_GD32F205/scsi_accel_greenpak.cpp b/lib/BlueSCSI_platform_GD32F205/scsi_accel_greenpak.cpp deleted file mode 100644 index 56265c8e..00000000 --- a/lib/BlueSCSI_platform_GD32F205/scsi_accel_greenpak.cpp +++ /dev/null @@ -1,365 +0,0 @@ -#include "scsi_accel_greenpak.h" -#include "BlueSCSI_platform.h" -#include -#include - -#ifndef GREENPAK_PLD_IO1 - -void scsi_accel_greenpak_send(const uint32_t *buf, uint32_t num_words, volatile int *resetFlag) -{ - assert(false); -} - -void scsi_accel_greenpak_recv(uint32_t *buf, uint32_t num_words, volatile int *resetFlag) -{ - assert(false); -} - -#else - -/*********************************************************/ -/* Optimized writes to SCSI bus in GREENPAK_PIO mode */ -/*********************************************************/ - -extern const uint32_t g_scsi_out_byte_to_bop_pld1hi[256]; -extern const uint32_t g_scsi_out_byte_to_bop_pld1lo[256]; - -// Optimized ASM blocks for the SCSI communication subroutine - -// Take 8 bits from d and format them for writing -// d is name of data operand, b is bit offset, x is unique label -#define ASM_LOAD_DATA_PLD1HI(d, b, x) \ -" load_data1_" x "_%=: \n" \ -" ubfx %[tmp1], %[" d "], #" b ", #8 \n" \ -" ldr %[tmp1], [%[byte_lookup_pld1hi], %[tmp1], lsl #2] \n" - -#define ASM_LOAD_DATA_PLD1LO(d, b, x) \ -" load_data1_" x "_%=: \n" \ -" ubfx %[tmp1], %[" d "], #" b ", #8 \n" \ -" ldr %[tmp1], [%[byte_lookup_pld1lo], %[tmp1], lsl #2] \n" - -// Write data to SCSI port -#define ASM_SEND_DATA(x) \ -" send_data" x "_%=: \n" \ -" str %[tmp1], [%[out_port_bop]] \n" - -// Wait for ACK to be low or REQ to be high. -// The external logic will set REQ low when PLD_IO1 is toggled and -// back high as soon as ACK goes low. New data can be written to -// GPIO as soon as ACK goes low. If an interrupt happens in the -// middle, we may miss the ACK pulse and should check REQ. -#define ASM_WAIT_DONE(x) \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], wait_done_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], wait_done_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], wait_done_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], wait_done_" x "_%= \n" \ -" wait_req_inactive_" x "_%=: \n" \ -" ldr %[tmp2], [%[req_pin_bb]] \n" \ -" cbnz %[tmp2], wait_done_" x "_%= \n" \ -" ldr %[tmp2], [%[reset_flag]] \n" \ -" cbnz %[tmp2], wait_done_" x "_%= \n" \ -" b.n wait_req_inactive_" x "_%= \n" \ -" wait_done_" x "_%=: \n" - -// Send bytes to SCSI bus using the asynchronous handshake mechanism -// Takes 4 bytes at a time for sending from buf. -void scsi_accel_greenpak_send(const uint32_t *buf, uint32_t num_words, volatile int *resetFlag) -{ - volatile uint32_t *out_port_bop = (volatile uint32_t*)&GPIO_BOP(SCSI_OUT_PORT); - uint32_t ack_pin_bb = PERIPH_BB_BASE + (((uint32_t)&GPIO_ISTAT(SCSI_ACK_PORT)) - APB1_BUS_BASE) * 32 + SCSI_IN_ACK_IDX * 4; - uint32_t req_pin_bb = PERIPH_BB_BASE + (((uint32_t)&GPIO_ISTAT(SCSI_OUT_PORT)) - APB1_BUS_BASE) * 32 + SCSI_OUT_REQ_IDX * 4; - register uint32_t tmp1 = 0; - register uint32_t tmp2 = 0; - register uint32_t data = 0; - - // Set REQ pin as input and PLD_IO2 high to enable logic - GPIO_BC(SCSI_OUT_PORT) = GREENPAK_PLD_IO1; - gpio_init(SCSI_OUT_PORT, GPIO_MODE_IPU, 0, SCSI_OUT_REQ); - GPIO_BOP(SCSI_OUT_PORT) = GREENPAK_PLD_IO2; - - asm volatile ( - " ldr %[data], [%[buf]], #4 \n" \ - ASM_LOAD_DATA_PLD1HI("data", "0", "first") - - "inner_loop_%=: \n" \ - ASM_SEND_DATA("0") - ASM_LOAD_DATA_PLD1LO("data", "8", "8") - ASM_WAIT_DONE("0") - - ASM_SEND_DATA("8") - ASM_LOAD_DATA_PLD1HI("data", "16", "16") - ASM_WAIT_DONE("8") - - ASM_SEND_DATA("16") - ASM_LOAD_DATA_PLD1LO("data", "24", "24") - ASM_WAIT_DONE("16") - - ASM_SEND_DATA("24") - " ldr %[data], [%[buf]], #4 \n" \ - ASM_LOAD_DATA_PLD1HI("data", "0", "0") - ASM_WAIT_DONE("24") - - " subs %[num_words], %[num_words], #1 \n" \ - " bne inner_loop_%= \n" - : /* Output */ [tmp1] "+l" (tmp1), [tmp2] "+l" (tmp2), [data] "+r" (data), - [buf] "+r" (buf), [num_words] "+r" (num_words) - : /* Input */ [ack_pin_bb] "r" (ack_pin_bb), - [req_pin_bb] "r" (req_pin_bb), - [out_port_bop] "r"(out_port_bop), - [byte_lookup_pld1hi] "r" (g_scsi_out_byte_to_bop_pld1hi), - [byte_lookup_pld1lo] "r" (g_scsi_out_byte_to_bop_pld1lo), - [reset_flag] "r" (resetFlag) - : /* Clobber */ ); - - SCSI_RELEASE_DATA_REQ(); - - // Disable external logic and set REQ pin as output - GPIO_BC(SCSI_OUT_PORT) = GREENPAK_PLD_IO2; - gpio_init(SCSI_OUT_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_REQ); -} - -/**********************************************/ -/* Mapping from data bytes to GPIO BOP values */ -/**********************************************/ - -#define PARITY(n) ((1 ^ (n) ^ ((n)>>1) ^ ((n)>>2) ^ ((n)>>3) ^ ((n)>>4) ^ ((n)>>5) ^ ((n)>>6) ^ ((n)>>7)) & 1) -#define X(n) (\ - ((n & 0x01) ? (SCSI_OUT_DB0 << 16) : SCSI_OUT_DB0) | \ - ((n & 0x02) ? (SCSI_OUT_DB1 << 16) : SCSI_OUT_DB1) | \ - ((n & 0x04) ? (SCSI_OUT_DB2 << 16) : SCSI_OUT_DB2) | \ - ((n & 0x08) ? (SCSI_OUT_DB3 << 16) : SCSI_OUT_DB3) | \ - ((n & 0x10) ? (SCSI_OUT_DB4 << 16) : SCSI_OUT_DB4) | \ - ((n & 0x20) ? (SCSI_OUT_DB5 << 16) : SCSI_OUT_DB5) | \ - ((n & 0x40) ? (SCSI_OUT_DB6 << 16) : SCSI_OUT_DB6) | \ - ((n & 0x80) ? (SCSI_OUT_DB7 << 16) : SCSI_OUT_DB7) | \ - (PARITY(n) ? (SCSI_OUT_DBP << 16) : SCSI_OUT_DBP) | \ - (GREENPAK_PLD_IO1) \ -) - -const uint32_t g_scsi_out_byte_to_bop_pld1hi[256] = -{ - X(0x00), X(0x01), X(0x02), X(0x03), X(0x04), X(0x05), X(0x06), X(0x07), X(0x08), X(0x09), X(0x0a), X(0x0b), X(0x0c), X(0x0d), X(0x0e), X(0x0f), - X(0x10), X(0x11), X(0x12), X(0x13), X(0x14), X(0x15), X(0x16), X(0x17), X(0x18), X(0x19), X(0x1a), X(0x1b), X(0x1c), X(0x1d), X(0x1e), X(0x1f), - X(0x20), X(0x21), X(0x22), X(0x23), X(0x24), X(0x25), X(0x26), X(0x27), X(0x28), X(0x29), X(0x2a), X(0x2b), X(0x2c), X(0x2d), X(0x2e), X(0x2f), - X(0x30), X(0x31), X(0x32), X(0x33), X(0x34), X(0x35), X(0x36), X(0x37), X(0x38), X(0x39), X(0x3a), X(0x3b), X(0x3c), X(0x3d), X(0x3e), X(0x3f), - X(0x40), X(0x41), X(0x42), X(0x43), X(0x44), X(0x45), X(0x46), X(0x47), X(0x48), X(0x49), X(0x4a), X(0x4b), X(0x4c), X(0x4d), X(0x4e), X(0x4f), - X(0x50), X(0x51), X(0x52), X(0x53), X(0x54), X(0x55), X(0x56), X(0x57), X(0x58), X(0x59), X(0x5a), X(0x5b), X(0x5c), X(0x5d), X(0x5e), X(0x5f), - X(0x60), X(0x61), X(0x62), X(0x63), X(0x64), X(0x65), X(0x66), X(0x67), X(0x68), X(0x69), X(0x6a), X(0x6b), X(0x6c), X(0x6d), X(0x6e), X(0x6f), - X(0x70), X(0x71), X(0x72), X(0x73), X(0x74), X(0x75), X(0x76), X(0x77), X(0x78), X(0x79), X(0x7a), X(0x7b), X(0x7c), X(0x7d), X(0x7e), X(0x7f), - X(0x80), X(0x81), X(0x82), X(0x83), X(0x84), X(0x85), X(0x86), X(0x87), X(0x88), X(0x89), X(0x8a), X(0x8b), X(0x8c), X(0x8d), X(0x8e), X(0x8f), - X(0x90), X(0x91), X(0x92), X(0x93), X(0x94), X(0x95), X(0x96), X(0x97), X(0x98), X(0x99), X(0x9a), X(0x9b), X(0x9c), X(0x9d), X(0x9e), X(0x9f), - X(0xa0), X(0xa1), X(0xa2), X(0xa3), X(0xa4), X(0xa5), X(0xa6), X(0xa7), X(0xa8), X(0xa9), X(0xaa), X(0xab), X(0xac), X(0xad), X(0xae), X(0xaf), - X(0xb0), X(0xb1), X(0xb2), X(0xb3), X(0xb4), X(0xb5), X(0xb6), X(0xb7), X(0xb8), X(0xb9), X(0xba), X(0xbb), X(0xbc), X(0xbd), X(0xbe), X(0xbf), - X(0xc0), X(0xc1), X(0xc2), X(0xc3), X(0xc4), X(0xc5), X(0xc6), X(0xc7), X(0xc8), X(0xc9), X(0xca), X(0xcb), X(0xcc), X(0xcd), X(0xce), X(0xcf), - X(0xd0), X(0xd1), X(0xd2), X(0xd3), X(0xd4), X(0xd5), X(0xd6), X(0xd7), X(0xd8), X(0xd9), X(0xda), X(0xdb), X(0xdc), X(0xdd), X(0xde), X(0xdf), - X(0xe0), X(0xe1), X(0xe2), X(0xe3), X(0xe4), X(0xe5), X(0xe6), X(0xe7), X(0xe8), X(0xe9), X(0xea), X(0xeb), X(0xec), X(0xed), X(0xee), X(0xef), - X(0xf0), X(0xf1), X(0xf2), X(0xf3), X(0xf4), X(0xf5), X(0xf6), X(0xf7), X(0xf8), X(0xf9), X(0xfa), X(0xfb), X(0xfc), X(0xfd), X(0xfe), X(0xff) -}; - -#undef X - -#define X(n) (\ - ((n & 0x01) ? (SCSI_OUT_DB0 << 16) : SCSI_OUT_DB0) | \ - ((n & 0x02) ? (SCSI_OUT_DB1 << 16) : SCSI_OUT_DB1) | \ - ((n & 0x04) ? (SCSI_OUT_DB2 << 16) : SCSI_OUT_DB2) | \ - ((n & 0x08) ? (SCSI_OUT_DB3 << 16) : SCSI_OUT_DB3) | \ - ((n & 0x10) ? (SCSI_OUT_DB4 << 16) : SCSI_OUT_DB4) | \ - ((n & 0x20) ? (SCSI_OUT_DB5 << 16) : SCSI_OUT_DB5) | \ - ((n & 0x40) ? (SCSI_OUT_DB6 << 16) : SCSI_OUT_DB6) | \ - ((n & 0x80) ? (SCSI_OUT_DB7 << 16) : SCSI_OUT_DB7) | \ - (PARITY(n) ? (SCSI_OUT_DBP << 16) : SCSI_OUT_DBP) | \ - (GREENPAK_PLD_IO1 << 16) \ -) - -const uint32_t g_scsi_out_byte_to_bop_pld1lo[256] = -{ - X(0x00), X(0x01), X(0x02), X(0x03), X(0x04), X(0x05), X(0x06), X(0x07), X(0x08), X(0x09), X(0x0a), X(0x0b), X(0x0c), X(0x0d), X(0x0e), X(0x0f), - X(0x10), X(0x11), X(0x12), X(0x13), X(0x14), X(0x15), X(0x16), X(0x17), X(0x18), X(0x19), X(0x1a), X(0x1b), X(0x1c), X(0x1d), X(0x1e), X(0x1f), - X(0x20), X(0x21), X(0x22), X(0x23), X(0x24), X(0x25), X(0x26), X(0x27), X(0x28), X(0x29), X(0x2a), X(0x2b), X(0x2c), X(0x2d), X(0x2e), X(0x2f), - X(0x30), X(0x31), X(0x32), X(0x33), X(0x34), X(0x35), X(0x36), X(0x37), X(0x38), X(0x39), X(0x3a), X(0x3b), X(0x3c), X(0x3d), X(0x3e), X(0x3f), - X(0x40), X(0x41), X(0x42), X(0x43), X(0x44), X(0x45), X(0x46), X(0x47), X(0x48), X(0x49), X(0x4a), X(0x4b), X(0x4c), X(0x4d), X(0x4e), X(0x4f), - X(0x50), X(0x51), X(0x52), X(0x53), X(0x54), X(0x55), X(0x56), X(0x57), X(0x58), X(0x59), X(0x5a), X(0x5b), X(0x5c), X(0x5d), X(0x5e), X(0x5f), - X(0x60), X(0x61), X(0x62), X(0x63), X(0x64), X(0x65), X(0x66), X(0x67), X(0x68), X(0x69), X(0x6a), X(0x6b), X(0x6c), X(0x6d), X(0x6e), X(0x6f), - X(0x70), X(0x71), X(0x72), X(0x73), X(0x74), X(0x75), X(0x76), X(0x77), X(0x78), X(0x79), X(0x7a), X(0x7b), X(0x7c), X(0x7d), X(0x7e), X(0x7f), - X(0x80), X(0x81), X(0x82), X(0x83), X(0x84), X(0x85), X(0x86), X(0x87), X(0x88), X(0x89), X(0x8a), X(0x8b), X(0x8c), X(0x8d), X(0x8e), X(0x8f), - X(0x90), X(0x91), X(0x92), X(0x93), X(0x94), X(0x95), X(0x96), X(0x97), X(0x98), X(0x99), X(0x9a), X(0x9b), X(0x9c), X(0x9d), X(0x9e), X(0x9f), - X(0xa0), X(0xa1), X(0xa2), X(0xa3), X(0xa4), X(0xa5), X(0xa6), X(0xa7), X(0xa8), X(0xa9), X(0xaa), X(0xab), X(0xac), X(0xad), X(0xae), X(0xaf), - X(0xb0), X(0xb1), X(0xb2), X(0xb3), X(0xb4), X(0xb5), X(0xb6), X(0xb7), X(0xb8), X(0xb9), X(0xba), X(0xbb), X(0xbc), X(0xbd), X(0xbe), X(0xbf), - X(0xc0), X(0xc1), X(0xc2), X(0xc3), X(0xc4), X(0xc5), X(0xc6), X(0xc7), X(0xc8), X(0xc9), X(0xca), X(0xcb), X(0xcc), X(0xcd), X(0xce), X(0xcf), - X(0xd0), X(0xd1), X(0xd2), X(0xd3), X(0xd4), X(0xd5), X(0xd6), X(0xd7), X(0xd8), X(0xd9), X(0xda), X(0xdb), X(0xdc), X(0xdd), X(0xde), X(0xdf), - X(0xe0), X(0xe1), X(0xe2), X(0xe3), X(0xe4), X(0xe5), X(0xe6), X(0xe7), X(0xe8), X(0xe9), X(0xea), X(0xeb), X(0xec), X(0xed), X(0xee), X(0xef), - X(0xf0), X(0xf1), X(0xf2), X(0xf3), X(0xf4), X(0xf5), X(0xf6), X(0xf7), X(0xf8), X(0xf9), X(0xfa), X(0xfb), X(0xfc), X(0xfd), X(0xfe), X(0xff) -}; - -#undef X - -/*********************************************************/ -/* Optimized reads from SCSI bus in GREENPAK_PIO mode */ -/*********************************************************/ - -// Wait for ACK to go high and back low. -// This indicates that there is a byte ready to be read -// If interrupt occurs in middle, we may miss ACK going high. -// In that case, verify that REQ is already low. -#define ASM_WAIT_ACK(x) \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbnz %[tmp2], ack_is_high_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbnz %[tmp2], ack_is_high_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbnz %[tmp2], ack_is_high_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbnz %[tmp2], ack_is_high_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbnz %[tmp2], ack_is_high_" x "_%= \n" \ -" wait_req_low_" x "_%=: \n" \ -" cpsid i \n" \ -" ldr %[tmp2], [%[req_pin_bb]] \n" \ -" cbz %[tmp2], ack_is_high_" x "_%= \n" \ -" ldr %[tmp2], [%[reset_flag]] \n" \ -" cbnz %[tmp2], ack_is_high_" x "_%= \n" \ -" cpsie i \n" \ -" b.n wait_req_low_" x "_%= \n" \ -" ack_is_high_" x "_%=: \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], ack_is_low_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], ack_is_low_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], ack_is_low_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], ack_is_low_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], ack_is_low_" x "_%= \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], ack_is_low_" x "_%= \n" \ -" wait_ack_low_" x "_%=: \n" \ -" cpsid i \n" \ -" ldr %[tmp2], [%[ack_pin_bb]] \n" \ -" cbz %[tmp2], ack_is_low_" x "_%= \n" \ -" ldr %[tmp2], [%[reset_flag]] \n" \ -" cbnz %[tmp2], ack_is_low_" x "_%= \n" \ -" cpsie i \n" \ -" b.n wait_ack_low_" x "_%= \n" \ -" ack_is_low_" x "_%=: \n" - -// Prepare for reception of data by loading the next PLD_IO1 value -// and disabling interrupts. -#define ASM_PREP_RECV(l) \ -" mov %[tmp1], %[" l "] \n" \ -" cpsid i \n" - -// Read GPIO bus, take the data byte and toggle PLD_IO1. -// Note that the PLD_IO1 write is done first to reduce latency, but -// the istat value that is read by next instruction is still the old -// one due to IO port delays. Interrupts must be disabled for this -// sequence to work correctly. -// -// d is the name of register where data is to be stored -// b is the bit offset to store the byte at -// x is unique label -#define ASM_RECV_DATA(d, b, x) \ -" read_data_" x "_%=: \n" \ -" str %[tmp1], [%[out_port_bop]] \n" \ -" ldr %[tmp1], [%[in_port_istat]] \n" \ -" ubfx %[tmp1], %[tmp1], %[data_in_shift], #8 \n" \ -" bfi %[" d "], %[tmp1], #" b ", #8 \n" \ -" cpsie i \n" - -// Read bytes from SCSI bus using asynchronous handshake mechanism -// Takes 4 bytes at a time. -void scsi_accel_greenpak_recv(uint32_t *buf, uint32_t num_words, volatile int *resetFlag) -{ - volatile uint32_t *out_port_bop = (volatile uint32_t*)&GPIO_BOP(SCSI_OUT_PORT); - volatile uint32_t *in_port_istat = (volatile uint32_t*)&GPIO_ISTAT(SCSI_IN_PORT); - uint32_t ack_pin_bb = PERIPH_BB_BASE + (((uint32_t)&GPIO_ISTAT(SCSI_ACK_PORT)) - APB1_BUS_BASE) * 32 + SCSI_IN_ACK_IDX * 4; - uint32_t req_pin_bb = PERIPH_BB_BASE + (((uint32_t)&GPIO_ISTAT(SCSI_OUT_PORT)) - APB1_BUS_BASE) * 32 + SCSI_OUT_REQ_IDX * 4; - register uint32_t tmp1 = 0; - register uint32_t tmp2 = 0; - register uint32_t data = 0; - - // Last word requires special handling so that hardware doesn't issue new REQ pulse. - assert(num_words >= 2); - num_words -= 1; - - // Set PLD_IO3 high to enable read from SCSI bus - GPIO_BOP(SCSI_OUT_PORT) = GREENPAK_PLD_IO3; - - // Make sure that the previous access has fully completed. - // E.g. Macintosh can hold ACK low for long time after last byte of block. - while (SCSI_IN(ACK) && !*resetFlag); - - // Set REQ pin as input and PLD_IO2 high to enable logic - GPIO_BC(SCSI_OUT_PORT) = GREENPAK_PLD_IO1; - gpio_init(SCSI_OUT_PORT, GPIO_MODE_IPU, 0, SCSI_OUT_REQ); - GPIO_BOP(SCSI_OUT_PORT) = GREENPAK_PLD_IO2; - - asm volatile ( - "inner_loop_%=: \n" - ASM_PREP_RECV("pld1_hi") - ASM_WAIT_ACK("0") - ASM_RECV_DATA("data", "0", "0") - - ASM_PREP_RECV("pld1_lo") - ASM_WAIT_ACK("8") - ASM_RECV_DATA("data", "8", "8") - - ASM_PREP_RECV("pld1_hi") - ASM_WAIT_ACK("16") - ASM_RECV_DATA("data", "16", "16") - - ASM_PREP_RECV("pld1_lo") - ASM_WAIT_ACK("24") - ASM_RECV_DATA("data", "24", "24") - - " mvn %[data], %[data] \n" - " str %[data], [%[buf]], #4 \n" - " subs %[num_words], %[num_words], #1 \n" - " bne inner_loop_%= \n" - - // Process last word separately to avoid issuing extra REQ pulse at end. - "recv_last_word_%=: \n" - ASM_PREP_RECV("pld1_hi") - ASM_WAIT_ACK("0b") - ASM_RECV_DATA("data", "0", "0b") - - ASM_PREP_RECV("pld1_lo") - ASM_WAIT_ACK("8b") - ASM_RECV_DATA("data", "8", "8b") - - ASM_PREP_RECV("pld1_hi") - ASM_WAIT_ACK("16b") - ASM_RECV_DATA("data", "16", "16b") - - ASM_PREP_RECV("pld1_hi") - ASM_WAIT_ACK("24b") - ASM_RECV_DATA("data", "24", "24b") - - " mvn %[data], %[data] \n" - " str %[data], [%[buf]], #4 \n" - - : /* Output */ [tmp1] "+l" (tmp1), [tmp2] "+l" (tmp2), [data] "+r" (data), - [buf] "+r" (buf), [num_words] "+r" (num_words) - : /* Input */ [ack_pin_bb] "r" (ack_pin_bb), - [req_pin_bb] "r" (req_pin_bb), - [out_port_bop] "r"(out_port_bop), - [in_port_istat] "r" (in_port_istat), - [reset_flag] "r" (resetFlag), - [data_in_shift] "I" (SCSI_IN_SHIFT), - [pld1_lo] "I" (SCSI_OUT_PLD1 << 16), - [pld1_hi] "I" (SCSI_OUT_PLD1) - : /* Clobber */ ); - - SCSI_RELEASE_DATA_REQ(); - - // Disable external logic and set REQ pin as output - GPIO_BC(SCSI_OUT_PORT) = GREENPAK_PLD_IO2; - gpio_init(SCSI_OUT_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_REQ); - GPIO_BC(SCSI_OUT_PORT) = GREENPAK_PLD_IO3; -} - -#endif diff --git a/lib/BlueSCSI_platform_GD32F205/scsi_accel_greenpak.h b/lib/BlueSCSI_platform_GD32F205/scsi_accel_greenpak.h deleted file mode 100644 index 043689db..00000000 --- a/lib/BlueSCSI_platform_GD32F205/scsi_accel_greenpak.h +++ /dev/null @@ -1,9 +0,0 @@ -// SCSI subroutines using external GreenPAK logic chip for acceleration - -#pragma once - -#include -#include "greenpak.h" - -void scsi_accel_greenpak_send(const uint32_t *buf, uint32_t num_words, volatile int *resetFlag); -void scsi_accel_greenpak_recv(uint32_t *buf, uint32_t num_words, volatile int *resetFlag); \ No newline at end of file diff --git a/lib/BlueSCSI_platform_GD32F205/scsi_accel_sync.cpp b/lib/BlueSCSI_platform_GD32F205/scsi_accel_sync.cpp deleted file mode 100644 index 9477ac8c..00000000 --- a/lib/BlueSCSI_platform_GD32F205/scsi_accel_sync.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* Synchronous mode SCSI implementation. - * - * In synchronous mode, the handshake mechanism is not used. Instead - * either end of the communication will just send a bunch of bytes - * and only afterwards checks that the number of acknowledgement - * pulses matches. - * - * The receiving end should latch in the data at the falling edge of - * the request pulse (on either REQ or ACK pin). We use the GD32 EXMC - * peripheral to implement this latching with the NWAIT pin when - * reading data from the host. NOE is used to generate the REQ pulses. - * - * Writing data to the host is simpler, as we can just write it out - * from the GPIO port at our own pace. A timer is used for generating - * the output pulses on REQ pin. - */ - -#include "scsi_accel_sync.h" -#include -#include -#include - -#ifndef SCSI_SYNC_MODE_AVAILABLE - -void scsi_accel_sync_init() {} - -void scsi_accel_sync_recv(uint8_t *data, uint32_t count, int* parityError, volatile int *resetFlag) {} -void scsi_accel_sync_send(const uint8_t* data, uint32_t count, volatile int *resetFlag) {} - -#else - -/********************************/ -/* Transfer from host to device */ -/********************************/ - -#define SYNC_DMA_BUFSIZE 512 -static uint32_t g_sync_dma_buf[SYNC_DMA_BUFSIZE]; - -void scsi_accel_sync_init() -{ - rcu_periph_clock_enable(RCU_EXMC); - rcu_periph_clock_enable(SCSI_EXMC_DMA_RCU); - rcu_periph_clock_enable(SCSI_SYNC_TIMER_RCU); - - exmc_norsram_timing_parameter_struct timing_param = { - .asyn_access_mode = EXMC_ACCESS_MODE_A, - .syn_data_latency = EXMC_DATALAT_2_CLK, - .syn_clk_division = EXMC_SYN_CLOCK_RATIO_2_CLK, - .bus_latency = 1, - .asyn_data_setuptime = 2, - .asyn_address_holdtime = 2, - .asyn_address_setuptime = 16 - }; - - exmc_norsram_parameter_struct sram_param = { - .norsram_region = EXMC_BANK0_NORSRAM_REGION0, - .write_mode = EXMC_ASYN_WRITE, - .extended_mode = DISABLE, - .asyn_wait = ENABLE, - .nwait_signal = ENABLE, - .memory_write = DISABLE, - .nwait_config = EXMC_NWAIT_CONFIG_DURING, - .wrap_burst_mode = DISABLE, - .nwait_polarity = EXMC_NWAIT_POLARITY_HIGH, - .burst_mode = DISABLE, - .databus_width = EXMC_NOR_DATABUS_WIDTH_16B, - .memory_type = EXMC_MEMORY_TYPE_SRAM, - .address_data_mux = DISABLE, - .read_write_timing = &timing_param - }; - - EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_SNCTL_NRBKEN; - exmc_norsram_init(&sram_param); - - // DMA used to transfer data from EXMC to RAM - // DMA is used so that if data transfer fails, we can at least abort by resetting CPU. - // Accessing EXMC from the CPU directly hangs it totally if ACK pulses are not received. - dma_parameter_struct exmc_dma_config = - { - .periph_addr = EXMC_NOR_PSRAM, - .periph_width = DMA_PERIPHERAL_WIDTH_16BIT, - .memory_addr = (uint32_t)g_sync_dma_buf, - .memory_width = DMA_MEMORY_WIDTH_16BIT, - .number = 0, // Filled before transfer - .priority = DMA_PRIORITY_MEDIUM, - .periph_inc = DMA_PERIPH_INCREASE_DISABLE, - .memory_inc = DMA_MEMORY_INCREASE_ENABLE, - .direction = DMA_PERIPHERAL_TO_MEMORY - }; - dma_init(SCSI_EXMC_DMA, SCSI_EXMC_DMACH, &exmc_dma_config); - dma_memory_to_memory_enable(SCSI_EXMC_DMA, SCSI_EXMC_DMACH); - - gpio_init(SCSI_IN_ACK_EXMC_NWAIT_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_IN_ACK_EXMC_NWAIT_PIN); - gpio_init(SCSI_TIMER_IN_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_TIMER_IN_PIN); - - // TIMER1 is used to count ACK pulses - TIMER_CTL0(SCSI_SYNC_TIMER) = 0; - TIMER_SMCFG(SCSI_SYNC_TIMER) = TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_CI0FE0; - TIMER_CAR(SCSI_SYNC_TIMER) = 65535; - TIMER_PSC(SCSI_SYNC_TIMER) = 0; - TIMER_CHCTL0(SCSI_SYNC_TIMER) = 0x0001; // CH0 as input -} - -void scsi_accel_sync_recv(uint8_t *data, uint32_t count, int* parityError, volatile int *resetFlag) -{ - // Enable EXMC to drive REQ from EXMC_NOE pin - EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= EXMC_SNCTL_NRBKEN; - uint32_t oldmode = GPIO_CTL0(SCSI_OUT_REQ_EXMC_NOE_PORT); - uint32_t newmode = oldmode & ~(0xF << (SCSI_OUT_REQ_EXMC_NOE_IDX * 4)); - newmode |= 0xB << (SCSI_OUT_REQ_EXMC_NOE_IDX * 4); - GPIO_CTL0(SCSI_OUT_REQ_EXMC_NOE_PORT) = newmode; - - while (count > 0) - { - uint32_t blocksize = (count > SYNC_DMA_BUFSIZE * 2) ? (SYNC_DMA_BUFSIZE * 2) : count; - count -= blocksize; - - DMA_CHCNT(SCSI_EXMC_DMA, SCSI_EXMC_DMACH) = blocksize; - DMA_CHCTL(SCSI_EXMC_DMA, SCSI_EXMC_DMACH) |= DMA_CHXCTL_CHEN; - - uint16_t *src = (uint16_t*)g_sync_dma_buf; - uint8_t *dst = data; - uint8_t *end = data + blocksize; - uint32_t start = millis(); - while (dst < end) - { - uint32_t remain = DMA_CHCNT(SCSI_EXMC_DMA, SCSI_EXMC_DMACH); - - while (dst < end - remain) - { - *dst++ = ~(*src++) >> SCSI_EXMC_DATA_SHIFT; - } - - if ((uint32_t)(millis() - start) > 500 || *resetFlag) - { - // We are in a pinch here: without ACK pulses coming, the EXMC and DMA peripherals - // are locked up. The only way out is a whole system reset. - bluelog("SCSI Synchronous read timeout: resetting system"); - NVIC_SystemReset(); - } - } - - DMA_CHCTL(SCSI_EXMC_DMA, SCSI_EXMC_DMACH) &= ~DMA_CHXCTL_CHEN; - data = end; - } - - GPIO_CTL0(SCSI_OUT_REQ_EXMC_NOE_PORT) = oldmode; - EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_SNCTL_NRBKEN; -} - -/********************************/ -/* Transfer from device to host */ -/********************************/ - -// Simple delay, about 20 ns. -// This is less likely to get optimized away by CPU pipeline than nop -#define ASM_DELAY() \ -" ldr %[tmp2], [%[reset_flag]] \n" - -// Take 8 bits from d and format them for writing -// d is name of data operand, b is bit offset -#define ASM_LOAD_DATA(b) \ -" ubfx %[tmp1], %[data], #" b ", #8 \n" \ -" ldr %[tmp1], [%[byte_lookup], %[tmp1], lsl #2] \n" - -// Write data to SCSI port and set REQ high -#define ASM_SEND_DATA() \ -" str %[tmp1], [%[out_port_bop]] \n" - -// Set REQ low -#define ASM_SET_REQ_LOW() \ -" mov %[tmp2], %[bop_req_low] \n" \ -" str %[tmp2], [%[out_port_bop]] \n" - -// Wait for ACK_TIMER - n to be less than num_bytes -#define ASM_WAIT_ACK_TIMER(n) \ - "wait_acks_" n "_%=: \n" \ - " ldr %[tmp2], [%[ack_timer]] \n" \ - " sub %[tmp2], # " n " \n" \ - " cmp %[tmp2], %[num_bytes] \n" \ - " ble got_acks_" n "_%= \n" \ - " ldr %[tmp2], [%[reset_flag]] \n" \ - " cmp %[tmp2], #0 \n" \ - " bne all_done_%= \n" \ - " b wait_acks_" n "_%= \n" \ - "got_acks_" n "_%=: \n" - -// Send 4 bytes -#define ASM_SEND_4BYTES() \ -ASM_LOAD_DATA("0") \ -ASM_SEND_DATA() \ -ASM_DELAY1() \ -ASM_SET_REQ_LOW() \ -ASM_DELAY2() \ -ASM_LOAD_DATA("8") \ -ASM_SEND_DATA() \ -ASM_DELAY1() \ -ASM_SET_REQ_LOW() \ -ASM_DELAY2() \ -ASM_LOAD_DATA("16") \ -ASM_SEND_DATA() \ -ASM_DELAY1() \ -ASM_SET_REQ_LOW() \ -ASM_DELAY2() \ -ASM_LOAD_DATA("24") \ -ASM_SEND_DATA() \ -ASM_DELAY1() \ -ASM_SET_REQ_LOW() - -// Send 1 byte, wait for ACK_TIMER to be less than num_bytes + n and send 3 bytes more -// This interleaving minimizes the delay caused by WAIT_ACK_TIMER. -#define ASM_SEND_4BYTES_WAIT(n) \ -ASM_LOAD_DATA("0") \ -ASM_SEND_DATA() \ -ASM_DELAY2() \ -ASM_LOAD_DATA("8") \ -ASM_SET_REQ_LOW() \ -ASM_DELAY2() \ -" ldr %[tmp2], [%[ack_timer]] \n" \ -" sub %[tmp2], # " n " \n" \ -ASM_SEND_DATA() \ -" cmp %[tmp2], %[num_bytes] \n" \ -" ble got_acks_" n "_%= \n" \ -ASM_WAIT_ACK_TIMER(n) \ -ASM_DELAY2() \ -ASM_SET_REQ_LOW() \ -ASM_DELAY2() \ -ASM_LOAD_DATA("16") \ -ASM_SEND_DATA() \ -ASM_DELAY1() \ -ASM_SET_REQ_LOW() \ -ASM_DELAY2() \ -ASM_LOAD_DATA("24") \ -ASM_SEND_DATA() \ -ASM_DELAY1() \ -ASM_SET_REQ_LOW() \ - -// Specialized routine for settings: -// <=100 ns period, >=15 outstanding REQs -static void sync_send_100ns_15off(const uint8_t *buf, uint32_t num_bytes, volatile int *resetFlag) -{ - volatile uint32_t *out_port_bop = (volatile uint32_t*)&GPIO_BOP(SCSI_OUT_PORT); - volatile uint32_t *ack_timer = &TIMER_CNT(SCSI_SYNC_TIMER); - const uint32_t *byte_lookup = g_scsi_out_byte_to_bop; - register uint32_t tmp1 = 0; - register uint32_t tmp2 = 0; - register uint32_t data = 0; - -// Delay 1 is typically longest and delay 2 shortest. -// Tuning these is just trial and error. -#define ASM_DELAY1() " nop\n nop\n nop\n" -#define ASM_DELAY2() " nop\n nop\n" - - asm volatile ( - "main_loop_%=: \n" - " subs %[num_bytes], %[num_bytes], #16 \n" - " bmi last_bytes_%= \n" - - /* At each point make sure there is at most 15 bytes in flight */ - " ldr %[data], [%[buf]], #4 \n" - ASM_SEND_4BYTES_WAIT("22") - " ldr %[data], [%[buf]], #4 \n" - ASM_SEND_4BYTES() - " ldr %[data], [%[buf]], #4 \n" - ASM_SEND_4BYTES_WAIT("14") - " ldr %[data], [%[buf]], #4 \n" - ASM_SEND_4BYTES() - - " cbz %[num_bytes], all_done_%= \n" - " b main_loop_%= \n" - - "last_bytes_%=: \n" - " add %[num_bytes], %[num_bytes], #16 \n" - "last_bytes_loop_%=: \n" - " ldrb %[data], [%[buf]], #1 \n" - ASM_LOAD_DATA("0") - - ASM_WAIT_ACK_TIMER("15") - ASM_SEND_DATA() - ASM_DELAY1() - ASM_SET_REQ_LOW() - - " subs %[num_bytes], %[num_bytes], #1 \n" - " bne last_bytes_loop_%= \n" - "all_done_%=: \n" - ASM_DELAY() - - : /* Output */ [tmp1] "+l" (tmp1), [tmp2] "+l" (tmp2), [data] "+r" (data), - [buf] "+r" (buf), [num_bytes] "+r" (num_bytes) - : /* Input */ [ack_timer] "r" (ack_timer), - [bop_req_low] "I" (SCSI_OUT_REQ << 16), - [out_port_bop] "r"(out_port_bop), - [byte_lookup] "r" (byte_lookup), - [reset_flag] "r" (resetFlag) - : /* Clobber */); - -#undef ASM_DELAY1 -#undef ASM_DELAY2 - - SCSI_RELEASE_DATA_REQ(); -} - -// Specialized routine for settings: -// <=200 ns period, >=15 outstanding REQs -static void sync_send_200ns_15off(const uint8_t *buf, uint32_t num_bytes, volatile int *resetFlag) -{ - volatile uint32_t *out_port_bop = (volatile uint32_t*)&GPIO_BOP(SCSI_OUT_PORT); - volatile uint32_t *ack_timer = &TIMER_CNT(SCSI_SYNC_TIMER); - const uint32_t *byte_lookup = g_scsi_out_byte_to_bop; - register uint32_t tmp1 = 0; - register uint32_t tmp2 = 0; - register uint32_t data = 0; - -#define ASM_DELAY1() ASM_DELAY() ASM_DELAY() ASM_DELAY() ASM_DELAY() -#define ASM_DELAY2() ASM_DELAY() ASM_DELAY() ASM_DELAY() - - asm volatile ( - "main_loop_%=: \n" - " subs %[num_bytes], %[num_bytes], #16 \n" - " bmi last_bytes_%= \n" - - /* At each point make sure there is at most 15 bytes in flight */ - " ldr %[data], [%[buf]], #4 \n" - ASM_SEND_4BYTES_WAIT("22") - ASM_DELAY2() - " ldr %[data], [%[buf]], #4 \n" - ASM_SEND_4BYTES() - ASM_DELAY2() - " ldr %[data], [%[buf]], #4 \n" - ASM_SEND_4BYTES_WAIT("14") - ASM_DELAY2() - " ldr %[data], [%[buf]], #4 \n" - ASM_SEND_4BYTES() - - " cbz %[num_bytes], all_done_%= \n" - " b main_loop_%= \n" - - "last_bytes_%=: \n" - " add %[num_bytes], %[num_bytes], #16 \n" - "last_bytes_loop_%=: \n" - " ldrb %[data], [%[buf]], #1 \n" - ASM_LOAD_DATA("0") - - ASM_WAIT_ACK_TIMER("15") - ASM_SEND_DATA() - ASM_DELAY1() - ASM_SET_REQ_LOW() - ASM_DELAY2() - - " subs %[num_bytes], %[num_bytes], #1 \n" - " bne last_bytes_loop_%= \n" - "all_done_%=: \n" - ASM_DELAY1() - - : /* Output */ [tmp1] "+l" (tmp1), [tmp2] "+l" (tmp2), [data] "+r" (data), - [buf] "+r" (buf), [num_bytes] "+r" (num_bytes) - : /* Input */ [ack_timer] "r" (ack_timer), - [bop_req_low] "I" (SCSI_OUT_REQ << 16), - [out_port_bop] "r"(out_port_bop), - [byte_lookup] "r" (byte_lookup), - [reset_flag] "r" (resetFlag) - : /* Clobber */); - -#undef ASM_DELAY1 -#undef ASM_DELAY2 - - SCSI_RELEASE_DATA_REQ(); -} - -// Specialized routine for settings: -// <=260 ns period, >=7 outstanding REQs -static void sync_send_260ns_7off(const uint8_t *buf, uint32_t num_bytes, volatile int *resetFlag) -{ - volatile uint32_t *out_port_bop = (volatile uint32_t*)&GPIO_BOP(SCSI_OUT_PORT); - volatile uint32_t *ack_timer = &TIMER_CNT(SCSI_SYNC_TIMER); - const uint32_t *byte_lookup = g_scsi_out_byte_to_bop; - register uint32_t tmp1 = 0; - register uint32_t tmp2 = 0; - register uint32_t data = 0; - -#define ASM_DELAY1() ASM_DELAY() ASM_DELAY() ASM_DELAY() ASM_DELAY() \ - ASM_DELAY() ASM_DELAY() -#define ASM_DELAY2() ASM_DELAY() ASM_DELAY() ASM_DELAY() ASM_DELAY() \ - ASM_DELAY() ASM_DELAY() ASM_DELAY() ASM_DELAY() - - asm volatile ( - "main_loop_%=: \n" - " subs %[num_bytes], %[num_bytes], #4 \n" - " bmi last_bytes_%= \n" - - /* At each point make sure there is at most 3 bytes in flight */ - " ldr %[data], [%[buf]], #4 \n" - ASM_SEND_4BYTES_WAIT("7") - - " cbz %[num_bytes], all_done_%= \n" - " b main_loop_%= \n" - - "last_bytes_%=: \n" - " add %[num_bytes], %[num_bytes], #4 \n" - "last_bytes_loop_%=: \n" - " ldrb %[data], [%[buf]], #1 \n" - ASM_LOAD_DATA("0") - - ASM_WAIT_ACK_TIMER("5") - ASM_SEND_DATA() - ASM_DELAY1() - ASM_SET_REQ_LOW() - ASM_DELAY2() - - " subs %[num_bytes], %[num_bytes], #1 \n" - " bne last_bytes_loop_%= \n" - "all_done_%=: \n" - ASM_DELAY1() - - : /* Output */ [tmp1] "+l" (tmp1), [tmp2] "+l" (tmp2), [data] "+r" (data), - [buf] "+r" (buf), [num_bytes] "+r" (num_bytes) - : /* Input */ [ack_timer] "r" (ack_timer), - [bop_req_low] "I" (SCSI_OUT_REQ << 16), - [out_port_bop] "r"(out_port_bop), - [byte_lookup] "r" (byte_lookup), - [reset_flag] "r" (resetFlag) - : /* Clobber */); - -#undef ASM_DELAY1 -#undef ASM_DELAY2 - - SCSI_RELEASE_DATA_REQ(); -} - -void scsi_accel_sync_send(const uint8_t* data, uint32_t count, volatile int *resetFlag) -{ - // Timer counts down from the initial number of bytes. - TIMER_CNT(SCSI_SYNC_TIMER) = count; - TIMER_CTL0(SCSI_SYNC_TIMER) = TIMER_CTL0_CEN | TIMER_CTL0_DIR; - - int syncOffset = scsiDev.target->syncOffset; - int syncPeriod = scsiDev.target->syncPeriod; - - if (syncOffset >= 15 && syncPeriod <= 25) - { - sync_send_100ns_15off(data, count, resetFlag); - } - else if (syncOffset >= 15 && syncPeriod <= 50) - { - sync_send_200ns_15off(data, count, resetFlag); - } - else if (syncOffset >= 7 && syncPeriod <= 65) - { - sync_send_260ns_7off(data, count, resetFlag); - } - else - { - bluedbg("No optimized routine for syncOffset=", syncOffset, " syndPeriod=", syncPeriod, ", using fallback"); - while (count-- > 0) - { - while (TIMER_CNT(SCSI_SYNC_TIMER) > count + syncOffset && !*resetFlag); - - SCSI_OUT_DATA(*data++); - delay_ns(syncPeriod * 2); - SCSI_OUT(REQ, 0); - delay_ns(syncPeriod * 2); - } - delay_ns(syncPeriod * 2); - SCSI_RELEASE_DATA_REQ(); - } - - while (TIMER_CNT(SCSI_SYNC_TIMER) > 0 && !*resetFlag); - - if (*resetFlag) - { - bluedbg("Bus reset during sync transfer, total ", (int)count, - " bytes, remaining ACK count ", (int)TIMER_CNT(SCSI_SYNC_TIMER)); - } - - TIMER_CTL0(SCSI_SYNC_TIMER) = 0; -} - - -#endif diff --git a/lib/BlueSCSI_platform_GD32F205/scsi_accel_sync.h b/lib/BlueSCSI_platform_GD32F205/scsi_accel_sync.h deleted file mode 100644 index 360868bf..00000000 --- a/lib/BlueSCSI_platform_GD32F205/scsi_accel_sync.h +++ /dev/null @@ -1,17 +0,0 @@ -// SCSI subroutines that implement synchronous mode SCSI. -// Uses DMA for data transfer, EXMC for data input and -// GD32 timer for the REQ pin toggling. - -#pragma once - -#include -#include "BlueSCSI_platform.h" - -#ifdef SCSI_IN_ACK_EXMC_NWAIT_PORT -#define SCSI_SYNC_MODE_AVAILABLE -#endif - -void scsi_accel_sync_init(); - -void scsi_accel_sync_recv(uint8_t *data, uint32_t count, int* parityError, volatile int *resetFlag); -void scsi_accel_sync_send(const uint8_t* data, uint32_t count, volatile int *resetFlag); diff --git a/lib/BlueSCSI_platform_GD32F205/sd_card_sdio.cpp b/lib/BlueSCSI_platform_GD32F205/sd_card_sdio.cpp deleted file mode 100644 index 3d916ea2..00000000 --- a/lib/BlueSCSI_platform_GD32F205/sd_card_sdio.cpp +++ /dev/null @@ -1,310 +0,0 @@ -// Driver and interface for accessing SD card in SDIO mode -// Used on BlueSCSI v1.1. - -#include "BlueSCSI_platform.h" - -#ifdef SD_USE_SDIO - -#include "BlueSCSI_log.h" -#include "gd32f20x_sdio.h" -#include "gd32f20x_dma.h" -#include "gd32_sdio_sdcard.h" -#include - -static sd_error_enum g_sdio_error = SD_OK; -static int g_sdio_error_line = 0; -static uint32_t g_sdio_card_status; -static uint32_t g_sdio_clk_kHz; -static sdio_card_type_enum g_sdio_card_type; -static uint16_t g_sdio_card_rca; -static uint32_t g_sdio_sector_count; - -#define checkReturnOk(call) ((g_sdio_error = (call)) == SD_OK ? true : logSDError(__LINE__)) -static bool logSDError(int line) -{ - g_sdio_error_line = line; - bluelog("SDIO SD card error on line ", line, ", error code ", (int)g_sdio_error); - return false; -} - -bool SdioCard::begin(SdioConfig sdioConfig) -{ - rcu_periph_clock_enable(RCU_SDIO); - rcu_periph_clock_enable(RCU_DMA1); - nvic_irq_enable(SDIO_IRQn, 0, 0); - - g_sdio_error = sd_init(); - if (g_sdio_error != SD_OK) - { - // Don't spam the log when main program polls for card insertion. - bluedbg("sd_init() failed: ", (int)g_sdio_error); - return false; - } - - return checkReturnOk(sd_card_information_get_short(&g_sdio_card_type, &g_sdio_card_rca)) - && checkReturnOk(sd_card_select_deselect(g_sdio_card_rca)) - && checkReturnOk(sd_cardstatus_get(&g_sdio_card_status)) - && checkReturnOk(sd_bus_mode_config(SDIO_BUSMODE_4BIT)) - && checkReturnOk(sd_transfer_mode_config(sdioConfig.useDma() ? SD_DMA_MODE : SD_POLLING_MODE)) - && (g_sdio_sector_count = sectorCount()); -} - -uint8_t SdioCard::errorCode() const -{ - if (g_sdio_error == SD_OK) - return SD_CARD_ERROR_NONE; - else - return 0x80 + g_sdio_error; -} - -uint32_t SdioCard::errorData() const -{ - return 0; -} - -uint32_t SdioCard::errorLine() const -{ - return g_sdio_error_line; -} - -bool SdioCard::isBusy() -{ - return (GPIO_ISTAT(SD_SDIO_DATA_PORT) & SD_SDIO_D0) == 0; -} - -uint32_t SdioCard::kHzSdClk() -{ - return g_sdio_clk_kHz; -} - -bool SdioCard::readCID(cid_t* cid) -{ - sd_cid_get((uint8_t*)cid); - return true; -} - -bool SdioCard::readCSD(csd_t* csd) -{ - sd_csd_get((uint8_t*)csd); - return true; -} - -bool SdioCard::readOCR(uint32_t* ocr) -{ - // SDIO mode does not have CMD58, but main program uses this to - // poll for card presence. Return status register instead. - return sd_cardstatus_get(ocr) == SD_OK; -} - -bool SdioCard::readData(uint8_t* dst) -{ - bluelog("SdioCard::readData() called but not implemented!"); - return false; -} - -bool SdioCard::readStart(uint32_t sector) -{ - bluelog("SdioCard::readStart() called but not implemented!"); - return false; -} - -bool SdioCard::readStop() -{ - bluelog("SdioCard::readStop() called but not implemented!"); - return false; -} - -uint32_t SdioCard::sectorCount() -{ - csd_t csd; - sd_csd_get((uint8_t*)&csd); - return sdCardCapacity(&csd); -} - -uint32_t SdioCard::status() -{ - uint32_t status = 0; - if (!checkReturnOk(sd_cardstatus_get(&status))) - return 0; - else - return status; -} - -bool SdioCard::stopTransmission(bool blocking) -{ - if (!checkReturnOk(sd_transfer_stop())) - return false; - - if (!blocking) - { - return true; - } - else - { - uint32_t end = millis() + 100; - while (millis() < end && isBusy()) - { - } - if (isBusy()) - { - bluelog("SdioCard::stopTransmission() timeout"); - return false; - } - else - { - return true; - } - } -} - -bool SdioCard::syncDevice() -{ - if (sd_transfer_state_get() != SD_NO_TRANSFER) - { - return stopTransmission(true); - } - return true; -} - -uint8_t SdioCard::type() const -{ - if (g_sdio_card_type == SDIO_HIGH_CAPACITY_SD_CARD) - return SD_CARD_TYPE_SDHC; - else if (g_sdio_card_type == SDIO_STD_CAPACITY_SD_CARD_V2_0) - return SD_CARD_TYPE_SD2; - else - return SD_CARD_TYPE_SD1; -} - -bool SdioCard::writeData(const uint8_t* src) -{ - bluelog("SdioCard::writeData() called but not implemented!"); - return false; -} - -bool SdioCard::writeStart(uint32_t sector) -{ - bluelog("SdioCard::writeStart() called but not implemented!"); - return false; -} - -bool SdioCard::writeStop() -{ - bluelog("SdioCard::writeStop() called but not implemented!"); - return false; -} - -bool SdioCard::erase(uint32_t firstSector, uint32_t lastSector) -{ - return checkReturnOk(sd_erase(firstSector * 512, lastSector * 512)); -} - -/* Writing and reading, with progress callback */ - -static sd_callback_t m_stream_callback; -static const uint8_t *m_stream_buffer; -static uint32_t m_stream_count; -static uint32_t m_stream_count_start; - -void bluescsiplatform_set_sd_callback(sd_callback_t func, const uint8_t *buffer) -{ - m_stream_callback = func; - m_stream_buffer = buffer; - m_stream_count = 0; - m_stream_count_start = 0; -} - -static void sdio_callback(uint32_t complete) -{ - if (m_stream_callback) - { - m_stream_callback(m_stream_count_start + complete); - } -} - -static sdio_callback_t get_stream_callback(const uint8_t *buf, uint32_t count, const char *accesstype, uint32_t sector) -{ - m_stream_count_start = m_stream_count; - - if (m_stream_callback) - { - if (buf == m_stream_buffer + m_stream_count) - { - m_stream_count += count; - return &sdio_callback; - } - else - { - bluedbg("SD card ", accesstype, "(", (int)sector, - ") slow transfer, buffer", (uint32_t)buf, " vs. ", (uint32_t)(m_stream_buffer + m_stream_count)); - return NULL; - } - } - - return NULL; -} - - -bool SdioCard::writeSector(uint32_t sector, const uint8_t* src) -{ - return checkReturnOk(sd_block_write((uint32_t*)src, (uint64_t)sector * 512, 512, - get_stream_callback(src, 512, "writeSector", sector))); -} - -bool SdioCard::writeSectors(uint32_t sector, const uint8_t* src, size_t n) -{ - return checkReturnOk(sd_multiblocks_write((uint32_t*)src, (uint64_t)sector * 512, 512, n, - get_stream_callback(src, n * 512, "writeSectors", sector))); -} - -bool SdioCard::readSector(uint32_t sector, uint8_t* dst) -{ - return checkReturnOk(sd_block_read((uint32_t*)dst, (uint64_t)sector * 512, 512, - get_stream_callback(dst, 512, "readSector", sector))); -} - -bool SdioCard::readSectors(uint32_t sector, uint8_t* dst, size_t n) -{ - if (sector + n >= g_sdio_sector_count) - { - // sd_multiblocks_read() seems to have trouble reading the very last sector - for (int i = 0; i < n; i++) - { - if (!readSector(sector + i, dst + i * 512)) - { - bluelog("End of drive read failed at ", sector, " + ", i); - return false; - } - } - return true; - } - - return checkReturnOk(sd_multiblocks_read((uint32_t*)dst, (uint64_t)sector * 512, 512, n, - get_stream_callback(dst, n * 512, "readSectors", sector))); -} - -// Check if a DMA request for SD card read has completed. -// This is used to optimize the timing of data transfers on SCSI bus. -bool check_sd_read_done() -{ - return (DMA_CHCTL(DMA1, DMA_CH3) & DMA_CHXCTL_CHEN) - && (DMA_INTF(DMA1) & DMA_FLAG_ADD(DMA_FLAG_FTF, DMA_CH3)); -} - -// These functions are not used for SDIO mode but are needed to avoid build error. -void sdCsInit(SdCsPin_t pin) {} -void sdCsWrite(SdCsPin_t pin, bool level) {} - -// Interrupt handler for SDIO -extern "C" void SDIO_IRQHandler(void) -{ - sd_interrupts_process(); -} - -// SDIO configuration for main program -SdioConfig g_sd_sdio_config(DMA_SDIO); - -// SDIO configuration in crash -SdioConfig g_sd_sdio_config_crash(0); - -#endif diff --git a/lib/BlueSCSI_platform_GD32F205/sd_card_spi.cpp b/lib/BlueSCSI_platform_GD32F205/sd_card_spi.cpp deleted file mode 100644 index 46f767bd..00000000 --- a/lib/BlueSCSI_platform_GD32F205/sd_card_spi.cpp +++ /dev/null @@ -1,274 +0,0 @@ -// Driver and interface for accessing SD card in SPI mode -// Used on BlueSCSI v1.0. - -#include "BlueSCSI_platform.h" -#include "BlueSCSI_log.h" -#include "gd32f20x_spi.h" -#include "gd32f20x_dma.h" -#include - -#ifndef SD_USE_SDIO - -class GD32SPIDriver : public SdSpiBaseClass -{ -public: - void begin(SdSpiConfig config) { - rcu_periph_clock_enable(RCU_SPI0); - rcu_periph_clock_enable(RCU_DMA0); - - dma_parameter_struct rx_dma_config = - { - .periph_addr = (uint32_t)&SPI_DATA(SD_SPI), - .periph_width = DMA_PERIPHERAL_WIDTH_8BIT, - .memory_addr = 0, // Set before transfer - .memory_width = DMA_MEMORY_WIDTH_8BIT, - .number = 0, // Set before transfer - .priority = DMA_PRIORITY_ULTRA_HIGH, - .periph_inc = DMA_PERIPH_INCREASE_DISABLE, - .memory_inc = DMA_MEMORY_INCREASE_ENABLE, - .direction = DMA_PERIPHERAL_TO_MEMORY - }; - dma_init(DMA0, SD_SPI_RX_DMA_CHANNEL, &rx_dma_config); - - dma_parameter_struct tx_dma_config = - { - .periph_addr = (uint32_t)&SPI_DATA(SD_SPI), - .periph_width = DMA_PERIPHERAL_WIDTH_8BIT, - .memory_addr = 0, // Set before transfer - .memory_width = DMA_MEMORY_WIDTH_8BIT, - .number = 0, // Set before transfer - .priority = DMA_PRIORITY_HIGH, - .periph_inc = DMA_PERIPH_INCREASE_DISABLE, - .memory_inc = DMA_MEMORY_INCREASE_ENABLE, - .direction = DMA_MEMORY_TO_PERIPHERAL - }; - dma_init(DMA0, SD_SPI_TX_DMA_CHANNEL, &tx_dma_config); - } - - void activate() { - spi_parameter_struct config = { - SPI_MASTER, - SPI_TRANSMODE_FULLDUPLEX, - SPI_FRAMESIZE_8BIT, - SPI_NSS_SOFT, - SPI_ENDIAN_MSB, - SPI_CK_PL_LOW_PH_1EDGE, - SPI_PSC_256 - }; - - // Select closest available divider based on system frequency - int divider = (SystemCoreClock + m_sckfreq / 2) / m_sckfreq; - if (divider <= 2) - config.prescale = SPI_PSC_2; - else if (divider <= 4) - config.prescale = SPI_PSC_4; - else if (divider <= 8) - config.prescale = SPI_PSC_8; - else if (divider <= 16) - config.prescale = SPI_PSC_16; - else if (divider <= 32) - config.prescale = SPI_PSC_32; - else if (divider <= 64) - config.prescale = SPI_PSC_64; - else if (divider <= 128) - config.prescale = SPI_PSC_128; - else - config.prescale = SPI_PSC_256; - - spi_init(SD_SPI, &config); - spi_enable(SD_SPI); - } - - void deactivate() { - spi_disable(SD_SPI); - } - - void wait_idle() { - while (!(SPI_STAT(SD_SPI) & SPI_STAT_TBE)); - while (SPI_STAT(SD_SPI) & SPI_STAT_TRANS); - } - - // Single byte receive - uint8_t receive() { - // Wait for idle and clear RX buffer - wait_idle(); - (void)SPI_DATA(SD_SPI); - - // Send dummy byte and wait for receive - SPI_DATA(SD_SPI) = 0xFF; - while (!(SPI_STAT(SD_SPI) & SPI_STAT_RBNE)); - return SPI_DATA(SD_SPI); - } - - // Single byte send - void send(uint8_t data) { - SPI_DATA(SD_SPI) = data; - wait_idle(); - } - - // Multiple byte receive - uint8_t receive(uint8_t* buf, size_t count) - { - // Wait for idle and clear RX buffer - wait_idle(); - (void)SPI_DATA(SD_SPI); - - // Check if this is part of callback streaming request - bool stream = false; - if (m_stream_callback && buf == m_stream_buffer + m_stream_count) - { - stream = true; - } - else if (m_stream_callback) - { - bluedbg("Stream buffer mismatch: ", (uint32_t)buf, " vs. ", (uint32_t)(m_stream_buffer + m_stream_count)); - } - - // Use DMA to stream dummy TX data and store RX data - uint8_t tx_data = 0xFF; - DMA_INTC(DMA0) = DMA_FLAG_ADD(DMA_FLAG_FTF | DMA_FLAG_ERR, SD_SPI_RX_DMA_CHANNEL); - DMA_INTC(DMA0) = DMA_FLAG_ADD(DMA_FLAG_FTF | DMA_FLAG_ERR, SD_SPI_TX_DMA_CHANNEL); - DMA_CHMADDR(DMA0, SD_SPI_RX_DMA_CHANNEL) = (uint32_t)buf; - DMA_CHMADDR(DMA0, SD_SPI_TX_DMA_CHANNEL) = (uint32_t)&tx_data; - DMA_CHCTL(DMA0, SD_SPI_TX_DMA_CHANNEL) &= ~DMA_CHXCTL_MNAGA; // No memory increment for TX - DMA_CHCNT(DMA0, SD_SPI_RX_DMA_CHANNEL) = count; - DMA_CHCNT(DMA0, SD_SPI_TX_DMA_CHANNEL) = count; - DMA_CHCTL(DMA0, SD_SPI_RX_DMA_CHANNEL) |= DMA_CHXCTL_CHEN; - DMA_CHCTL(DMA0, SD_SPI_TX_DMA_CHANNEL) |= DMA_CHXCTL_CHEN; - - SPI_CTL1(SD_SPI) |= SPI_CTL1_DMAREN | SPI_CTL1_DMATEN; - - uint32_t start = millis(); - while (!(DMA_INTF(DMA0) & DMA_FLAG_ADD(DMA_FLAG_FTF | DMA_FLAG_ERR, SD_SPI_RX_DMA_CHANNEL))) - { - if (millis() - start > 500) - { - bluelog("ERROR: SPI DMA receive of ", (int)count, " bytes timeouted"); - return 1; - } - - if (stream) - { - uint32_t complete = m_stream_count + (count - DMA_CHCNT(DMA0, SD_SPI_RX_DMA_CHANNEL)); - m_stream_callback(complete); - } - } - - if (DMA_INTF(DMA0) & DMA_FLAG_ADD(DMA_FLAG_ERR, SD_SPI_RX_DMA_CHANNEL)) - { - bluelog("ERROR: SPI DMA receive set DMA_FLAG_ERR"); - } - - SPI_CTL1(SD_SPI) &= ~(SPI_CTL1_DMAREN | SPI_CTL1_DMATEN); - DMA_CHCTL(DMA0, SD_SPI_RX_DMA_CHANNEL) &= ~DMA_CHXCTL_CHEN; - DMA_CHCTL(DMA0, SD_SPI_TX_DMA_CHANNEL) &= ~DMA_CHXCTL_CHEN; - - if (stream) - { - m_stream_count += count; - } - - return 0; - } - - // Multiple byte send - void send(const uint8_t* buf, size_t count) { - // Check if this is part of callback streaming request - bool stream = false; - if (m_stream_callback && buf == m_stream_buffer + m_stream_count) - { - stream = true; - } - else if (m_stream_callback) - { - bluedbg("Stream buffer mismatch: ", (uint32_t)buf, " vs. ", (uint32_t)(m_stream_buffer + m_stream_count)); - } - - // Use DMA to stream TX data - DMA_INTC(DMA0) = DMA_FLAG_ADD(DMA_FLAG_FTF | DMA_FLAG_ERR, SD_SPI_TX_DMA_CHANNEL); - DMA_CHMADDR(DMA0, SD_SPI_TX_DMA_CHANNEL) = (uint32_t)buf; - DMA_CHCTL(DMA0, SD_SPI_TX_DMA_CHANNEL) |= DMA_CHXCTL_MNAGA; // Memory increment for TX - DMA_CHCNT(DMA0, SD_SPI_TX_DMA_CHANNEL) = count; - DMA_CHCTL(DMA0, SD_SPI_TX_DMA_CHANNEL) |= DMA_CHXCTL_CHEN; - - SPI_CTL1(SD_SPI) |= SPI_CTL1_DMATEN; - - uint32_t start = millis(); - while (!(DMA_INTF(DMA0) & DMA_FLAG_ADD(DMA_FLAG_FTF | DMA_FLAG_ERR, SD_SPI_TX_DMA_CHANNEL))) - { - if (millis() - start > 500) - { - bluelog("ERROR: SPI DMA transmit of ", (int)count, " bytes timeouted"); - return; - } - - if (stream) - { - uint32_t complete = m_stream_count + (count - DMA_CHCNT(DMA0, SD_SPI_TX_DMA_CHANNEL)); - m_stream_callback(complete); - } - } - - if (DMA_INTF(DMA0) & DMA_FLAG_ADD(DMA_FLAG_ERR, SD_SPI_TX_DMA_CHANNEL)) - { - bluelog("ERROR: SPI DMA transmit set DMA_FLAG_ERR"); - } - - wait_idle(); - - SPI_CTL1(SD_SPI) &= ~(SPI_CTL1_DMAREN | SPI_CTL1_DMATEN); - DMA_CHCTL(DMA0, SD_SPI_TX_DMA_CHANNEL) &= ~DMA_CHXCTL_CHEN; - - if (stream) - { - m_stream_count += count; - } - } - - void setSckSpeed(uint32_t maxSck) { - m_sckfreq = maxSck; - } - - void set_sd_callback(sd_callback_t func, const uint8_t *buffer) - { - m_stream_buffer = buffer; - m_stream_count = 0; - m_stream_callback = func; - } - -private: - uint32_t m_sckfreq; - const uint8_t *m_stream_buffer; - uint32_t m_stream_count; - sd_callback_t m_stream_callback; -}; - -void sdCsInit(SdCsPin_t pin) -{ -} - -void sdCsWrite(SdCsPin_t pin, bool level) -{ - if (level) - GPIO_BOP(SD_PORT) = SD_CS_PIN; - else - GPIO_BC(SD_PORT) = SD_CS_PIN; -} - -GD32SPIDriver g_sd_spi_port; -SdSpiConfig g_sd_spi_config(0, DEDICATED_SPI, SD_SCK_MHZ(30), &g_sd_spi_port); - -void bluescsiplatform_set_sd_callback(sd_callback_t func, const uint8_t *buffer) -{ - g_sd_spi_port.set_sd_callback(func, buffer); -} - -// Check if a DMA request for SD card read has completed. -// This is used to optimize the timing of data transfers on SCSI bus. -bool check_sd_read_done() -{ - return (DMA_CHCTL(DMA0, SD_SPI_RX_DMA_CHANNEL) & DMA_CHXCTL_CHEN) - && (DMA_INTF(DMA0) & DMA_FLAG_ADD(DMA_FLAG_FTF, SD_SPI_RX_DMA_CHANNEL)); -} - -#endif diff --git a/lib/SdFat_NoArduino/.gitattributes b/lib/SdFat_NoArduino/.gitattributes deleted file mode 100644 index 412eeda7..00000000 --- a/lib/SdFat_NoArduino/.gitattributes +++ /dev/null @@ -1,22 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto - -# Custom for Visual Studio -*.cs diff=csharp -*.sln merge=union -*.csproj merge=union -*.vbproj merge=union -*.fsproj merge=union -*.dbproj merge=union - -# Standard to msysgit -*.doc diff=astextplain -*.DOC diff=astextplain -*.docx diff=astextplain -*.DOCX diff=astextplain -*.dot diff=astextplain -*.DOT diff=astextplain -*.pdf diff=astextplain -*.PDF diff=astextplain -*.rtf diff=astextplain -*.RTF diff=astextplain diff --git a/lib/SdFat_NoArduino/.gitignore b/lib/SdFat_NoArduino/.gitignore deleted file mode 100644 index b9d6bd92..00000000 --- a/lib/SdFat_NoArduino/.gitignore +++ /dev/null @@ -1,215 +0,0 @@ -################# -## Eclipse -################# - -*.pydevproject -.project -.metadata -bin/ -tmp/ -*.tmp -*.bak -*.swp -*~.nib -local.properties -.classpath -.settings/ -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Locally stored "Eclipse launch configurations" -*.launch - -# CDT-specific -.cproject - -# PDT-specific -.buildpath - - -################# -## Visual Studio -################# - -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.sln.docstates - -# Build results - -[Dd]ebug/ -[Rr]elease/ -x64/ -build/ -[Bb]in/ -[Oo]bj/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -*_i.c -*_p.c -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.log -*.scc - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opensdf -*.sdf -*.cachefile - -# Visual Studio profiler -*.psess -*.vsp -*.vspx - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -*.ncrunch* -.*crunch*.local.xml - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.Publish.xml -*.pubxml - -# NuGet Packages Directory -## TODO: If you have NuGet Package Restore enabled, uncomment the next line -#packages/ - -# Windows Azure Build Output -csx -*.build.csdef - -# Windows Store app package directory -AppPackages/ - -# Others -sql/ -*.Cache -ClientBin/ -[Ss]tyle[Cc]op.* -~$* -*~ -*.dbmdl -*.[Pp]ublish.xml -*.pfx -*.publishsettings - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file to a newer -# Visual Studio version. Backup files are not needed, because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -App_Data/*.mdf -App_Data/*.ldf - -############# -## Windows detritus -############# - -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Mac crap -.DS_Store - - -############# -## Python -############# - -*.py[co] - -# Packages -*.egg -*.egg-info -dist/ -build/ -eggs/ -parts/ -var/ -sdist/ -develop-eggs/ -.installed.cfg - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -.tox - -#Translations -*.mo - -#Mr Developer -.mr.developer.cfg diff --git a/lib/SdFat_NoArduino/.piopm b/lib/SdFat_NoArduino/.piopm deleted file mode 100644 index 482f6163..00000000 --- a/lib/SdFat_NoArduino/.piopm +++ /dev/null @@ -1 +0,0 @@ -{"type": "library", "name": "SdFat", "version": "2.1.2", "spec": {"owner": "greiman", "id": 322, "name": "SdFat", "requirements": null, "url": null}} \ No newline at end of file diff --git a/lib/SdFat_NoArduino/LICENSE.md b/lib/SdFat_NoArduino/LICENSE.md deleted file mode 100644 index a8147353..00000000 --- a/lib/SdFat_NoArduino/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2011..2020 Bill Greiman - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/lib/SdFat_NoArduino/README.md b/lib/SdFat_NoArduino/README.md deleted file mode 100644 index c3abc011..00000000 --- a/lib/SdFat_NoArduino/README.md +++ /dev/null @@ -1,110 +0,0 @@ -### Warning: This is SdFat Version 2. - -Earlier releases of Version 1 are here: - -https://github.com/greiman/SdFat/releases - -UTF-8 encoded filenames are supported in v2.1.0 or later. - -Try the UnicodeFilenames example. Here is output from ls: -

-Type any character to begin
-ls:
-         0 😀/
-          20 россиянин
-          17 très élégant
-           9 狗.txt
-
- -SdFat Version 2 supports FAT16/FAT32 and exFAT SD cards. It is mostly -backward compatible with SdFat Version 1 for FAT16/FAT32 cards. - -exFAT supports files larger than 4GB so files sizes and positions are -type uint64_t for classes that support exFAT. - -exFAT has many features not available in FAT16/FAT32. exFAT has excellent -support for contiguous files on flash devices and supports preallocation. - -If the SD card is the only SPI device, use dedicated SPI mode. This can -greatly improve performance. See the bench example. - -Here is write performance for an old, 2011, card on a Due board. -``` -Shared SPI: -write speed and latency -speed,max,min,avg -KB/Sec,usec,usec,usec -294.45,24944,1398,1737 - -Dedicated SPI: -write speed and latency -speed,max,min,avg -KB/Sec,usec,usec,usec -3965.11,16733,110,127 -``` -The default version of SdFatConfig.h enables support for dedicated SPI and -optimized access to contiguous files. This makes SdFat Version 2 slightly -larger than Version 1. If these features are disabled, Version 2 is smaller -than Version 1. - -The types for the classes SdFat and File are defined in SdFatConfig.h. -The default version of SdFatConfig.h defines SdFat to only support FAT16/FAT32. -SdFat and File are defined in terms of more basic classes by typedefs. You -can use these basic classes in applications. - -Support for exFAT requires a substantial amount of flash. Here are sizes on -an UNO for a simple program that opens a file, prints one line, and closes -the file. -``` -FAT16/FAT32 only: 9780 bytes flash, 875 bytes SRAM. - -exFAT only: 13830 bytes flash, 938 bytes SRAM. - -FAT16/FAT32/exFAT: 19326 bytes flash, 928 bytes SRAM. -``` -The section below of SdFatConfig.h has been edited to uses FAT16/FAT32 for -small AVR boards and FAT16/FAT32/exFAT for all other boards. -``` -/** - * File types for SdFat, File, SdFile, SdBaseFile, fstream, - * ifstream, and ofstream. - * - * Set SDFAT_FILE_TYPE to: - * - * 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT. - */ -#if defined(__AVR__) && FLASHEND < 0X8000 -// FAT16/FAT32 for 32K AVR boards. -#define SDFAT_FILE_TYPE 1 -#else // defined(__AVR__) && FLASHEND < 0X8000 -// FAT16/FAT32 and exFAT for all other boards. -#define SDFAT_FILE_TYPE 3 -#endif // defined(__AVR__) && FLASHEND < 0X8000 -``` -The SdBaseFile class has no Arduino Stream or Print support. - -The File class is derived from Stream and SdBaseFile. - -The SdFile class is derived from SdBaseFile and Print. - -Please try the examples. Start with SdInfo, bench, and ExFatLogger. - -To use SdFat Version 2, unzip the download file, rename the library folder -SdFat and place the SdFat folder into the libraries sub-folder in your main -sketch folder. - -For more information see the Manual installation section of this guide: - -http://arduino.cc/en/Guide/Libraries - -A number of configuration options can be set by editing SdFatConfig.h -define macros. See the html documentation File tab for details. - -Please read the html documentation for this library in SdFat/doc/SdFat.html. -Start with the Main Page. Next go to the Classes tab and read the -documentation for the classes SdFat32, SdExFat, SdFs, File32, ExFile, FsFile. - -The SdFat and File classes are defined in terms of the above classes by -typedefs. Edit SdFatConfig.h to select class options. - -Please continue by reading the html documentation in the SdFat/doc folder. diff --git a/lib/SdFat_NoArduino/doc/Doxyfile b/lib/SdFat_NoArduino/doc/Doxyfile deleted file mode 100644 index 811563db..00000000 --- a/lib/SdFat_NoArduino/doc/Doxyfile +++ /dev/null @@ -1,2685 +0,0 @@ -# Doxyfile 1.9.2 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the configuration -# file that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# https://www.gnu.org/software/libiconv/ for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = SdFat - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = . - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = YES - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = YES - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = C:/Users/bill/Documents/ - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = NO - -# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line -# such as -# /*************** -# as being the beginning of a Javadoc-style comment "banner". If set to NO, the -# Javadoc-style will behave just like regular comments and it will not be -# interpreted by doxygen. -# The default value is: NO. - -JAVADOC_BANNER = NO - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# By default Python docstrings are displayed as preformatted text and doxygen's -# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the -# doxygen's special commands can be used and the contents of the docstring -# documentation blocks is shown as doxygen documentation. -# The default value is: YES. - -PYTHON_DOCSTRING = YES - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = NO - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:^^" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". Note that you cannot put \n's in the value part of an alias -# to insert newlines (in the resulting output). You can put ^^ in the value part -# of an alias to insert a newline as if a physical newline was in the original -# file. When you need a literal { or } or , in the value part of an alias you -# have to escape them by means of a backslash (\), this can lead to conflicts -# with the commands \{ and \} for these it is advised to use the version @{ and -# @} or use a double escape (\\{ and \\}) - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice -# sources only. Doxygen will then generate output that is more tailored for that -# language. For instance, namespaces will be presented as modules, types will be -# separated into more groups, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_SLICE = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, -# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, -# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: -# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser -# tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files). For instance to make doxygen treat .inc files -# as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. When specifying no_extension you should add -# * to the FILE_PATTERNS. -# -# Note see also the list of default file extension mappings. - -EXTENSION_MAPPING = - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See https://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up -# to that level are automatically included in the table of contents, even if -# they do not have an id attribute. -# Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 5. -# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. - -TOC_INCLUDE_HEADINGS = 0 - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# If one adds a struct or class to a group and this option is enabled, then also -# any nested class or struct is added to the same group. By default this option -# is disabled and one has to add nested compounds explicitly via \ingroup. -# The default value is: NO. - -GROUP_NESTED_COMPOUNDS = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use -# during processing. When set to 0 doxygen will based this on the number of -# cores available in the system. You can set it explicitly to a value larger -# than 0 to get more control over the balance between CPU load and processing -# speed. At this moment only the input processing can be done using multiple -# threads. Since this is still an experimental feature the default is set to 1, -# which effectively disables parallel processing. Please report any issues you -# encounter. Generating dot graphs in parallel is controlled by the -# DOT_NUM_THREADS setting. -# Minimum value: 0, maximum value: 32, default value: 1. - -NUM_PROC_THREADS = 1 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual -# methods of a class will be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIV_VIRTUAL = NO - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = NO - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If this flag is set to YES, the name of an unnamed parameter in a declaration -# will be determined by the corresponding definition. By default unnamed -# parameters remain unnamed in the output. -# The default value is: YES. - -RESOLVE_UNNAMED_PARAMS = YES - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# declarations. If set to NO, these declarations will be included in the -# documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# With the correct setting of option CASE_SENSE_NAMES doxygen will better be -# able to match the capabilities of the underlying filesystem. In case the -# filesystem is case sensitive (i.e. it supports files in the same directory -# whose names only differ in casing), the option must be set to YES to properly -# deal with such files in case they appear in the input. For filesystems that -# are not case sensitive the option should be be set to NO to properly deal with -# output files written for symbols that only differ in casing, such as for two -# classes, one named CLASS and the other named Class, and to also support -# references to files without having to specify the exact matching casing. On -# Windows (including Cygwin) and MacOS, users should typically set this option -# to NO, whereas on Linux or other Unix flavors it should typically be set to -# YES. -# The default value is: system dependent. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class -# will show which file needs to be included to use the class. -# The default value is: YES. - -SHOW_HEADERFILE = YES - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = YES - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if ... \endif and \cond -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 2 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. See also section "Changing the -# layout of pages" for information. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as documenting some parameters in -# a documented function twice, or documenting parameters that don't exist or -# using markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete -# function parameter documentation. If set to NO, doxygen will accept that some -# parameters have no documentation without warning. -# The default value is: YES. - -WARN_IF_INCOMPLETE_DOC = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong parameter -# documentation, but not about the absence of documentation. If EXTRACT_ALL is -# set to YES then this flag will automatically be disabled. See also -# WARN_IF_INCOMPLETE_DOC -# The default value is: NO. - -WARN_NO_PARAMDOC = YES - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS -# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but -# at the end of the doxygen process doxygen will return with a non-zero status. -# Possible values are: NO, YES and FAIL_ON_WARNINGS. -# The default value is: NO. - -WARN_AS_ERROR = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = ../src \ - ../src/ExFatLib \ - ../src/FatLib \ - ../src/iostream \ - ../src/common \ - ../src/SdCard \ - ../src/SpiDriver \ - mainpage.h \ - ../src/FsLib \ - ../src/FsLib - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: -# https://www.gnu.org/software/libiconv/) for the list of possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# Note the list of default checked file patterns might differ from the list of -# default file extension mappings. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, -# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C -# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, -# *.vhdl, *.ucf, *.qsf and *.ice. - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox \ - *.py \ - *.f90 \ - *.f \ - *.vhd \ - *.vhdl \ - *.cpp - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = ../src/common/FsStructs.h \ - ../src/ExFatLib/upcase.cpp \ - ../src/common/PrintBasic.h \ - ../src/common/PrintBasic.cpp \ - ../src/SpiDriver/SdSpiBareUnoDriver.h \ - ../src/iostream/StreamBaseClass.cpp - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = * - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# -# -# where is the value of the INPUT_FILTER tag, and is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# entity all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see https://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = NO - -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: -# http://clang.llvm.org/) for more accurate parsing at the cost of reduced -# performance. This can be particularly helpful with template rich C++ code for -# which doxygen's built-in parser lacks the necessary type information. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. -# The default value is: NO. - -CLANG_ASSISTED_PARSING = NO - -# If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS -# tag is set to YES then doxygen will add the directory of each input to the -# include path. -# The default value is: YES. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - -CLANG_ADD_INC_PATHS = YES - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - -CLANG_OPTIONS = - -# If clang assisted parsing is enabled you can provide the clang parser with the -# path to the directory containing a file called compile_commands.json. This -# file is the compilation database (see: -# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the -# options used when the source files were built. This is equivalent to -# specifying the -p option to a clang tool, such as clang-check. These options -# will then be passed to the parser. Any options specified with CLANG_OPTIONS -# will be added as well. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. - -CLANG_DATABASE_PATH = - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = NO - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a color-wheel, see -# https://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use gray-scales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = YES - -# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML -# documentation will contain a main index with vertical navigation menus that -# are dynamically created via JavaScript. If disabled, the navigation index will -# consists of multiple levels of tabs that are statically embedded in every HTML -# page. Disable this option to support browsers that do not have JavaScript, -# like the Qt help browser. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_MENUS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: -# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To -# create a documentation set, doxygen will generate a Makefile in the HTML -# output directory. Running make will produce the docset in that directory and -# running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy -# genXcode/_index.html for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# on Windows. In the beginning of 2021 Microsoft took the original page, with -# a.o. the download links, offline the HTML help workshop was already many years -# in maintenance mode). You can download the HTML help workshop from the web -# archives at Installation executable (see: -# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo -# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the main .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location (absolute path -# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to -# run qhelpgenerator on the generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine tune the look of the index (see "Fine-tuning the output"). As an -# example, the default style sheet generated by doxygen has an example that -# shows how to put an image at the root of the tree instead of the PROJECT_NAME. -# Since the tree basically has the same information as the tab index, you could -# consider setting DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = NO - -# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the -# FULL_SIDEBAR option determines if the side bar is limited to only the treeview -# area (value NO) or if it should extend to the full height of the window (value -# YES). Setting this to YES gives a layout similar to -# https://docs.readthedocs.io with more room for contents, but less room for the -# project logo, title, and description. If either GENERATOR_TREEVIEW or -# DISABLE_INDEX is set to NO, this option has no effect. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FULL_SIDEBAR = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg -# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see -# https://inkscape.org) to generate formulas as SVG images instead of PNGs for -# the HTML output. These images will generally look nicer at scaled resolutions. -# Possible values are: png (the default) and svg (looks nicer but requires the -# pdf2svg or inkscape tool). -# The default value is: png. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FORMULA_FORMAT = png - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANSPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands -# to create new LaTeX commands to be used in formulas as building blocks. See -# the section "Including formulas" for details. - -FORMULA_MACROFILE = - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# https://www.mathjax.org) which uses client side JavaScript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. -# Note that the different versions of MathJax have different requirements with -# regards to the different settings, so it is possible that also other MathJax -# settings have to be changed when switching between the different MathJax -# versions. -# Possible values are: MathJax_2 and MathJax_3. -# The default value is: MathJax_2. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_VERSION = MathJax_2 - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. For more details about the output format see MathJax -# version 2 (see: -# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 -# (see: -# http://docs.mathjax.org/en/latest/web/components/output.html). -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility. This is the name for Mathjax version 2, for MathJax version 3 -# this will be translated into chtml), NativeMML (i.e. MathML. Only supported -# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This -# is the name for Mathjax version 3, for MathJax version 2 this will be -# translated into HTML-CSS) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. The default value is: -# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 -# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = http://www.mathjax.org/mathjax - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# for MathJax version 2 (see -# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# For example for MathJax version 3 (see -# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): -# MATHJAX_EXTENSIONS = ams -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: -# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use + S -# (what the is depends on the OS and browser, but it is typically -# , /