#ifndef SDBlock_h #define SDBlock_h // #define USE_SDCORE #define USE_SD2CARD // #define USE_SDFS #ifdef USE_SDCORE #include #endif #ifdef USE_SD2CARD #include #include #endif #ifdef USE_SDFS #include // if (!sd.card()->readSector(0, (uint8_t*)&mbr)) { #define SD_CS_PIN SS #define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI) #endif #include #include #include "SDBlockData.h" // Define Callback with buffers // typedef void (*CallbackFunction) (uint32_t recId, uint32_t blockId, uint32_t blockCount, void *buf, uint16_t size); #define ERASE_SIZE 262144L class SDBlock { public: void begin(uint32_t dId); void end(); bool debug; Stream *stream; #ifdef USE_SD2CARD Sd2Card sd; #endif #ifdef USE_SDFS // SdFat sd; // SdExFat sd; SdCardFactory cardFactory; SdFs sd; #endif uint32_t size; // Erase card etc SDBlock_Allocation* allocation; SDBlock_Metadata* metadata; SDBlock_LogLines* loglines; SDBlock_Queue* queue; SDBlock_Block* block; // Thew actual Buffer byte buffer[SDBLOCK_SECTOR_SIZE] = {0x00}; bool getMBR(); bool _sdinit(); bool cardIsOpen(); bool cardErase(); bool cardOpen(uint32_t cId, bool format = false); bool cardClose(); void cardForceClose(); void checkInternals(); bool read(unsigned long address_in); bool write(unsigned long address_in); bool allocationDefault(); bool allocationUpdate(); bool allocationWrite(); bool allocationValid(); bool allocationRead(); void crcUpdate(); bool crcCheck(); void crcSet(); bool validRange(char *str, uint32_t test, uint32_t start, uint32_t max); bool dataIsOpen(); bool dataOpen(uint32_t recId); bool dataClose(bool output); bool dataPrepare(void* in = NULL, uint16_t size = 0); bool dataWrite(void* in = NULL, uint16_t size = 0); bool metadataPrepare(void* in = NULL, uint16_t size = 0); bool metadataWrite(void* in = NULL, uint16_t size = 0); bool metadataRead(uint32_t fromEnd); bool metadataReadBLK(uint32_t address_in); bool metadataUpdateStatus(uint32_t address_in, uint32_t record_in, uint32_t status_in); void metadataList(uint32_t fromEnd, uint32_t num, Print* altstream = NULL); //, CallbackFunction cb = NULL); bool resultsRead(uint32_t adddress); bool resultsReadBLK(uint32_t adddress); // Status Updats, note: BLK - means actual block (where ever it is) /* bool metadataStatusBLK(uint32_t block, uint32_t status); bool dataStatusBLK(uint32_t block, uint32_t status); */ uint32_t metadataCount(); // void dataList(unsigned long address, Print* altstream = NULL, CallbackFunction metadata_cb = NULL, CallbackFunction data_cb = NULL); bool singlePrepare(void* in = NULL, uint16_t size = 0); bool singleWrite(void* in = NULL, uint16_t size = 0); bool singleRead(uint32_t fromEnd); uint32_t singleCount(); void setDeviceId(uint32_t dId); void setRecordId(uint32_t rId); void setAutoFormat(bool in); bool getAutoFormat(); // Very basic queue bool queuePrepare(uint32_t status, void* in = NULL, uint16_t in_size = 0, void* out = NULL, uint16_t out_size = 0); bool queueWrite(uint32_t status = 0, void* in = NULL, uint16_t in_size = 0, void* out = NULL, uint16_t out_size = 0); // Update queue - fromEnd - like Single - include status cahnge, and optional data out bool queueUpdate(uint32_t fromEnd, uint32_t status, void* out = NULL, uint16_t out_size = 0); bool queueRead(uint32_t fromEnd); uint32_t queueCount(); uint32_t getDataNext(); // Get the next block for manual reading uint32_t getMetadataNext(); // Get the next block for manual reading uint8_t getCardId(); // Get the next block for manual reading uint32_t getMetadataFirst(); // Get the next block for manual reading uint32_t getDataFirst(); // Get the next block for manual reading /* Logging: Logging: - Can be implemented completely outside of here. - And just use single or even a pecial set of singles. Basics: - Balance memory with Blocks - a full 512 byte block in memory is probably too much for logging. - logAdd(level, string); . Return something.... to say buffer full, need to writeBlock - logAuto(); // Automatiaclly prepare, write, etc. // Maybe pass param true, says write even if // only one log in the queue - logPrepare(); - logWrite(); */ // Queue. - standard queue commands, work like Single /* More advanced Queue Reader - Next Low|High, Type e.g. High Iridium Send then low Iridium Send Iridium receive Slow to find? Status can be used for all the lookups - 32 bit, 8 bit type 8 bit status 16 bit info (e.g. why it failed, or number of blocsk) Size vs Data WII4 Data * 2 blocks (two transmits) * 299 bytes - 6 blocks * 336 bytes - 7 blocsk * AKA - two blocks on the SD Card So we do have to use a whole SD Card block Early optomisation is death * Use CaptureMode code or Iridium code to manage. * Simplified walking queueRead(rec); if (status - in range - ie. not sent, right type) sendIridium recordResults back in records queueUpdate(rec, X,Y,Z) rec++; if (rec > 10000) { // That will do. exit } queueNextHigh(X) queuePrepare queueWrite queueRead - like single, from end queueReadHigh - Read most resent high queueReadLow - Read most resent low queueUpdate(id, stuff - eg status) */ uint32_t dataLast; uint32_t metadataLast; uint32_t queueLast; uint32_t singleLast; protected: byte response; // Resuable for all read/write uint32_t crc; uint32_t address_local; // Temporary location of calculated addresses uint32_t count; // Reusable counter (for loops) bool autoFormat; // Automatically format on failure // Allocation tabler uint32_t dataBlockNext; // Next, becasue first record is 0, so initilaly we write there uint32_t metadataBlockNext; // And of course where is the Metadata uint32_t singleBlockNext; // And of course where is the Metadata uint32_t loglinesBlockNext; // And of course where is the Metadata uint32_t queueBlockNext; // And of course where is the Metadata // Card read, open and valid bool valid; // Current DATA uint32_t dataBlockStart; uint32_t dataBlockCurrent; uint32_t dataBlockRecordId; uint32_t metadata_dataBlockStart; uint32_t metadata_dataBlocks; uint32_t metadata_resultsBlockStart; uint32_t metadata_resultsBlocks; uint32_t cardId; uint32_t deviceId; uint32_t recordId; }; extern SDBlock sdBlock; #endif