260 lines
6.5 KiB
C++
260 lines
6.5 KiB
C++
#ifndef SDBlock_h
|
|
#define SDBlock_h
|
|
|
|
// #define USE_SDCORE
|
|
#define USE_SD2CARD
|
|
// #define USE_SDFS
|
|
|
|
#ifdef USE_SDCORE
|
|
#include <SDCore.h>
|
|
#endif
|
|
|
|
#ifdef USE_SD2CARD
|
|
#include <SPI.h>
|
|
#include <SD.h>
|
|
#endif
|
|
|
|
#ifdef USE_SDFS
|
|
#include <SdFs.h>
|
|
// if (!sd.card()->readSector(0, (uint8_t*)&mbr)) {
|
|
#define SD_CS_PIN SS
|
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI)
|
|
#endif
|
|
|
|
#include <TimeLib.h>
|
|
#include <CRC32.h>
|
|
#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
|