Finalize implementation of sd card formatter

This commit is contained in:
KemoNine 2020-09-13 02:01:25 -04:00
parent 3fefcf7e34
commit d89a0cfbde
3 changed files with 136 additions and 122 deletions

View File

@ -69,13 +69,55 @@ bool popupOnScreen = false;
void handlerKeyboard();
void handlerBatteryLevel();
void eraseAndFormatCard();
void sdError(char*);
// SD Card related
#define USE_SDIO 0
const uint8_t chipSelect = 5;
#define SPI_SPEED SD_SCK_MHZ(50)
#include <SPI.h>
#include "src/SdFat/SdFat.h"
#include "src/SdFat/sdios.h"
#if USE_SDIO
// Use faster SdioCardEX
SdioCardEX card;
// SdioCard card;
#else // USE_SDIO
Sd2Card card;
#endif // USE_SDIO
uint32_t cardSizeBlocks;
uint32_t cardCapacityMB;
// cache for SD block
cache_t cache;
// MBR information
uint8_t partType;
uint32_t relSector;
uint32_t partSize;
// Fake disk geometry
uint8_t numberOfHeads;
uint8_t sectorsPerTrack;
// FAT parameters
uint16_t reservedSectors;
uint8_t sectorsPerCluster;
uint32_t fatStart;
uint32_t fatSize;
uint32_t dataStart;
// constants for file system structure
uint16_t const BU16 = 128;
uint16_t const BU32 = 8192;
// strings needed in file system structures
char noName[] = "NO NAME ";
char fat16str[] = "FAT16 ";
char fat32str[] = "FAT32 ";
// Save some element references for direct access
//<Save_References !Start!>
gslc_tsElemRef* m_pElemBatteryLevel= NULL;
gslc_tsElemRef* m_pElemBtFmt = NULL;
gslc_tsElemRef* m_pElemBtSDNo = NULL;
gslc_tsElemRef* m_pElemBtSDYes = NULL;
gslc_tsElemRef* m_pElemSDInfo = NULL;
gslc_tsElemRef* m_pElemSDStatus = NULL;
gslc_tsElemRef* m_pElemStatusText = NULL;
//<Save_References !End!>
@ -112,11 +154,14 @@ bool CbBtnCommon(void* pvGui,void *pvElemRef,gslc_teTouch eTouch,int16_t nX,int1
case E_ELEM_SD_YES:
gslc_PopupHide(&m_gui);
popupOnScreen = false;
gslc_ElemXTextboxReset(&m_gui, m_pElemSDInfo);
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "Formatting SD Card\n");
gslc_ElemXTextboxReset(&m_gui, m_pElemSDStatus);
gslc_ElemSetVisible(&m_gui, m_pElemBtFmt, false);
gslc_ElemSetVisible(&m_gui, m_pElemSDInfo, false);
gslc_ElemSetVisible(&m_gui, m_pElemSDStatus, true);
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "Formatting SD Card\n");
gslc_Update(&m_gui);
eraseAndFormatCard();
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "Formatting Complete\n");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "Formatting Complete\n");
gslc_Update(&m_gui);
break;
//<Button Enums !End!>
@ -216,6 +261,7 @@ void setup() {
// Flip to main screen
// This wouldn't be necessary if we hadn't chopped off the formatter from the main _controller project and actually updated the main screen ;)
gslc_SetPageCur(&m_gui, E_SD_CARD);
gslc_ElemSetVisible(&m_gui, m_pElemSDStatus, false);
// Set neopixels to standard start state
pixels_wing.clear();
@ -223,6 +269,57 @@ void setup() {
pixels_board.setPixelColor(0, pixels_board.Color(0, 0, 255));
pixels_board.show();
#if USE_SDIO
if (!card.begin()) {
sdError("card.begin failed");
}
#else // USE_SDIO
if (!card.begin(chipSelect, SPI_SPEED)) {
sdError("card.begin failed");
}
#endif
cardSizeBlocks = card.cardSize();
if (cardSizeBlocks == 0) {
sdError("cardSize");
}
cardCapacityMB = (cardSizeBlocks + 2047)/2048;
char textForDisplay[128];
snprintf(textForDisplay, 128, "Card Size: %.0fMb\n", 1.048576*cardCapacityMB);
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, textForDisplay);
char* type;
switch (card.type()) {
case SD_CARD_TYPE_SD1:
type = "SD1";
break;
case SD_CARD_TYPE_SD2:
type = "SD2";
break;
case SD_CARD_TYPE_SDHC:
if (cardSizeBlocks < 70000000) {
type = "SDHC";
} else {
type = "SDXC";
}
break;
default:
type = "Unknown";
}
snprintf(textForDisplay, 128, "Type: %s\n", type);
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, textForDisplay);
cid_t cid;
if (!card.readCID(&cid)) {
sdError("readCID failed");
}
snprintf(textForDisplay, 128, "Serial Number: %x\n", cid.psn);
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, textForDisplay);
snprintf(textForDisplay, 128, "Manufacturing date: %04d-%02d\n", (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high), int(cid.mdt_month));
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, textForDisplay);
gslc_Update(&m_gui);
}
// -----------------------------------
@ -320,84 +417,14 @@ void handlerBatteryLevel() {
}
// ------------------------------------------------
// Format SD Card
// Format SD Card Methods
// ------------------------------------------------
/*
* This program will format an SD or SDHC card.
* Warning all data will be deleted!
*
* For SD/SDHC cards larger than 64 MB this
* program attempts to match the format
* generated by SDFormatter available here:
*
* http://www.sdcard.org/consumers/formatter/
*
* For smaller cards this program uses FAT16
* and SDFormatter uses FAT12.
*/
// Set USE_SDIO to zero for SPI card access.
#define USE_SDIO 0
//
// Change the value of chipSelect if your hardware does
// not use the default value, SS. Common values are:
// Arduino Ethernet shield: pin 4
// Sparkfun SD shield: pin 8
// Adafruit SD shields and modules: pin 10
const uint8_t chipSelect = 5;
// Initialize at highest supported speed not over 50 MHz.
// Reduce max speed if errors occur.
#define SPI_SPEED SD_SCK_MHZ(50)
// Print extra info for debug if DEBUG_PRINT is nonzero
#include <SPI.h>
#include "src/SdFat/SdFat.h"
#include "src/SdFat/sdios.h"
#if USE_SDIO
// Use faster SdioCardEX
SdioCardEX card;
// SdioCard card;
#else // USE_SDIO
Sd2Card card;
#endif // USE_SDIO
uint32_t cardSizeBlocks;
uint32_t cardCapacityMB;
// cache for SD block
cache_t cache;
// MBR information
uint8_t partType;
uint32_t relSector;
uint32_t partSize;
// Fake disk geometry
uint8_t numberOfHeads;
uint8_t sectorsPerTrack;
// FAT parameters
uint16_t reservedSectors;
uint8_t sectorsPerCluster;
uint32_t fatStart;
uint32_t fatSize;
uint32_t dataStart;
// constants for file system structure
uint16_t const BU16 = 128;
uint16_t const BU32 = 8192;
// strings needed in file system structures
char noName[] = "NO NAME ";
char fat16str[] = "FAT16 ";
char fat32str[] = "FAT32 ";
//------------------------------------------------------------------------------
void sdError(char* msg) {
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "error: ");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, msg);
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "\n");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "error: ");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, msg);
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "\n");
gslc_Update(&m_gui);
sdErrorHalt();
@ -407,7 +434,7 @@ void sdErrorHalt() {
if (card.errorCode()) {
char textForDisplay[32];
snprintf(textForDisplay, 32, "SD error: %d\n", int(card.errorCode()));
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, textForDisplay);
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, textForDisplay);
gslc_Update(&m_gui);
}
SysCall::halt();
@ -441,7 +468,7 @@ void initSizes() {
char textForDisplay[64];
snprintf(textForDisplay, 64, "Blocks/Cluster: %d\n", int(sectorsPerCluster));
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, textForDisplay);
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, textForDisplay);
gslc_Update(&m_gui);
// set fake disk geometry
@ -477,26 +504,20 @@ void clearCache(uint8_t addSig) {
//------------------------------------------------------------------------------
// zero FAT and root dir area on SD
void clearFatDir(uint32_t bgn, uint32_t count) {
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "Clear FAT/DIR\n (This may take awhile)\n");
gslc_Update(&m_gui);
clearCache(false);
#if USE_SDIO
for (uint32_t i = 0; i < count; i++) {
if (!card.writeBlock(bgn + i, cache.data)) {
sdError("Clear FAT/DIR writeBlock failed");
}
if ((i & 0XFF) == 0) {
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, ".");
gslc_Update(&m_gui);
}
}
#else // USE_SDIO
if (!card.writeStart(bgn, count)) {
sdError("Clear FAT/DIR writeStart failed");
}
for (uint32_t i = 0; i < count; i++) {
if ((i & 0XFF) == 0) {
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, ".");
gslc_Update(&m_gui);
}
if (!card.writeData(cache.data)) {
sdError("Clear FAT/DIR writeData failed");
}
@ -505,8 +526,6 @@ void clearFatDir(uint32_t bgn, uint32_t count) {
sdError("Clear FAT/DIR writeStop failed");
}
#endif // USE_SDIO
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "\n");
gslc_Update(&m_gui);
}
//------------------------------------------------------------------------------
// return cylinder number for a logical block number
@ -725,7 +744,7 @@ void makeFat32() {
// flash erase all data
uint32_t const ERASE_SIZE = 262144L;
void eraseCard() {
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "Erasing\n");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "Erasing\n");
gslc_Update(&m_gui);
uint32_t firstBlock = 0;
uint32_t lastBlock;
@ -739,65 +758,45 @@ void eraseCard() {
if (!card.erase(firstBlock, lastBlock)) {
sdError("erase failed");
}
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, ".");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, ".");
gslc_Update(&m_gui);
if ((n++)%32 == 31) {
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "\n");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "\n");
gslc_Update(&m_gui);
}
firstBlock += ERASE_SIZE;
} while (firstBlock < cardSizeBlocks);
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "\n");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "\n");
gslc_Update(&m_gui);
if (!card.readBlock(0, cache.data)) {
sdError("readBlock");
}
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "Erase done\n");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "Erase done\n");
gslc_Update(&m_gui);
}
//------------------------------------------------------------------------------
void formatCard() {
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "Formatting\n");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "Formatting\n");
gslc_Update(&m_gui);
initSizes();
if (card.type() != SD_CARD_TYPE_SDHC) {
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "FAT16\n");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "FAT16\n");
gslc_Update(&m_gui);
makeFat16();
} else {
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "FAT32\n");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "FAT32\n");
gslc_Update(&m_gui);
makeFat32();
}
#if DEBUG_PRINT
debugPrint();
#endif // DEBUG_PRINT
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, "Format done\n");
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDStatus, "Format done\n");
gslc_Update(&m_gui);
}
//------------------------------------------------------------------------------
void eraseAndFormatCard() {
#if USE_SDIO
if (!card.begin()) {
sdError("card.begin failed");
}
#else // USE_SDIO
if (!card.begin(chipSelect, SPI_SPEED)) {
sdError("card.begin failed");
}
#endif
cardSizeBlocks = card.cardSize();
if (cardSizeBlocks == 0) {
sdError("cardSize");
}
cardCapacityMB = (cardSizeBlocks + 2047)/2048;
char textForDisplay[128];
snprintf(textForDisplay, 128, "Card Size: : %.0fMB, (MB = 1,000,000 bytes)\n", 1.048576*cardCapacityMB);
gslc_ElemXTextboxAdd(&m_gui, m_pElemSDInfo, textForDisplay);
gslc_Update(&m_gui);
eraseCard();
formatCard();
}

View File

@ -53,7 +53,7 @@
enum {E_PG_BASE,E_PG_MAIN,E_SD_CARD,E_PG_SD_CONFIRM};
enum {E_ELEM_BATT_LEVEL,E_ELEM_BOX1,E_ELEM_BTN_SD_FMT,E_ELEM_SD_NO
,E_ELEM_SD_YES,E_ELEM_STATUS,E_ELEM_TEXT14,E_ELEM_TEXT15
,E_ELEM_TX_SD_INFO,E_STATUS_LINE};
,E_ELEM_TX_SD_INFO,E_ELEM_TX_SD_STS,E_STATUS_LINE};
// Must use separate enum for fonts with MAX_FONT at end to use gslc_FontSet.
enum {E_AO_NOTOMONO10PT7B,E_AO_NOTOMONO12PT7B,E_AO_NOTOMONO16PT7B
,E_AO_NOTOMONO8PT7B,MAX_FONT};
@ -75,7 +75,7 @@ enum {E_AO_NOTOMONO10PT7B,E_AO_NOTOMONO12PT7B,E_AO_NOTOMONO16PT7B
#define MAX_ELEM_PG_MAIN 0 // # Elems total on page
#define MAX_ELEM_PG_MAIN_RAM MAX_ELEM_PG_MAIN // # Elems in RAM
#define MAX_ELEM_SD_CARD 2 // # Elems total on page
#define MAX_ELEM_SD_CARD 3 // # Elems total on page
#define MAX_ELEM_SD_CARD_RAM MAX_ELEM_SD_CARD // # Elems in RAM
#define MAX_ELEM_PG_SD_CONFIRM 5 // # Elems total on page
@ -101,7 +101,9 @@ gslc_tsElem m_asPopup1Elem[MAX_ELEM_PG_SD_CONFIRM_RAM];
gslc_tsElemRef m_asPopup1ElemRef[MAX_ELEM_PG_SD_CONFIRM];
gslc_tsXProgress m_sXBarGauge2;
gslc_tsXTextbox m_sTextbox2;
char m_acTextboxBuf2[224]; // NRows=8 NCols=28
char m_acTextboxBuf2[448]; // NRows=8 NCols=56
gslc_tsXTextbox m_sTextbox3;
char m_acTextboxBuf3[672]; // NRows=12 NCols=56
#define MAX_STR 100
@ -114,10 +116,13 @@ char m_acTextboxBuf2[224]; // NRows=8 NCols=28
// Element References for direct access
//<Extern_References !Start!>
extern gslc_tsElemRef* m_pElemBatteryLevel;
extern gslc_tsElemRef* m_pElemBtFmt;
extern gslc_tsElemRef* m_pElemBtSDNo;
extern gslc_tsElemRef* m_pElemBtSDYes;
extern gslc_tsElemRef* m_pElemSDInfo;
extern gslc_tsElemRef* m_pElemSDStatus;
extern gslc_tsElemRef* m_pElemStatusText;
extern gslc_tsElemRef* m_pTextSlider3;
extern gslc_tsElemRef* m_pTextSliderSDInfo;
//<Extern_References !End!>
@ -203,7 +208,7 @@ void InitGUIslice_gen()
// Create textbox
pElemRef = gslc_ElemXTextboxCreate(&m_gui,E_ELEM_TX_SD_INFO,E_SD_CARD,&m_sTextbox2,
(gslc_tsRect){3,30,313,150},E_AO_NOTOMONO8PT7B,
(char*)&m_acTextboxBuf2,8,28);
(char*)&m_acTextboxBuf2,8,56);
gslc_ElemXTextboxWrapSet(&m_gui,pElemRef,true);
gslc_ElemSetTxtCol(&m_gui,pElemRef,GSLC_COL_GRAY_LT3);
gslc_ElemSetCol(&m_gui,pElemRef,GSLC_COL_GRAY,GSLC_COL_BLACK,GSLC_COL_BLACK);
@ -213,6 +218,16 @@ void InitGUIslice_gen()
pElemRef = gslc_ElemCreateBtnTxt(&m_gui,E_ELEM_BTN_SD_FMT,E_SD_CARD,
(gslc_tsRect){110,190,100,40},(char*)"FORMAT?",0,E_AO_NOTOMONO8PT7B,&CbBtnCommon);
gslc_ElemSetCol(&m_gui,pElemRef,GSLC_COL_RED_DK1,GSLC_COL_GRAY,GSLC_COL_RED_DK1);
m_pElemBtFmt = pElemRef;
// Create textbox
pElemRef = gslc_ElemXTextboxCreate(&m_gui,E_ELEM_TX_SD_STS,E_SD_CARD,&m_sTextbox3,
(gslc_tsRect){3,30,313,200},E_AO_NOTOMONO8PT7B,
(char*)&m_acTextboxBuf3,12,56);
gslc_ElemXTextboxWrapSet(&m_gui,pElemRef,true);
gslc_ElemSetTxtCol(&m_gui,pElemRef,GSLC_COL_GRAY_LT3);
gslc_ElemSetCol(&m_gui,pElemRef,GSLC_COL_GRAY,GSLC_COL_BLACK,GSLC_COL_BLACK);
m_pElemSDStatus = pElemRef;
// -----------------------------------
// PAGE: E_PG_SD_CONFIRM