#include #define SINE_WAVE_ARRAY_LENGTH 26 #define BLOCK_SIZE 512 #define MAX_NUM_BLOCKS 128 #define INIT_SAMPLE_RATE 1600 const uint8_t chipSelect = 53; // Chip select pin SdFs sd; typedef enum { BEING_FILLED, FILLED, BEING_EMPTIED, EMPTY } myBufferState_t; typedef struct { myBufferState_t state; uint8_t buffer[BLOCK_SIZE]; } sdCardBlock_t; sdCardBlock_t redBuffer, blueBuffer; volatile bool collectAudioData = false; uint16_t sampleRate = INIT_SAMPLE_RATE; void setup() { Serial.begin(9600); while (!Serial); redBuffer.state = BEING_FILLED; blueBuffer.state = BEING_FILLED; } void loop() { uint8_t i, status, row, sinIndex; const uint8_t sin[SINE_WAVE_ARRAY_LENGTH] = {128, 159, 187, 213, 233, 248, 255, 255, 248, 233, 213, 187, 159, 128, 97, 69, 43, 23, 8, 1, 1, 8, 23, 43, 69, 97}; uint16_t sample; uint16_t blockCount; uint64_t sdCardAddress = 0x0000000000; uint64_t loopSDcardAddress; char cmd; for(;;){ if (Serial.available()) { char cmd = Serial.read(); switch (cmd) { case 'i': sd.begin(chipSelect, SPI_FULL_SPEED); Serial.println("SD card initialized"); break; case 'a': case 'A': if (cmd == 'a') { sdCardAddress -= BLOCK_SIZE; // 0x04000000 is 2^10 * 2^10 * 2^6 which is 64M // 2^10 * 2^10 * 2^10 is 1G, so 16 G is 2^4 * 2^10 * 2^10 * 2^10 = 2^34, is 0x0400000000 if (sdCardAddress >= 0x0400000000) { Serial.println("Underflowed to high address"); sdCardAddress = 0x0400000000 - BLOCK_SIZE; } else { Serial.println("Decreased address"); } } else { sdCardAddress += BLOCK_SIZE; if (sdCardAddress >= 0x0400000000) { Serial.println("Overflowed to low address"); sdCardAddress = 0x0000000000; } else { Serial.println("Increased address"); } } case '0': loopSDcardAddress = 0; for (blockCount = 0; blockCount < MAX_NUM_BLOCKS; blockCount++) { // MAX_NUM_BLOCKS is set as 128 // BLOCK_SIZE is 512 bytes (per page or per block, very common value for SD cards) for (sample = 0; sample < BLOCK_SIZE; sample++) redBuffer.buffer[sample] = blockCount; if (!sd.card()->writeStart(loopSDcardAddress)) { Serial.println("Write start failed."); sd.initErrorHalt(); } // Write the data to the started block if (!sd.card()->writeData(redBuffer.buffer)) { Serial.println("Write data failed."); sd.initErrorHalt(); } // Stop the write operation if (!sd.card()->writeStop()) { Serial.println("Write stop failed."); sd.initErrorHalt(); } loopSDcardAddress += BLOCK_SIZE; } Serial.println("Write block success."); break; case '1': // this is the number 1, not lower case L loopSDcardAddress = 0; sinIndex = 0; for (blockCount = 0; blockCount < MAX_NUM_BLOCKS; blockCount++) { for (sample = 0; sample < BLOCK_SIZE; sample++) { redBuffer.buffer[sample] = sin[sinIndex]; sinIndex += 1; if (sinIndex == SINE_WAVE_ARRAY_LENGTH) sinIndex = 0; } if (!sd.card()->writeStart(loopSDcardAddress)) { Serial.println("Write start failed."); sd.initErrorHalt(); } // Write the data to the started block if (!sd.card()->writeData(redBuffer.buffer)) { Serial.println("Write data failed."); sd.initErrorHalt(); } // Stop the write operation if (!sd.card()->writeStop()) { Serial.println("Write stop failed."); sd.initErrorHalt(); } loopSDcardAddress += BLOCK_SIZE; } Serial.println("Write block success."); break; case 's': Serial.println("Spooling data to CSV. Press any key to stop."); Serial.println("Log to file in terminal: enable logging, set .csv extension."); while (!Serial.available()); Serial.read(); blockCount = 0; loopSDcardAddress = 0; // Start the read operation for a single block while (!Serial.available()){ if (!sd.card()->readStart(loopSDcardAddress)) { Serial.println("Read start failed."); sd.initErrorHalt(); } // Read the data from the started block if (!sd.card()->readData(redBuffer.buffer)) { Serial.println("Read data failed."); sd.initErrorHalt(); } loopSDcardAddress += BLOCK_SIZE; blockCount += 1; for (uint16_t i = 0; i < BLOCK_SIZE; i++) { Serial.println(redBuffer.buffer[i]); } } break; } } } }