├── OpenBCI_8bit_Library └── OpenBCI_8 │ ├── ADS1299.cpp │ ├── ADS1299.h │ ├── Definitions.h │ ├── HonorALovedOne.cpp │ ├── LIS3DH.cpp │ ├── LIS3DH.h │ ├── OpenBCI_8.cpp │ └── OpenBCI_8.h ├── OpenBCI_8bit_SD ├── OpenBCI_8bit_SD.ino └── SDcard.ino ├── OpenBCI_8bit_SDfat_Library └── SdFat │ ├── ArduinoStream.h │ ├── MinimumSerial.cpp │ ├── MinimumSerial.h │ ├── Sd2Card.cpp │ ├── Sd2Card.h │ ├── SdBaseFile.cpp │ ├── SdBaseFile.h │ ├── SdBaseFilePrint.cpp │ ├── SdFat.cpp │ ├── SdFat.h │ ├── SdFatConfig.h │ ├── SdFatErrorPrint.cpp │ ├── SdFatStructs.h │ ├── SdFatUtil.cpp │ ├── SdFatUtil.h │ ├── SdFatmainpage.h │ ├── SdFile.cpp │ ├── SdFile.h │ ├── SdInfo.h │ ├── SdSpi.h │ ├── SdSpiAVR.cpp │ ├── SdSpiArduino.cpp │ ├── SdSpiMK20DX128.cpp │ ├── SdSpiSAM3X.cpp │ ├── SdStream.cpp │ ├── SdStream.h │ ├── SdVolume.cpp │ ├── SdVolume.h │ ├── bufstream.h │ ├── examples │ ├── AnalogLogger │ │ └── AnalogLogger.ino │ ├── HelloWorld │ │ └── HelloWorld.ino │ ├── MiniSerial │ │ └── MiniSerial.ino │ ├── OpenNext │ │ └── OpenNext.ino │ ├── PrintBenchmark │ │ └── PrintBenchmark.ino │ ├── QuickStart │ │ └── QuickStart.ino │ ├── RawWrite │ │ └── RawWrite.ino │ ├── ReadWriteSdFat │ │ └── ReadWriteSdFat.ino │ ├── SD_Size │ │ └── SD_Size.ino │ ├── SdFatSize │ │ └── SdFatSize.ino │ ├── SdFormatter │ │ └── SdFormatter.ino │ ├── SdInfo │ │ └── SdInfo.ino │ ├── StressTest │ │ └── StressTest.ino │ ├── Timestamp │ │ └── Timestamp.ino │ ├── TwoCards │ │ └── TwoCards.ino │ ├── append │ │ └── append.ino │ ├── average │ │ └── average.ino │ ├── bench │ │ └── bench.ino │ ├── benchSD │ │ └── benchSD.ino │ ├── bufstream │ │ └── bufstream.ino │ ├── cin_cout │ │ └── cin_cout.ino │ ├── eventlog │ │ └── eventlog.ino │ ├── fgets │ │ └── fgets.ino │ ├── fgetsRewrite │ │ └── fgetsRewrite.ino │ ├── formatting │ │ └── formatting.ino │ ├── getline │ │ └── getline.ino │ ├── readCSV │ │ └── readCSV.ino │ ├── readlog │ │ └── readlog.ino │ └── rename │ │ └── rename.ino │ ├── ios.h │ ├── iostream.h │ ├── istream.cpp │ ├── istream.h │ ├── ostream.cpp │ ├── ostream.h │ └── utility │ ├── DigitalPin.h │ └── SoftSPI.h └── README.md /OpenBCI_8bit_Library/OpenBCI_8/ADS1299.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef ____ADS1299__ 4 | #define ____ADS1299__ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "pins_arduino.h" 10 | #include "Definitions.h" 11 | 12 | class ADS1299 { 13 | public: 14 | 15 | void initialize(); 16 | 17 | //ADS1299 SPI Command Definitions 18 | //System Commands 19 | void WAKEUP(void); // get out of low power mode 20 | void STANDBY(void); // go into low power mode 21 | void RESET(void); // set all register values to default 22 | void START(void); // start data acquisition 23 | void STOP(void); // stop data acquisition 24 | 25 | //Data Read Commands 26 | void RDATAC(); 27 | void SDATAC(); 28 | void RDATA(); 29 | 30 | //Register Read/Write Commands 31 | 32 | byte RREG(byte); // read one register 33 | void RREGS(byte, byte); // read multiple registers 34 | void WREG(byte, byte); // write one register 35 | void WREGS(byte, byte); // write multiple registers 36 | byte getDeviceID(); 37 | void printRegisterName(byte); // used for verbosity 38 | void printHex(byte); // used for verbosity 39 | void updateChannelData(void); // retrieve data from ADS 40 | 41 | byte xfer(byte); // SPI Transfer function 42 | int DRDY, CS, RST; // pin numbers for DataRead ChipSelect Reset pins 43 | int DIVIDER; // select SPI SCK frequency 44 | int stat; // used to hold the status register 45 | byte regData [24]; // array is used to mirror register data 46 | long channelData [9]; // array used when reading channel data as ints 47 | byte bit24ChannelData[24]; // array to hold raw channel data 48 | char channelSettings[8][6]; // array to hold current channel settings 49 | char defaultChannelSettings[6]; // default channel settings 50 | boolean useInBias[8]; // used to remember if we were included in Bias before channel power down 51 | boolean useSRB1; // used to keep track of if we are using SRB1 52 | boolean useSRB2[8]; // used to remember if we were included in SRB2 before channel power down 53 | char leadOffSettings[8][2]; // used to control on/off of impedance measure for P and N side of each channel 54 | boolean verbosity; // turn on/off Serial feedback 55 | 56 | 57 | void resetADS(void); //reset all the ADS1299's settings. Call however you'd like 58 | void startADS(void); 59 | void stopADS(void); 60 | 61 | void writeChannelSettings(void); 62 | void writeChannelSettings(int); 63 | void activateChannel(int); // activate a given channel 1-8 64 | void reportDefaultChannelSettings(void); 65 | void deactivateChannel(int); //disable given channel 1-8 66 | 67 | void configureLeadOffDetection(byte, byte); 68 | void changeChannelLeadOffDetection(void); 69 | void configureInternalTestSignal(byte, byte); 70 | 71 | boolean isDataAvailable(void); 72 | void writeADSchannelData(void); 73 | void printAllRegisters(void); 74 | void setSRB1(boolean desired_state); 75 | void printDeviceID(void); 76 | 77 | private: 78 | 79 | boolean isRunning; 80 | void csLow(); 81 | void csHigh(); 82 | 83 | }; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /OpenBCI_8bit_Library/OpenBCI_8/Definitions.h: -------------------------------------------------------------------------------- 1 | // 2 | // Definitions.h 3 | // 4 | // 5 | // Created by Conor Russomanno, Luke Travis, and Joel Murphy. Summer 2013. 6 | // 7 | // 8 | 9 | #ifndef _Definitions_h // add _8_ 10 | #define _Definitions_h 11 | 12 | //SPI 13 | #define SPI_DATA_MODE 0x04 //CPOL = 0; CPHA = 1 (Datasheet, p8) 14 | #define SPI_MODE_MASK 0x0C // mask of CPOL and CPHA on SPCR 15 | #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR 16 | #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR 17 | #define SPI_CLOCK_DIV_2 0X04 // 8MHz SPI SCK 18 | #define SPI_CLOCK_DIV_4 0X00 // 4MHz SPI SCK 19 | #define SPI_CLOCK_DIV_16 0x01 // 1MHz SPI SCK 20 | 21 | //PIN CONNECTIONS 22 | #define ADS_DRDY (8) 23 | #define ADS_RST (9) 24 | #define SCK_MHZ (4) 25 | #define ADS_SS (10) // ADS chip select 26 | #define DAISY_SS (7) // ADS Daisy chip select 27 | #define SD_SS (6) // SD card chip select 28 | #define LIS3DH_SS (5) // LIS3DH chip select 29 | 30 | //ADS1299 SPI Command Definition Byte Assignments 31 | #define _WAKEUP 0x02 // Wake-up from standby mode 32 | #define _STANDBY 0x04 // Enter Standby mode 33 | #define _RESET 0x06 // Reset the device registers to default 34 | #define _START 0x08 // Start and restart (synchronize) conversions 35 | #define _STOP 0x0A // Stop conversion 36 | #define _RDATAC 0x10 // Enable Read Data Continuous mode (default mode at power-up) 37 | #define _SDATAC 0x11 // Stop Read Data Continuous mode 38 | #define _RDATA 0x12 // Read data by command; supports multiple read back 39 | 40 | //ASD1299 Register Addresses 41 | #define ID 0x00 42 | #define CONFIG1 0x01 43 | #define CONFIG2 0x02 44 | #define CONFIG3 0x03 45 | #define LOFF 0x04 46 | #define CH1SET 0x05 47 | #define CH2SET 0x06 48 | #define CH3SET 0x07 49 | #define CH4SET 0x08 50 | #define CH5SET 0x09 51 | #define CH6SET 0x0A 52 | #define CH7SET 0x0B 53 | #define CH8SET 0x0C 54 | #define BIAS_SENSP 0x0D 55 | #define BIAS_SENSN 0x0E 56 | #define LOFF_SENSP 0x0F 57 | #define LOFF_SENSN 0x10 58 | #define LOFF_FLIP 0x11 59 | #define LOFF_STATP 0x12 60 | #define LOFF_STATN 0x13 61 | #define GPIO 0x14 62 | #define MISC1 0x15 63 | #define MISC2 0x16 64 | #define CONFIG4 0x17 65 | 66 | #define OPENBCI_NCHAN (8) // number of EEG channels 67 | // CHANNEL SETTINGS 68 | #define POWER_DOWN (0) 69 | #define GAIN_SET (1) 70 | #define INPUT_TYPE_SET (2) 71 | #define BIAS_SET (3) 72 | #define SRB2_SET (4) 73 | #define SRB1_SET (5) 74 | #define YES (0x01) 75 | #define NO (0x00) 76 | 77 | //gainCode choices 78 | #define ADS_GAIN01 (0b00000000) // 0x00 79 | #define ADS_GAIN02 (0b00010000) // 0x10 80 | #define ADS_GAIN04 (0b00100000) // 0x20 81 | #define ADS_GAIN06 (0b00110000) // 0x30 82 | #define ADS_GAIN08 (0b01000000) // 0x40 83 | #define ADS_GAIN12 (0b01010000) // 0x50 84 | #define ADS_GAIN24 (0b01100000) // 0x60 85 | 86 | //inputType choices 87 | #define ADSINPUT_NORMAL (0b00000000) 88 | #define ADSINPUT_SHORTED (0b00000001) 89 | #define ADSINPUT_BIAS_MEAS (0b00000010) 90 | #define ADSINPUT_MVDD (0b00000011) 91 | #define ADSINPUT_TEMP (0b00000100) 92 | #define ADSINPUT_TESTSIG (0b00000101) 93 | #define ADSINPUT_BIAS_DRP (0b00000110) 94 | #define ADSINPUT_BIAS_DRN (0b00000111) 95 | 96 | //test signal choices...ADS1299 datasheet page 41 97 | #define ADSTESTSIG_AMP_1X (0b00000000) 98 | #define ADSTESTSIG_AMP_2X (0b00000100) 99 | #define ADSTESTSIG_PULSE_SLOW (0b00000000) 100 | #define ADSTESTSIG_PULSE_FAST (0b00000001) 101 | #define ADSTESTSIG_DCSIG (0b00000011) 102 | #define ADSTESTSIG_NOCHANGE (0b11111111) 103 | 104 | //Lead-off signal choices 105 | #define LOFF_MAG_6NA (0b00000000) 106 | #define LOFF_MAG_24NA (0b00000100) 107 | #define LOFF_MAG_6UA (0b00001000) 108 | #define LOFF_MAG_24UA (0b00001100) 109 | #define LOFF_FREQ_DC (0b00000000) 110 | #define LOFF_FREQ_7p8HZ (0b00000001) 111 | #define LOFF_FREQ_31p2HZ (0b00000010) 112 | #define LOFF_FREQ_FS_4 (0b00000011) 113 | #define PCHAN (0) 114 | #define NCHAN (1) 115 | #define OFF (0) 116 | #define ON (1) 117 | 118 | // used for channel settings 119 | #define ACTIVATE_SHORTED (2) 120 | #define ACTIVATE (1) 121 | #define DEACTIVATE (0) 122 | 123 | #define PCKT_START 0xA0 // prefix for data packet error checking 124 | #define PCKT_END 0xC0 // postfix for data packet error checking 125 | 126 | //LIS3DH 127 | #define READ_REG 0x80 128 | #define READ_MULTI 0x40 129 | #define LIS3DH_DRDY 3 130 | 131 | #define LIS3DH_MODE 3 // c pol =1, c pha = 1, mode = 3 132 | #define STATUS_REG_AUX 0x07 // axis over-run and data available flags (see 0x27) 133 | #define OUT_ADC1_L 0x08 // 134 | #define OUT_ADC1_H 0x09 // 135 | #define OUT_ADC2_L 0x0A // ADC input values (check DS) 136 | #define OUT_ADC2_H 0x0B // 137 | #define OUT_ADC3_L 0x0C // 138 | #define OUT_ADC3_H 0x0D // 139 | #define INT_COUNTER_REG 0x0E // ?? 140 | #define WHO_AM_I 0x0F // DEVICE ID = 0x33 141 | #define TMP_CFG_REG 0x1F // ADC enable (0x80); Temperature sensor enable (0x40) 142 | #define CTRL_REG1 0x20 // Data Rate; Power Mode; X enable; Y enable; Z enable (on >= 0x10) 143 | #define CTRL_REG2 0x21 // High Pass Filter Stuph 144 | #define CTRL_REG3 0x22 // INT1 select register 145 | #define CTRL_REG4 0x23 // Block update timing; endian; G-force; resolution; self test; SPI pins 146 | #define CTRL_REG5 0x24 // reboot; FIFO enable; latch; 4D detection; 147 | #define CTRL_REG6 0x25 // ?? 148 | #define REFERENCE 0x26 // interrupt reference 149 | #define STATUS_REG2 0x27 // axis overrun and availale flags (see 0x07) 150 | #define OUT_X_L 0x28 // 151 | #define OUT_X_H 0x29 // 152 | #define OUT_Y_L 0x2A // tripple axis values (see 0x0A) 153 | #define OUT_Y_H 0x2B // 154 | #define OUT_Z_L 0x2C // 155 | #define OUT_Z_H 0x2D // 156 | #define FIFO_CTRL_REG 0x2E // FIFO mode; trigger output pin select (?); 157 | #define FIFO_SRC_REG 0x2F // ?? 158 | #define INT1_CFG 0x30 // 6 degree control register 159 | #define INT1_SOURCE 0x31 // axis threshold interrupt control 160 | #define INT1_THS 0x32 // INT1 threshold 161 | #define INT1_DURATION 0x33 // INT1 duration 162 | #define CLICK_CFG 0x38 // click on axis 163 | #define CLICK_SRC 0x39 // other click 164 | #define CLICK_THS 0x3A // more click 165 | #define TIME_LIMIT 0x3B // click related 166 | #define TIME_LATENCY 0x3C // and so on 167 | #define TIME_WINDOW 0x3D // contined click 168 | 169 | #define SCALE_2G 0x00 //(b00000000) // +/- 2G sensitivity 170 | #define SCALE_4G 0x10 //(b00010000) // +/- 4G sensitivity 171 | #define SCALE_8G 0x20 //(b00100000) // +/- 8G sensitivity 172 | #define SCALE_16G 0x30 //(b00110000) // +/- 16G sensitivity 173 | #define RATE_1HZ 0x10 //(b00010000) // 1Hz sample rate in normal or low-power mode 174 | #define RATE_10HZ 0x20 //(b00100000) // 10Hz sample rate in normal or low-power mode 175 | #define RATE_25HZ 0x30 //(b00110000) // 25Hz sample rate in normal or low-power mode 176 | #define RATE_50HZ 0x40 //(b01000000) // 50Hz sample rate in normal or low-power mode 177 | #define RATE_100HZ 0x50 //(b01010000) // 100Hz sample rate in normal or low-power mode 178 | #define RATE_200HZ 0x60 //(b01100000) // 200Hz sample rate in normal or low-power mode 179 | #define RATE_400HZ 0x70 //(b01110000) // 400Hz sample rate in normal or low-power mode 180 | #define RATE_1600HZ_LP 0x80 //(b10000000) // 1600Hz sample rate in low-power mode 181 | #define RATE_1250HZ_N 0x90 //(b10010000) // 1250Hz sample rate in normal mode 182 | #define RATE_5000HZ_LP 0x90 //(b10010000) // 5000Hz sample rate in low-power mode 183 | 184 | 185 | 186 | #endif 187 | -------------------------------------------------------------------------------- /OpenBCI_8bit_Library/OpenBCI_8/HonorALovedOne.cpp: -------------------------------------------------------------------------------- 1 | 2 | //==========================================================// 3 | // OpenBCI Kickstarter Pledge - Honor A Loved One // 4 | //==========================================================// 5 | 6 | /* 7 | Name Of Loved One To Be Honored -- Note About Honored Loved One 8 | Sebi Kravitz -- Super cheerful child, autistic 9 | Emir Emrah Uckan -- :) 10 | Peter A. Newman -- So the body will give way for the mind. 11 | Cecelia Grejda -- Beloved grandmother. You are missed. 12 | Tina Tolk -- A beautiful mind with a heart of gold 13 | All good peoples -- for the best 14 | Shirley R. Lukoff -- The essence of her soul was stolen by dementia. We miss and celebrate the person she was. 15 | See below -- Meant to honor father who studied brain waves but see now the honor level is devoted to those with brain related disease 16 | Woon Lee -- In the hope that BCI can help people who suffer from essential tremor. 17 | Virginia Entwistle -- Could have used this 18 | Anonymous -- 19 | Bernadette Roberta Hilsey -- Cherished wife and mother of four, and devout Irish Catholic, who was a victim of early-onset Alzheimer's disease. 20 | Entropicous -- Shine on you crazy diamond. 21 | Nathan Olshin -- My beloved uncle who had a great brain. 22 | RC -- For a future without disease. 23 | Danny Rodriguez -- A great man destroyed by Alzheimer's. 24 | Sandie Bautista -- My G'ma is the sexiest G'ma around! 25 | Nihat -- A truly amazing man! 26 | GNX -- do your best and good luck 27 | Freja Ishøj -- An explosively creative mind 28 | Nicholas Paul Diamante I -- My beloved grandfather for whom I am named 29 | Michael Andrew Womack -- For my father who didn't live long enough to reap the benefits of open-source brain technology. 30 | Marian Eckert -- W imieniu Dziadka MaÅ„ka 31 | Elissa Donnellan -- A most wonderful sister 32 | Vincent Willem van Gogh -- Great things are done by a series of small things brought together. 33 | Tshukina Galina Alekseevna -- my grandmother 34 | Chester S. Dilday -- Vascular Dementia ended what WWII in the South Pacific and 96 years of hard work could not. 35 | Rebert Ahrensdorf -- Father in law and personal heroes. He rose from poverty to run the International division of The Thomas register. Died from Alzheimer’s @ 94 36 | Lawrence Blomkamp -- This is as much in honour of a wonderful man who suffers from a debilitating neurological disorder as the wonderful woman that stands by his side. Love to you both, forever sweethearts Coleen and Lawrence xxx 37 | Fabiola Scoralick -- My loved daugther born with a left side brain lesion. 38 | Katie Beth Craig -- Katie Beth had CP and needed the help this software could have enabled. It's too late for her, but it will bless others for years to come. 39 | L -- An awesome lady 40 | Elizabeth -- So Very Strong to 99 41 | Amy Almquist -- Her mind became weak but her positive outlook lasted. 42 | Jenny Lawson -- as The Bloggess says, "Depression Lies." But brain waves don't, and hopefully we can see the truth using OpenBCI 43 | morotomihead -- morotomihead 44 | Ali Eslamifar -- Thnk you 45 | David R. Keller -- in honor of my brother's strength to endure his neurological debilitation 46 | Dan Keating -- I want him playing video games again someday. 47 | Mao Tezka -- Gone too soon from an incorrectly treated depression. You will always be loved, never forgotten! 48 | Lindy L Grant -- After suffering a serious stroke back in 2001, Lindy suffers from aphasia and struggles to communicate. 49 | Dr. Frederick Fries -- To my father, a brilliantly mad neurologist. I will love you always. RIP 2010. 50 | Brian Fries -- A victim of addiction that will be missed by many. 51 | Kaya Nicole Inkster Kaya -- is a beautiful and intelligent 12 year old twin with a zest and zeal for life that is unmatched. She suffers from Cerebral Palsy, Dystonia, and now she have been given a diagnosis of "Diagnostic Odyssey". She is an amazing beautiful being. 52 | Pratap Shahani -- . 53 | CURFC -- Not only the source of our special friendship, but the inspiration of our shared interest in medicine and the brain. 54 | All creative people -- All creative people who aren't accommodated in standard Education systems 55 | Jessie VB Warms -- A cancer researcher who lost her keen mind and soul to Alzheimer's. We miss you. 56 | Trond Brox Bjørvik -- An extremely intelligent individual that due to a debilitating brain disease suffered for 8 years, never to make his major impact in this world. 57 | Carillon Leader -- My amazing grandmother, who loved her grandchildren more than anything in the world. Thank you for everything. You inspired me as a teacher, philanthropist, and lover of people. I hope to inspire others as you have me. 58 | */ -------------------------------------------------------------------------------- /OpenBCI_8bit_Library/OpenBCI_8/LIS3DH.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "LIS3DH.h" 4 | 5 | void LIS3DH::initialize(byte g){ 6 | byte setting = g | 0x08; // mask the g range for REG4 7 | pinMode(LIS3DH_SS,OUTPUT); digitalWrite(LIS3DH_SS,HIGH); 8 | pinMode(LIS3DH_DRDY,INPUT); // setup dataReady interupt from accelerometer 9 | LIS3DH_write(TMP_CFG_REG, 0x00); // DISable ADC inputs, enable temperature sensor 10 | LIS3DH_write(CTRL_REG1, 0x08); // disable accel, low power mode 11 | LIS3DH_write(CTRL_REG2, 0x00); // don't use the high pass filter 12 | LIS3DH_write(CTRL_REG3, 0x00); // no interrupts yet 13 | LIS3DH_write(CTRL_REG4, setting); // set scale to g, high resolution 14 | LIS3DH_write(CTRL_REG5, 0x00); // no boot, no fifo 15 | LIS3DH_write(CTRL_REG6, 0x00); 16 | LIS3DH_write(REFERENCE, 0x00); 17 | DRDYpinValue = lastDRDYpinValue = digitalRead(LIS3DH_DRDY); // take a reading to seed these variables 18 | } 19 | 20 | void LIS3DH::enable_accel(byte Hz){ // ADD ABILITY TO SET FREQUENCY & RESOLUTION 21 | for(int i=0; i<3; i++){ 22 | axisData[i] = 0; // clear the axisData array so we don't get any stale news 23 | } 24 | byte setting = Hz | 0x07; // mask the desired frequency 25 | LIS3DH_write(CTRL_REG1, setting); // set freq and enable all axis in normal mode 26 | LIS3DH_write(CTRL_REG3, 0x10); // enable DRDY1 on INT1 (tied to Arduino pin3, LIS3DH_DRDY) 27 | } 28 | 29 | void LIS3DH::disable_accel(){ 30 | LIS3DH_write(CTRL_REG1, 0x08); // power down, low power mode 31 | LIS3DH_write(CTRL_REG3, 0x00); // disable DRDY1 on INT1 32 | } 33 | 34 | byte LIS3DH::getDeviceID(){ 35 | return LIS3DH_read(0x0F); 36 | } 37 | 38 | boolean LIS3DH::LIS3DH_DataReady(){ 39 | boolean r = false; 40 | DRDYpinValue = digitalRead(LIS3DH_DRDY); // take a look at LIS3DH_DRDY pin 41 | if(DRDYpinValue != lastDRDYpinValue){ // if the value has changed since last looking 42 | if(DRDYpinValue == HIGH){ // see if this is the rising edge 43 | r = true; // if so, there is fresh data! 44 | } 45 | lastDRDYpinValue = DRDYpinValue; // keep track of the changing pin 46 | } 47 | return r; 48 | } 49 | 50 | boolean LIS3DH::LIS3DH_DataAvailable(){ 51 | boolean x = false; 52 | if((LIS3DH_read(STATUS_REG2) & 0x08) > 0) x = true; // read STATUS_REG 53 | return x; 54 | } 55 | 56 | void LIS3DH::writeLIS3DHdata(void){ 57 | for(int i=0; i<3; i++){ 58 | Serial.write(highByte(axisData[i])); // write 16 bit axis data MSB first 59 | Serial.write(lowByte(axisData[i])); 60 | axisData[i] = 0; 61 | } 62 | } 63 | 64 | byte LIS3DH::LIS3DH_read(byte reg){ 65 | reg |= READ_REG; // add the READ_REG bit 66 | csLow(); // take spi 67 | SPI.transfer(reg); // send reg to read 68 | byte inByte = SPI.transfer(0x00); // retrieve data 69 | csHigh(); // release spi 70 | return inByte; 71 | } 72 | 73 | void LIS3DH::LIS3DH_write(byte reg, byte value){ 74 | csLow(); // take spi 75 | SPI.transfer(reg); // send reg to write 76 | SPI.transfer(value); // write value 77 | csHigh(); // release spi 78 | } 79 | 80 | int LIS3DH::LIS3DH_read16(byte reg){ // use for reading axis data. 81 | int inData; 82 | reg |= READ_REG | READ_MULTI; // add the READ_REG and READ_MULTI bits 83 | csLow(); // take spi 84 | SPI.transfer(reg); // send reg to start reading from 85 | inData = SPI.transfer(0x00) | (SPI.transfer(0x00) << 8); // get the data and arrange it 86 | csHigh(); // release spi 87 | return inData; 88 | } 89 | 90 | int LIS3DH::LIS3DH_readAxis(byte reg){ 91 | byte Lbyte = LIS3DH_read(reg); 92 | byte Hbyte = LIS3DH_read(reg+1); 93 | int inData = Hbyte; 94 | inData <<= 8; 95 | inData |= Lbyte; 96 | return inData; 97 | } 98 | 99 | int LIS3DH::getX(){ 100 | return LIS3DH_readAxis(OUT_X_L); 101 | } 102 | 103 | int LIS3DH::getY(){ 104 | return LIS3DH_readAxis(OUT_Y_L); 105 | } 106 | 107 | int LIS3DH::getZ(){ 108 | return LIS3DH_readAxis(OUT_Z_L); 109 | } 110 | 111 | int LIS3DH::getX16(){ 112 | return LIS3DH_read16(OUT_X_L); 113 | } 114 | 115 | int LIS3DH::getY16(){ 116 | return LIS3DH_read16(OUT_Y_L); 117 | } 118 | 119 | int LIS3DH::getZ16(){ 120 | return LIS3DH_read16(OUT_Z_L); 121 | } 122 | 123 | void LIS3DH::LIS3DH_updateAxisData(){ 124 | axisData[0] = getX(); 125 | axisData[1] = getY(); 126 | axisData[2] = getZ(); 127 | } 128 | 129 | void LIS3DH::readAllRegs(){ 130 | 131 | byte inByte; 132 | 133 | for (int i = STATUS_REG_AUX; i <= WHO_AM_I; i++){ 134 | inByte = LIS3DH_read(i); 135 | Serial.print(F("0x0"));Serial.print(i,HEX); 136 | Serial.print(F("\t"));Serial.println(inByte,HEX); 137 | delay(20); 138 | } 139 | Serial.println(); 140 | 141 | for (int i = TMP_CFG_REG; i <= INT1_DURATION; i++){ 142 | inByte = LIS3DH_read(i); 143 | Serial.print(F("0x"));Serial.print(i,HEX); 144 | Serial.print(F("\t"));Serial.println(inByte,HEX); 145 | delay(20); 146 | } 147 | Serial.println(); 148 | 149 | for (int i = CLICK_CFG; i <= TIME_WINDOW; i++){ 150 | inByte = LIS3DH_read(i); 151 | Serial.print(F("0x"));Serial.print(i,HEX); 152 | Serial.print(F("\t"));Serial.println(inByte,HEX); 153 | delay(20); 154 | } 155 | 156 | } 157 | 158 | void LIS3DH::csLow(void) 159 | { 160 | SPI.setDataMode(SPI_MODE3); // switch modes 161 | digitalWrite(LIS3DH_SS, LOW); // drop Slave Select 162 | } 163 | 164 | void LIS3DH::csHigh(void) 165 | { 166 | digitalWrite(LIS3DH_SS, HIGH); // raise select 167 | SPI.setDataMode(SPI_MODE0); 168 | } 169 | -------------------------------------------------------------------------------- /OpenBCI_8bit_Library/OpenBCI_8/LIS3DH.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef ____LIS3DH__ 4 | #define ____LIS3DH__ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "pins_arduino.h" 10 | #include "Definitions.h" 11 | 12 | class LIS3DH { 13 | public: 14 | int axisData[3]; 15 | void initialize(byte); 16 | void enable_accel(byte); // start acceleromoeter with default settings 17 | void disable_accel(void); // stop data acquisition and go into low power mode 18 | byte getDeviceID(void); 19 | byte LIS3DH_read(byte); 20 | void LIS3DH_write(byte,byte); 21 | int LIS3DH_read16(byte); 22 | int LIS3DH_readAxis(byte); 23 | int getX(void); 24 | int getY(void); 25 | int getZ(void); 26 | int getX16(void); 27 | int getY16(void); 28 | int getZ16(void); 29 | boolean LIS3DH_DataReady(void); // check LIS3DH_DRDY pin 30 | boolean LIS3DH_DataAvailable(void); 31 | void readAllRegs(void); 32 | void writeLIS3DHdata(void); 33 | void LIS3DH_updateAxisData(void); 34 | 35 | private: 36 | void csLow(); 37 | void csHigh(); 38 | int DRDYpinValue; 39 | int lastDRDYpinValue; 40 | 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /OpenBCI_8bit_Library/OpenBCI_8/OpenBCI_8.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "OpenBCI_8.h" 4 | 5 | void OpenBCI::initialize(void){ 6 | pinMode(SD_SS,OUTPUT); digitalWrite(SD_SS,HIGH); // de-select the SD card if it's there 7 | initialize_ads(); 8 | initialize_accel(SCALE_4G); 9 | } 10 | 11 | void OpenBCI::initialize(byte G){ 12 | pinMode(SD_SS,OUTPUT); digitalWrite(SD_SS,HIGH); // de-select the SD card if it's there 13 | initialize_ads(); 14 | initialize_accel(G); 15 | } 16 | 17 | void OpenBCI::initialize_ads(void) { 18 | ads.initialize(); 19 | } 20 | 21 | void OpenBCI::initialize_accel(byte g) { 22 | accel.initialize(g); 23 | } 24 | 25 | void OpenBCI::enable_accel(byte Hz) { 26 | accel.enable_accel(Hz); 27 | } 28 | 29 | void OpenBCI::disable_accel(void){ 30 | accel.disable_accel(); 31 | } 32 | 33 | byte OpenBCI::getAccelID(void){ 34 | return accel.getDeviceID(); 35 | } 36 | 37 | boolean OpenBCI::LIS3DH_DataReady(void){ 38 | return accel.LIS3DH_DataReady(); 39 | } 40 | 41 | boolean OpenBCI::LIS3DH_DataAvailable(void){ 42 | return accel.LIS3DH_DataAvailable(); 43 | } 44 | 45 | void OpenBCI::updateAccelData(void){ 46 | accel.LIS3DH_updateAxisData(); 47 | } 48 | 49 | 50 | int OpenBCI::getX(void){ return accel.getX(); } 51 | int OpenBCI::getY(void){ return accel.getY(); } 52 | int OpenBCI::getZ(void){ return accel.getZ(); } 53 | 54 | void OpenBCI::printAccelRegisters(){ 55 | accel.readAllRegs(); 56 | } 57 | 58 | 59 | // ADS FUNCTIONS 60 | void OpenBCI::printAllRegisters(void) { 61 | Serial.println("\nADS Registers:"); 62 | ads.printAllRegisters(); 63 | delay(100); 64 | Serial.println("LIS3DH Registers:"); 65 | delay(100); 66 | accel.readAllRegs(); 67 | } 68 | 69 | byte OpenBCI::getADS_ID(void){ 70 | return ads.getDeviceID(); 71 | } 72 | 73 | void OpenBCI::setChannelsToDefault(void){ 74 | ads.channelSettings[0][POWER_DOWN] = NO; // NO = on, YES = off 75 | ads.channelSettings[0][GAIN_SET] = ADS_GAIN24; // Gain setting 76 | ads.channelSettings[0][INPUT_TYPE_SET] = ADSINPUT_NORMAL;// input muxer setting 77 | ads.channelSettings[0][BIAS_SET] = YES; // add this channel to bias generation 78 | ads.channelSettings[0][SRB2_SET] = YES; // connect this P side to SRB2 79 | ads.channelSettings[0][SRB1_SET] = NO; // don't use SRB1 80 | for(int i=1; i<8; i++){ 81 | for(int j=0; j<6; j++){ 82 | ads.channelSettings[i][j] = ads.channelSettings[0][j]; 83 | } 84 | } 85 | updateADSchannelSettings(); 86 | 87 | for(int i=0; i<8; i++){ 88 | ads.leadOffSettings[i][0] = ADSleadOffSettings[i][0] = OFF; 89 | ads.leadOffSettings[i][1] = ADSleadOffSettings[i][1] = OFF; 90 | } 91 | ads.changeChannelLeadOffDetection(); 92 | } 93 | 94 | void OpenBCI::setChannelsToEMG(void){ 95 | ads.channelSettings[0][POWER_DOWN] = NO; // NO = on, YES = off 96 | ads.channelSettings[0][GAIN_SET] = ADS_GAIN12; // Gain setting 97 | ads.channelSettings[0][INPUT_TYPE_SET] = ADSINPUT_NORMAL;// input muxer setting 98 | ads.channelSettings[0][BIAS_SET] = NO; // add this channel to bias generation 99 | ads.channelSettings[0][SRB2_SET] = NO; // connect this P side to SRB2 100 | ads.channelSettings[0][SRB1_SET] = NO; // don't use SRB1 101 | for(int i=1; i<8; i++){ 102 | for(int j=0; j<6; j++){ 103 | ads.channelSettings[i][j] = ads.channelSettings[0][j]; 104 | } 105 | } 106 | updateADSchannelSettings(); 107 | } 108 | 109 | void OpenBCI::setChannelsToECG(void){ 110 | ads.channelSettings[0][POWER_DOWN] = NO; // NO = on, YES = off 111 | ads.channelSettings[0][GAIN_SET] = ADS_GAIN12; // Gain setting 112 | ads.channelSettings[0][INPUT_TYPE_SET] = ADSINPUT_NORMAL;// input muxer setting 113 | ads.channelSettings[0][BIAS_SET] = NO; // add this channel to bias generation 114 | ads.channelSettings[0][SRB2_SET] = NO; // connect this P side to SRB2 115 | ads.channelSettings[0][SRB1_SET] = NO; // don't use SRB1 116 | for(int i=1; i<8; i++){ 117 | for(int j=0; j<6; j++){ 118 | ads.channelSettings[i][j] = ads.channelSettings[0][j]; 119 | } 120 | } 121 | updateADSchannelSettings(); 122 | } 123 | 124 | void OpenBCI::updateADSchannelSettings(void){ 125 | ads.writeChannelSettings(); 126 | } 127 | 128 | void OpenBCI::writeADSchannelSettings(void){ 129 | ads.writeChannelSettings(); 130 | } 131 | 132 | void OpenBCI::writeADSchannelSettings(int chan){ 133 | ads.writeChannelSettings(chan); 134 | } 135 | 136 | void OpenBCI::reportDefaultChannelSettings(void){ 137 | ads.reportDefaultChannelSettings(); 138 | } 139 | 140 | void OpenBCI::activateChannel(int chan){ 141 | ads.activateChannel(chan); 142 | } 143 | 144 | 145 | void OpenBCI::deactivateChannel(int N){ 146 | ads.deactivateChannel(N); 147 | } 148 | 149 | void OpenBCI::startStreaming(void){ 150 | ads.startADS(); 151 | } 152 | 153 | void OpenBCI::stopStreaming(void){ 154 | ads.stopADS(); 155 | accel.disable_accel(); 156 | } 157 | 158 | void OpenBCI::reset_ads(void){ 159 | ads.resetADS(); 160 | } 161 | 162 | boolean OpenBCI::isDataAvailable(void){ 163 | return ads.isDataAvailable(); 164 | } 165 | 166 | void OpenBCI::updateChannelData(void){ 167 | ads.updateChannelData(); 168 | } 169 | 170 | void OpenBCI::sendChannelData(byte sampleNumber){ 171 | Serial.write(sampleNumber); // 1 byte 172 | ads.writeADSchannelData(); // 24 bytes 173 | if(useAux){ 174 | writeAuxData(); // 3 16bit shorts 175 | useAux = false; 176 | }else{ 177 | accel.writeLIS3DHdata(); // 6 bytes 178 | } 179 | } 180 | 181 | void OpenBCI::writeAuxData(){ 182 | for(int i=0; i<3; i++){ 183 | Serial.write(highByte(auxData[i])); // write 16 bit axis data MSB first 184 | Serial.write(lowByte(auxData[i])); // axisData is array of type short (16bit) 185 | auxData[i] = 0; // reset auxData bytes to 0 186 | } 187 | } 188 | 189 | long OpenBCI::getChannel(int chan){ 190 | return ads.channelData[chan]; 191 | } 192 | 193 | void OpenBCI::putChannel(int chan, long val){ 194 | ads.channelData[chan] = val; 195 | } 196 | 197 | void OpenBCI::update24bitData(){ 198 | int indexCounter = 0; 199 | for(int i=0; i<8; i++){ 200 | for(int j=2; j>=0; j--){ 201 | ads.bit24ChannelData[indexCounter] = byte(ads.channelData[i] >> (8*j)); 202 | indexCounter++; 203 | } 204 | } 205 | } 206 | 207 | // Electrode-Off Detection Functions 208 | 209 | void OpenBCI::changeChannelLeadOffDetect(){ 210 | for(int i=0; i<8; i++){ 211 | ads.leadOffSettings[i][0] = ADSleadOffSettings[i][0]; 212 | ads.leadOffSettings[i][1] = ADSleadOffSettings[i][1]; 213 | } 214 | ads.changeChannelLeadOffDetection(); 215 | } 216 | 217 | void OpenBCI::configure_Zdetect(byte amplitudeCode, byte freqCode){ 218 | ads.configureLeadOffDetection(amplitudeCode, freqCode); 219 | } 220 | 221 | 222 | //Configure the test signals that can be inernally generated by the ADS1299 223 | void OpenBCI::configureInternalTestSignal(byte amplitudeCode, byte freqCode) 224 | { 225 | ads.configureInternalTestSignal(amplitudeCode, freqCode); 226 | } 227 | 228 | -------------------------------------------------------------------------------- /OpenBCI_8bit_Library/OpenBCI_8/OpenBCI_8.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef _____OpenBCI_8__ 4 | #define _____OpenBCI_8__ 5 | 6 | #include 7 | #include 8 | 9 | #include "ADS1299.h" 10 | #include "LIS3DH.h" 11 | #include "Definitions.h" 12 | 13 | class OpenBCI { 14 | 15 | public: 16 | 17 | ADS1299 ads; 18 | LIS3DH accel; 19 | ADS1299 daisy; 20 | 21 | // VARIABLES 22 | char ADSchannelSettings[8][6]; 23 | char ADSleadOffSettings[8][2]; 24 | boolean useAccel; 25 | int outputType; // we have a few output types 26 | int auxData[3]; 27 | boolean useAux; 28 | 29 | // BOARD WIDE FUNCTIONS 30 | void initialize(void); 31 | void initialize(byte); 32 | void updateChannelSettings(void); 33 | void writeChannelSettings(void); 34 | void setChannelsToDefault(void); 35 | void setChannelsToEMG(void); 36 | void setChannelsToECG(void); 37 | void sendChannelData(byte); 38 | void reportDefaultChannelSettings(void); 39 | void startStreaming(void); 40 | void stopStreaming(void); 41 | void writeAuxData(void); 42 | 43 | // ADS1299 FUNCITONS 44 | void initialize_ads(void); 45 | void printAllRegisters(void); 46 | void updateADSchannelSettings(void); 47 | void writeADSchannelSettings(void); 48 | void writeADSchannelSettings(int); 49 | void activateChannel(int); 50 | void activateChannel(int, byte, byte, boolean); 51 | void deactivateChannel(int); 52 | void configureInternalTestSignal(byte,byte); 53 | void configure_Zdetect(byte,byte); 54 | void changeChannelLeadOffDetect(void); 55 | void reset_ads(void); 56 | boolean isDataAvailable(void); 57 | void updateChannelData(void); 58 | void setSRB1(boolean); 59 | byte getADS_ID(void); 60 | byte defaultChannelBitField(void); 61 | long getChannel(int); 62 | void putChannel(int, long); 63 | void update24bitData(void); 64 | 65 | // ACCELEROMETER FUNCIONS 66 | void initialize_accel(byte); 67 | void disable_accel(void); 68 | void enable_accel(byte); 69 | byte getAccelID(void); 70 | void updateAccelData(void); 71 | boolean LIS3DH_DataReady(void); 72 | boolean LIS3DH_DataAvailable(void); 73 | int getX(void); 74 | int getY(void); 75 | int getZ(void); 76 | void testAccel(void); 77 | void printAccelRegisters(void); 78 | 79 | 80 | 81 | }; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/ArduinoStream.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef ArduinoStream_h 21 | #define ArduinoStream_h 22 | /** 23 | * \file 24 | * \brief ArduinoInStream and ArduinoOutStream classes 25 | */ 26 | #include 27 | //============================================================================== 28 | /** 29 | * \class ArduinoInStream 30 | * \brief Input stream for Arduino Stream objects 31 | */ 32 | class ArduinoInStream : public ibufstream { 33 | public: 34 | /** 35 | * Constructor 36 | * \param[in] hws hardware stream 37 | * \param[in] buf buffer for input line 38 | * \param[in] size size of input buffer 39 | */ 40 | ArduinoInStream(Stream &hws, char* buf, size_t size) { 41 | m_hw = &hws; 42 | m_line = buf; 43 | m_size = size; 44 | } 45 | /** read a line. */ 46 | void readline() { 47 | size_t i = 0; 48 | uint32_t t; 49 | m_line[0] = '\0'; 50 | while (!m_hw->available()); 51 | 52 | while (1) { 53 | t = millis(); 54 | while (!m_hw->available()) { 55 | if ((millis() - t) > 10) goto done; 56 | } 57 | if (i >= (m_size - 1)) { 58 | setstate(failbit); 59 | return; 60 | } 61 | m_line[i++] = m_hw->read(); 62 | m_line[i] = '\0'; 63 | } 64 | done: 65 | init(m_line); 66 | } 67 | 68 | protected: 69 | /** Internal - do not use. 70 | * \param[in] off 71 | * \param[in] way 72 | * \return true/false. 73 | */ 74 | bool seekoff(off_type off, seekdir way) {return false;} 75 | /** Internal - do not use. 76 | * \param[in] pos 77 | * \return true/false. 78 | */ 79 | bool seekpos(pos_type pos) {return false;} 80 | 81 | private: 82 | char *m_line; 83 | size_t m_size; 84 | Stream* m_hw; 85 | }; 86 | //============================================================================== 87 | /** 88 | * \class ArduinoOutStream 89 | * \brief Output stream for Arduino Print objects 90 | */ 91 | class ArduinoOutStream : public ostream { 92 | public: 93 | /** constructor 94 | * 95 | * \param[in] pr Print object for this ArduinoOutStream. 96 | */ 97 | explicit ArduinoOutStream(Print& pr) : m_pr(&pr) {} 98 | 99 | protected: 100 | /// @cond SHOW_PROTECTED 101 | /** 102 | * Internal do not use 103 | * \param[in] c 104 | */ 105 | void putch(char c) { 106 | if (c == '\n') m_pr->write('\r'); 107 | m_pr->write(c); 108 | } 109 | void putstr(const char* str) {m_pr->write(str);} 110 | bool seekoff(off_type off, seekdir way) {return false;} 111 | bool seekpos(pos_type pos) {return false;} 112 | bool sync() {return true;} 113 | pos_type tellpos() {return 0;} 114 | /// @endcond 115 | private: 116 | ArduinoOutStream() {} 117 | Print* m_pr; 118 | }; 119 | #endif // ArduinoStream_h 120 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/MinimumSerial.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #if defined(UDR0) || defined(DOXYGEN) 22 | #include 23 | //------------------------------------------------------------------------------ 24 | /** 25 | * Set baud rate for serial port zero and enable in non interrupt mode. 26 | * Do not call this function if you use another serial library. 27 | * \param[in] baud rate 28 | */ 29 | void MinimumSerial::begin(uint32_t baud) { 30 | uint16_t baud_setting; 31 | // don't worry, the compiler will squeeze out F_CPU != 16000000UL 32 | if (F_CPU != 16000000UL || baud != 57600) { 33 | // Double the USART Transmission Speed 34 | UCSR0A = 1 << U2X0; 35 | baud_setting = (F_CPU / 4 / baud - 1) / 2; 36 | } else { 37 | // hardcoded exception for compatibility with the bootloader shipped 38 | // with the Duemilanove and previous boards and the firmware on the 8U2 39 | // on the Uno and Mega 2560. 40 | UCSR0A = 0; 41 | baud_setting = (F_CPU / 8 / baud - 1) / 2; 42 | } 43 | // assign the baud_setting 44 | UBRR0H = baud_setting >> 8; 45 | UBRR0L = baud_setting; 46 | // enable transmit and receive 47 | UCSR0B |= (1 << TXEN0) | (1 << RXEN0); 48 | } 49 | //------------------------------------------------------------------------------ 50 | /** 51 | * Unbuffered read 52 | * \return -1 if no character is available or an available character. 53 | */ 54 | int MinimumSerial::read() { 55 | if (UCSR0A & (1 << RXC0)) return UDR0; 56 | return -1; 57 | } 58 | //------------------------------------------------------------------------------ 59 | /** 60 | * Unbuffered write 61 | * 62 | * \param[in] b byte to write. 63 | * \return 1 64 | */ 65 | size_t MinimumSerial::write(uint8_t b) { 66 | while (((1 << UDRIE0) & UCSR0B) || !(UCSR0A & (1 << UDRE0))) {} 67 | UDR0 = b; 68 | return 1; 69 | } 70 | MinimumSerial MiniSerial; 71 | #endif // defined(UDR0) || defined(DOXYGEN) 72 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/MinimumSerial.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef MinimumSerial_h 21 | #define MinimumSerial_h 22 | /** 23 | * \class MinimumSerial 24 | * \brief mini serial class for the %SdFat library. 25 | */ 26 | class MinimumSerial : public Print { 27 | public: 28 | void begin(uint32_t baud); 29 | int read(); 30 | size_t write(uint8_t b); 31 | using Print::write; 32 | }; 33 | #ifdef UDR0 34 | extern MinimumSerial MiniSerial; 35 | #endif // UDR0 36 | #endif // MinimumSerial_h 37 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdFat.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef SdFat_h 21 | #define SdFat_h 22 | /** 23 | * \file 24 | * \brief SdFat class 25 | */ 26 | //------------------------------------------------------------------------------ 27 | /** Macro for debug. */ 28 | #define DBG_FAIL_MACRO // Serial.print(__FILE__);Serial.println(__LINE__) 29 | //------------------------------------------------------------------------------ 30 | /** SdFat version YYYYMMDD */ 31 | #define SD_FAT_VERSION 20131225 32 | //------------------------------------------------------------------------------ 33 | /** error if old IDE */ 34 | #if !defined(ARDUINO) || ARDUINO < 100 35 | #error Arduino IDE must be 1.0 or greater 36 | #endif // ARDUINO < 100 37 | //------------------------------------------------------------------------------ 38 | #include 39 | #include 40 | #include 41 | #include 42 | //------------------------------------------------------------------------------ 43 | /** 44 | * \class SdFat 45 | * \brief Integration class for the %SdFat library. 46 | */ 47 | class SdFat { 48 | public: 49 | SdFat() {} 50 | /** \return a pointer to the Sd2Card object. */ 51 | Sd2Card* card() {return &m_card;} 52 | bool chdir(bool set_cwd = false); 53 | bool chdir(const char* path, bool set_cwd = false); 54 | void chvol(); 55 | void errorHalt(); 56 | void errorHalt(char const *msg); 57 | void errorPrint(); 58 | void errorPrint(char const *msg); 59 | bool exists(const char* name); 60 | bool begin(uint8_t chipSelectPin = SD_CHIP_SELECT_PIN, 61 | uint8_t sckDivisor = SPI_FULL_SPEED); 62 | void initErrorHalt(); 63 | void initErrorHalt(char const *msg); 64 | void initErrorPrint(); 65 | void initErrorPrint(char const *msg); 66 | void ls(uint8_t flags = 0); 67 | void ls(Print* pr, uint8_t flags = 0); 68 | bool mkdir(const char* path, bool pFlag = true); 69 | bool remove(const char* path); 70 | bool rename(const char *oldPath, const char *newPath); 71 | bool rmdir(const char* path); 72 | bool truncate(const char* path, uint32_t length); 73 | /** \return a pointer to the SdVolume object. */ 74 | SdVolume* vol() {return &m_vol;} 75 | /** \return a pointer to the volume working directory. */ 76 | SdBaseFile* vwd() {return &m_vwd;} 77 | //---------------------------------------------------------------------------- 78 | void errorHalt_P(PGM_P msg); 79 | void errorPrint_P(PGM_P msg); 80 | void initErrorHalt_P(PGM_P msg); 81 | void initErrorPrint_P(PGM_P msg); 82 | //---------------------------------------------------------------------------- 83 | /** 84 | * Set stdOut Print stream for messages. 85 | * \param[in] stream The new Print stream. 86 | */ 87 | static void setStdOut(Print* stream) {m_stdOut = stream;} 88 | /** \return Print stream for messages. */ 89 | static Print* stdOut() {return m_stdOut;} 90 | 91 | private: 92 | Sd2Card m_card; 93 | SdVolume m_vol; 94 | SdBaseFile m_vwd; 95 | static Print* m_stdOut; 96 | }; 97 | #endif // SdFat_h 98 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdFatConfig.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * \file 22 | * \brief configuration definitions 23 | */ 24 | #ifndef SdFatConfig_h 25 | #define SdFatConfig_h 26 | #include 27 | //------------------------------------------------------------------------------ 28 | /** 29 | * Set USE_SEPARATE_FAT_CACHE nonzero to use a second 512 byte cache 30 | * for FAT table entries. Improves performance for large writes that 31 | * are not a multiple of 512 bytes. 32 | */ 33 | #ifdef __arm__ 34 | #define USE_SEPARATE_FAT_CACHE 1 35 | #else // __arm__ 36 | #define USE_SEPARATE_FAT_CACHE 0 37 | #endif // __arm__ 38 | //------------------------------------------------------------------------------ 39 | /** 40 | * Set USE_MULTI_BLOCK_SD_IO nonzero to use multi-block SD read/write. 41 | * 42 | * Don't use mult-block read/write on small AVR boards. 43 | */ 44 | #if defined(RAMEND) && RAMEND < 3000 45 | #define USE_MULTI_BLOCK_SD_IO 0 46 | #else 47 | #define USE_MULTI_BLOCK_SD_IO 1 48 | #endif 49 | //------------------------------------------------------------------------------ 50 | /** 51 | * Force use of Arduino Standard SPI library if USE_ARDUINO_SPI_LIBRARY 52 | * is nonzero. 53 | */ 54 | #define USE_ARDUINO_SPI_LIBRARY 0 55 | //------------------------------------------------------------------------------ 56 | /** 57 | * To enable SD card CRC checking set USE_SD_CRC nonzero. 58 | * 59 | * Set USE_SD_CRC to 1 to use a smaller slower CRC-CCITT function. 60 | * 61 | * Set USE_SD_CRC to 2 to used a larger faster table driven CRC-CCITT function. 62 | */ 63 | #define USE_SD_CRC 0 64 | //------------------------------------------------------------------------------ 65 | /** 66 | * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero. 67 | * 68 | * Using multiple cards costs about 200 bytes of flash. 69 | * 70 | * Each card requires about 550 bytes of SRAM so use of a Mega is recommended. 71 | */ 72 | #define USE_MULTIPLE_CARDS 0 73 | //------------------------------------------------------------------------------ 74 | /** 75 | * Set DESTRUCTOR_CLOSES_FILE nonzero to close a file in its destructor. 76 | * 77 | * Causes use of lots of heap in ARM. 78 | */ 79 | #define DESTRUCTOR_CLOSES_FILE 0 80 | //------------------------------------------------------------------------------ 81 | /** 82 | * For AVR 83 | * 84 | * Set USE_SERIAL_FOR_STD_OUT nonzero to use Serial (the HardwareSerial class) 85 | * for error messages and output from print functions like ls(). 86 | * 87 | * If USE_SERIAL_FOR_STD_OUT is zero, a small non-interrupt driven class 88 | * is used to output messages to serial port zero. This allows an alternate 89 | * Serial library like SerialPort to be used with SdFat. 90 | * 91 | * You can redirect stdOut with SdFat::setStdOut(Print* stream) and 92 | * get the current stream with SdFat::stdOut(). 93 | */ 94 | #define USE_SERIAL_FOR_STD_OUT 0 95 | //------------------------------------------------------------------------------ 96 | /** 97 | * Call flush for endl if ENDL_CALLS_FLUSH is nonzero 98 | * 99 | * The standard for iostreams is to call flush. This is very costly for 100 | * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. 101 | * 102 | * SdFat has a single 512 byte buffer for SD I/O so it must write the current 103 | * data block to the SD, read the directory block from the SD, update the 104 | * directory entry, write the directory block to the SD and read the data 105 | * block back into the buffer. 106 | * 107 | * The SD flash memory controller is not designed for this many rewrites 108 | * so performance may be reduced by more than a factor of 100. 109 | * 110 | * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force 111 | * all data to be written to the SD. 112 | */ 113 | #define ENDL_CALLS_FLUSH 0 114 | //------------------------------------------------------------------------------ 115 | /** 116 | * Allow FAT12 volumes if FAT12_SUPPORT is nonzero. 117 | * FAT12 has not been well tested. 118 | */ 119 | #define FAT12_SUPPORT 0 120 | //------------------------------------------------------------------------------ 121 | /** 122 | * SPI SCK divisor for SD initialization commands. 123 | * or greater 124 | */ 125 | #ifdef __AVR__ 126 | const uint8_t SPI_SCK_INIT_DIVISOR = 64; 127 | #else 128 | const uint8_t SPI_SCK_INIT_DIVISOR = 128; 129 | #endif 130 | //------------------------------------------------------------------------------ 131 | /** 132 | * Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos. 133 | * Default pins used are SS 10, MOSI 11, MISO 12, and SCK 13. 134 | * Edit Software Spi pins to change pin numbers. 135 | * 136 | * MEGA_SOFT_SPI allows an unmodified 328 Shield to be used 137 | * on Mega Arduinos. 138 | */ 139 | #define MEGA_SOFT_SPI 0 140 | //------------------------------------------------------------------------------ 141 | /** 142 | * Define LEONARDO_SOFT_SPI nonzero to use software SPI on Leonardo Arduinos. 143 | * Default pins used are SS 10, MOSI 11, MISO 12, and SCK 13. 144 | * Edit Software Spi pins to change pin numbers. 145 | * 146 | * LEONARDO_SOFT_SPI allows an unmodified 328 Shield to be used 147 | * on Leonardo Arduinos. 148 | */ 149 | #define LEONARDO_SOFT_SPI 0 150 | //------------------------------------------------------------------------------ 151 | /** 152 | * Set USE_SOFTWARE_SPI nonzero to always use software SPI on AVR. 153 | */ 154 | #define USE_SOFTWARE_SPI 0 155 | // define software SPI pins so Mega can use unmodified 168/328 shields 156 | /** Default Software SPI chip select pin */ 157 | uint8_t const SOFT_SPI_CS_PIN = 10; 158 | /** Software SPI Master Out Slave In pin */ 159 | uint8_t const SOFT_SPI_MOSI_PIN = 11; 160 | /** Software SPI Master In Slave Out pin */ 161 | uint8_t const SOFT_SPI_MISO_PIN = 12; 162 | /** Software SPI Clock pin */ 163 | uint8_t const SOFT_SPI_SCK_PIN = 13; 164 | #endif // SdFatConfig_h 165 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdFatErrorPrint.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #ifndef PSTR 22 | #define PSTR(x) x 23 | #define PGM_P const char* 24 | #endif 25 | //------------------------------------------------------------------------------ 26 | static void pstrPrint(PGM_P str) { 27 | for (uint8_t c; (c = pgm_read_byte(str)); str++) SdFat::stdOut()->write(c); 28 | } 29 | //------------------------------------------------------------------------------ 30 | static void pstrPrintln(PGM_P str) { 31 | pstrPrint(str); 32 | SdFat::stdOut()->println(); 33 | } 34 | //------------------------------------------------------------------------------ 35 | /** %Print any SD error code and halt. */ 36 | void SdFat::errorHalt() { 37 | errorPrint(); 38 | while (1); 39 | } 40 | //------------------------------------------------------------------------------ 41 | /** %Print msg, any SD error code, and halt. 42 | * 43 | * \param[in] msg Message to print. 44 | */ 45 | void SdFat::errorHalt(char const* msg) { 46 | errorPrint(msg); 47 | while (1); 48 | } 49 | //------------------------------------------------------------------------------ 50 | /** %Print msg, any SD error code, and halt. 51 | * 52 | * \param[in] msg Message in program space (flash memory) to print. 53 | */ 54 | void SdFat::errorHalt_P(PGM_P msg) { 55 | errorPrint_P(msg); 56 | while (1); 57 | } 58 | //------------------------------------------------------------------------------ 59 | /** %Print any SD error code. */ 60 | void SdFat::errorPrint() { 61 | if (!m_card.errorCode()) return; 62 | pstrPrint(PSTR("SD errorCode: 0X")); 63 | m_stdOut->print(m_card.errorCode(), HEX); 64 | pstrPrint(PSTR(",0X")); 65 | m_stdOut->println(m_card.errorData(), HEX); 66 | } 67 | //------------------------------------------------------------------------------ 68 | /** %Print msg, any SD error code. 69 | * 70 | * \param[in] msg Message to print. 71 | */ 72 | void SdFat::errorPrint(char const* msg) { 73 | pstrPrint(PSTR("error: ")); 74 | m_stdOut->println(msg); 75 | errorPrint(); 76 | } 77 | //------------------------------------------------------------------------------ 78 | /** %Print msg, any SD error code. 79 | * 80 | * \param[in] msg Message in program space (flash memory) to print. 81 | */ 82 | void SdFat::errorPrint_P(PGM_P msg) { 83 | pstrPrint(PSTR("error: ")); 84 | pstrPrintln(msg); 85 | errorPrint(); 86 | } 87 | //------------------------------------------------------------------------------ 88 | /** %Print error details and halt after SdFat::init() fails. */ 89 | void SdFat::initErrorHalt() { 90 | initErrorPrint(); 91 | while (1); 92 | } 93 | //------------------------------------------------------------------------------ 94 | /**Print message, error details, and halt after SdFat::init() fails. 95 | * 96 | * \param[in] msg Message to print. 97 | */ 98 | void SdFat::initErrorHalt(char const *msg) { 99 | m_stdOut->println(msg); 100 | initErrorHalt(); 101 | } 102 | //------------------------------------------------------------------------------ 103 | /**Print message, error details, and halt after SdFat::init() fails. 104 | * 105 | * \param[in] msg Message in program space (flash memory) to print. 106 | */ 107 | void SdFat::initErrorHalt_P(PGM_P msg) { 108 | pstrPrintln(msg); 109 | initErrorHalt(); 110 | } 111 | //------------------------------------------------------------------------------ 112 | /** Print error details after SdFat::init() fails. */ 113 | void SdFat::initErrorPrint() { 114 | if (m_card.errorCode()) { 115 | pstrPrintln(PSTR("Can't access SD card. Do not reformat.")); 116 | if (m_card.errorCode() == SD_CARD_ERROR_CMD0) { 117 | pstrPrintln(PSTR("No card, wrong chip select pin, or SPI problem?")); 118 | } 119 | errorPrint(); 120 | } else if (m_vol.fatType() == 0) { 121 | pstrPrintln(PSTR("Invalid format, reformat SD.")); 122 | } else if (!m_vwd.isOpen()) { 123 | pstrPrintln(PSTR("Can't open root directory.")); 124 | } else { 125 | pstrPrintln(PSTR("No error found.")); 126 | } 127 | } 128 | //------------------------------------------------------------------------------ 129 | /**Print message and error details and halt after SdFat::init() fails. 130 | * 131 | * \param[in] msg Message to print. 132 | */ 133 | void SdFat::initErrorPrint(char const *msg) { 134 | m_stdOut->println(msg); 135 | initErrorPrint(); 136 | } 137 | //------------------------------------------------------------------------------ 138 | /**Print message and error details after SdFat::init() fails. 139 | * 140 | * \param[in] msg Message in program space (flash memory) to print. 141 | */ 142 | void SdFat::initErrorPrint_P(PGM_P msg) { 143 | pstrPrintln(msg); 144 | initErrorHalt(); 145 | } 146 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdFatUtil.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #include 22 | #include 23 | #ifdef __arm__ 24 | // should use uinstd.h to define sbrk but Due causes a conflict 25 | extern "C" char* sbrk(int incr); 26 | #else // __ARM__ 27 | extern char *__brkval; 28 | extern char __bss_end; 29 | #endif // __arm__ 30 | //------------------------------------------------------------------------------ 31 | /** Amount of free RAM 32 | * \return The number of free bytes. 33 | */ 34 | int SdFatUtil::FreeRam() { 35 | char top; 36 | #ifdef __arm__ 37 | return &top - reinterpret_cast(sbrk(0)); 38 | #else // __arm__ 39 | return __brkval ? &top - __brkval : &top - &__bss_end; 40 | #endif // __arm__ 41 | } 42 | //------------------------------------------------------------------------------ 43 | /** %Print a string in flash memory. 44 | * 45 | * \param[in] pr Print object for output. 46 | * \param[in] str Pointer to string stored in flash memory. 47 | */ 48 | void SdFatUtil::print_P(Print* pr, PGM_P str) { 49 | for (uint8_t c; (c = pgm_read_byte(str)); str++) pr->write(c); 50 | } 51 | //------------------------------------------------------------------------------ 52 | /** %Print a string in flash memory followed by a CR/LF. 53 | * 54 | * \param[in] pr Print object for output. 55 | * \param[in] str Pointer to string stored in flash memory. 56 | */ 57 | void SdFatUtil::println_P(Print* pr, PGM_P str) { 58 | print_P(pr, str); 59 | pr->println(); 60 | } 61 | //------------------------------------------------------------------------------ 62 | /** %Print a string in flash memory to Serial. 63 | * 64 | * \param[in] str Pointer to string stored in flash memory. 65 | */ 66 | void SdFatUtil::SerialPrint_P(PGM_P str) { 67 | print_P(SdFat::stdOut(), str); 68 | } 69 | //------------------------------------------------------------------------------ 70 | /** %Print a string in flash memory to Serial followed by a CR/LF. 71 | * 72 | * \param[in] str Pointer to string stored in flash memory. 73 | */ 74 | void SdFatUtil::SerialPrintln_P(PGM_P str) { 75 | println_P(SdFat::stdOut(), str); 76 | } 77 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdFatUtil.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef SdFatUtil_h 21 | #define SdFatUtil_h 22 | /** 23 | * \file 24 | * \brief Useful utility functions. 25 | */ 26 | #include 27 | /** Store and print a string in flash memory.*/ 28 | #define PgmPrint(x) SerialPrint_P(PSTR(x)) 29 | /** Store and print a string in flash memory followed by a CR/LF.*/ 30 | #define PgmPrintln(x) SerialPrintln_P(PSTR(x)) 31 | 32 | namespace SdFatUtil { 33 | int FreeRam(); 34 | void print_P(Print* pr, PGM_P str); 35 | void println_P(Print* pr, PGM_P str); 36 | void SerialPrint_P(PGM_P str); 37 | void SerialPrintln_P(PGM_P str); 38 | } 39 | using namespace SdFatUtil; // NOLINT 40 | #endif // #define SdFatUtil_h 41 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdFile.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include 21 | /** Create a file object and open it in the current working directory. 22 | * 23 | * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. 24 | * 25 | * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive 26 | * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). 27 | */ 28 | SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { 29 | } 30 | //------------------------------------------------------------------------------ 31 | /** Write data to an open file. 32 | * 33 | * \note Data is moved to the cache but may not be written to the 34 | * storage device until sync() is called. 35 | * 36 | * \param[in] buf Pointer to the location of the data to be written. 37 | * 38 | * \param[in] nbyte Number of bytes to write. 39 | * 40 | * \return For success write() returns the number of bytes written, always 41 | * \a nbyte. If an error occurs, write() returns -1. Possible errors 42 | * include write() is called before a file has been opened, write is called 43 | * for a read-only file, device is full, a corrupt file system or an I/O error. 44 | * 45 | */ 46 | int SdFile::write(const void* buf, size_t nbyte) { 47 | return SdBaseFile::write(buf, nbyte); 48 | } 49 | //------------------------------------------------------------------------------ 50 | /** Write a byte to a file. Required by the Arduino Print class. 51 | * \param[in] b the byte to be written. 52 | * Use getWriteError to check for errors. 53 | * \return 1 for success and 0 for failure. 54 | */ 55 | size_t SdFile::write(uint8_t b) { 56 | return SdBaseFile::write(&b, 1) == 1 ? 1 : 0; 57 | } 58 | //------------------------------------------------------------------------------ 59 | /** Write a string to a file. Used by the Arduino Print class. 60 | * \param[in] str Pointer to the string. 61 | * Use getWriteError to check for errors. 62 | * \return count of characters written for success or -1 for failure. 63 | */ 64 | int SdFile::write(const char* str) { 65 | return SdBaseFile::write(str, strlen(str)); 66 | } 67 | //------------------------------------------------------------------------------ 68 | /** Write a PROGMEM string to a file. 69 | * \param[in] str Pointer to the PROGMEM string. 70 | * Use getWriteError to check for errors. 71 | */ 72 | void SdFile::write_P(PGM_P str) { 73 | for (uint8_t c; (c = pgm_read_byte(str)); str++) write(c); 74 | } 75 | //------------------------------------------------------------------------------ 76 | /** Write a PROGMEM string followed by CR/LF to a file. 77 | * \param[in] str Pointer to the PROGMEM string. 78 | * Use getWriteError to check for errors. 79 | */ 80 | void SdFile::writeln_P(PGM_P str) { 81 | write_P(str); 82 | write_P(PSTR("\r\n")); 83 | } 84 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdFile.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * \file 22 | * \brief SdFile class 23 | */ 24 | #include 25 | #ifndef SdFile_h 26 | #define SdFile_h 27 | //------------------------------------------------------------------------------ 28 | /** 29 | * \class SdFile 30 | * \brief SdBaseFile with Print. 31 | */ 32 | class SdFile : public SdBaseFile, public Print { 33 | public: 34 | SdFile() {} 35 | SdFile(const char* name, uint8_t oflag); 36 | #if DESTRUCTOR_CLOSES_FILE 37 | ~SdFile() {} 38 | #endif // DESTRUCTOR_CLOSES_FILE 39 | /** \return value of writeError */ 40 | bool getWriteError() {return SdBaseFile::getWriteError();} 41 | /** Set writeError to zero */ 42 | void clearWriteError() {SdBaseFile::clearWriteError();} 43 | size_t write(uint8_t b); 44 | int write(const char* str); 45 | int write(const void* buf, size_t nbyte); 46 | void write_P(PGM_P str); 47 | void writeln_P(PGM_P str); 48 | }; 49 | #endif // SdFile_h 50 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdSpi.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdSpi Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the Arduino SdSpi Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdSpi Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * \file 22 | * \brief SdSpi class for V2 SD/SDHC cards 23 | */ 24 | #ifndef SdSpi_h 25 | #define SdSpi_h 26 | #include 27 | #include 28 | 29 | #if !USE_ARDUINO_SPI_LIBRARY 30 | // AVR Arduinos 31 | #ifdef __AVR__ 32 | #if USE_SOFTWARE_SPI 33 | #define USE_AVR_SOFTWARE_SPI 1 34 | #elif LEONARDO_SOFT_SPI && defined(__AVR_ATmega32U4__) && !defined(CORE_TEENSY) 35 | #define USE_AVR_SOFTWARE_SPI 1 36 | #elif MEGA_SOFT_SPI&&(defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__)) 37 | #define USE_AVR_SOFTWARE_SPI 1 38 | #else // USE_SOFTWARE_SPI 39 | #define USE_AVR_S0FTWARE_SPI 0 40 | #define USE_NATIVE_AVR_SPI 1 41 | #endif // USE_SOFTWARE_SPI 42 | #endif // __AVR__ 43 | // Due 44 | #if defined(__arm__) && !defined(CORE_TEENSY) 45 | /** Nonzero - use native SAM3X SPI */ 46 | #define USE_NATIVE_SAM3X_SPI 1 47 | #else // USE_NATIVE_SAM3X_SPI 48 | /** Zero - don't use native SAM3X SPI */ 49 | #define USE_NATIVE_SAM3X_SPI 0 50 | #endif // USE_NATIVE_SAM3X_SPI 51 | // Teensy 3.0 52 | #if defined(__arm__) && defined(CORE_TEENSY) 53 | /** Nonzero - use native MK20DX128 SPI */ 54 | #define USE_NATIVE_MK20DX128_SPI 1 55 | #else // USE_NATIVE_MK20DX128_SPI 56 | /** Zero - don't use native MK20DX128 SPI */ 57 | #define USE_NATIVE_MK20DX128_SPI 0 58 | #endif // USE_NATIVE_MK20DX128_SPI 59 | #endif // USE_ARDUINO_SPI_LIBRARY 60 | //------------------------------------------------------------------------------ 61 | // define default chip select pin 62 | // 63 | #if !USE_AVR_SOFTWARE_SPI 64 | /** The default chip select pin for the SD card is SS. */ 65 | uint8_t const SD_CHIP_SELECT_PIN = SS; 66 | #else // USE_AVR_SOFTWARE_SPI 67 | /** SPI chip select pin for software SPI. */ 68 | uint8_t const SD_CHIP_SELECT_PIN = SOFT_SPI_CS_PIN; 69 | #endif // USE_AVR_SOFTWARE_SPI 70 | 71 | //------------------------------------------------------------------------------ 72 | /** 73 | * \class SdSpi 74 | * \brief SPI class for access to SD and SDHC flash memory cards. 75 | */ 76 | class SdSpi { 77 | public: 78 | /** Initialize the SPI bus */ 79 | void begin(); 80 | /** Set SPI options for access to SD/SDHC cards. 81 | * 82 | * \param[in] spiDivisor SCK clock divider relative to the system clock. 83 | */ 84 | void init(uint8_t spiDivisor); 85 | /** Receive a byte. 86 | * 87 | * \return The byte. 88 | */ 89 | uint8_t receive(); 90 | /** Receive multiple bytes. 91 | * 92 | * \param[out] buf Buffer to receive the data. 93 | * \param[in] n Number of bytes to receive. 94 | * 95 | * \return Zero for no error or nonzero error code. 96 | */ 97 | uint8_t receive(uint8_t* buf, size_t n); 98 | /** Send a byte. 99 | * 100 | * \param[in] data Byte to send 101 | */ 102 | void send(uint8_t data); 103 | /** Send multiple bytes. 104 | * 105 | * \param[in] buf Buffer for data to be sent. 106 | * \param[in] n Number of bytes to send. 107 | */ 108 | void send(const uint8_t* buf, size_t n); 109 | }; 110 | //------------------------------------------------------------------------------ 111 | // Use of inline for AVR results in up to 10% better write performance. 112 | // Inline also save a little flash memory. 113 | /** inline avr native functions if nonzero. */ 114 | #define USE_AVR_NATIVE_SPI_INLINE 1 115 | #if USE_NATIVE_AVR_SPI && USE_AVR_NATIVE_SPI_INLINE 116 | inline uint8_t SdSpi::receive() { 117 | SPDR = 0XFF; 118 | while (!(SPSR & (1 << SPIF))); 119 | return SPDR; 120 | } 121 | inline uint8_t SdSpi::receive(uint8_t* buf, size_t n) { 122 | if (n-- == 0) return 0; 123 | SPDR = 0XFF; 124 | for (size_t i = 0; i < n; i++) { 125 | while (!(SPSR & (1 << SPIF))); 126 | uint8_t b = SPDR; 127 | SPDR = 0XFF; 128 | buf[i] = b; 129 | } 130 | while (!(SPSR & (1 << SPIF))); 131 | buf[n] = SPDR; 132 | return 0; 133 | } 134 | inline void SdSpi::send(uint8_t data) { 135 | SPDR = data; 136 | while (!(SPSR & (1 << SPIF))); 137 | } 138 | inline void SdSpi::send(const uint8_t* buf , size_t n) { 139 | if (n == 0) return; 140 | SPDR = buf[0]; 141 | if (n > 1) { 142 | uint8_t b = buf[1]; 143 | size_t i = 2; 144 | while (1) { 145 | while (!(SPSR & (1 << SPIF))); 146 | SPDR = b; 147 | if (i == n) break; 148 | b = buf[i++]; 149 | } 150 | } 151 | while (!(SPSR & (1 << SPIF))); 152 | } 153 | #endif // USE_NATIVE_AVR_SPI && USE_AVR_NATIVE_SPI_INLINE 154 | #endif // SdSpi_h 155 | 156 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdSpiAVR.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdSpi Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the Arduino SdSpi Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdSpi Library. If not, see 18 | * . 19 | */#include 20 | #if USE_NATIVE_AVR_SPI 21 | //------------------------------------------------------------------------------ 22 | void SdSpi::begin() { 23 | // set SS high - may be chip select for another SPI device 24 | digitalWrite(SS, HIGH); 25 | 26 | // SS must be in output mode even it is not chip select 27 | pinMode(SS, OUTPUT); 28 | pinMode(MISO, INPUT); 29 | pinMode(MOSI, OUTPUT); 30 | pinMode(SCK, OUTPUT); 31 | } 32 | //------------------------------------------------------------------------------ 33 | void SdSpi::init(uint8_t sckDivisor) { 34 | uint8_t r = 0; 35 | 36 | for (uint8_t b = 2; sckDivisor > b && r < 6; b <<= 1, r++); 37 | // See avr processor documentation 38 | SPCR = (1 << SPE) | (1 << MSTR) | (r >> 1); 39 | SPSR = r & 1 || r == 6 ? 0 : 1 << SPI2X; 40 | } 41 | #if !USE_AVR_NATIVE_SPI_INLINE 42 | //------------------------------------------------------------------------------ 43 | uint8_t SdSpi::receive() { 44 | SPDR = 0XFF; 45 | while (!(SPSR & (1 << SPIF))); 46 | return SPDR; 47 | } 48 | //------------------------------------------------------------------------------ 49 | uint8_t SdSpi::receive(uint8_t* buf, size_t n) { 50 | if (n-- == 0) return 0; 51 | SPDR = 0XFF; 52 | for (size_t i = 0; i < n; i++) { 53 | while (!(SPSR & (1 << SPIF))); 54 | uint8_t b = SPDR; 55 | SPDR = 0XFF; 56 | buf[i] = b; 57 | } 58 | while (!(SPSR & (1 << SPIF))); 59 | buf[n] = SPDR; 60 | return 0; 61 | } 62 | //------------------------------------------------------------------------------ 63 | void SdSpi::send(uint8_t data) { 64 | SPDR = data; 65 | while (!(SPSR & (1 << SPIF))); 66 | } 67 | //------------------------------------------------------------------------------ 68 | void SdSpi::send(const uint8_t* buf , size_t n) { 69 | if (n == 0) return; 70 | SPDR = buf[0]; 71 | if (n > 1) { 72 | uint8_t b = buf[1]; 73 | size_t i = 2; 74 | while (1) { 75 | while (!(SPSR & (1 << SPIF))); 76 | SPDR = b; 77 | if (i == n) break; 78 | b = buf[i++]; 79 | } 80 | } 81 | while (!(SPSR & (1 << SPIF))); 82 | } 83 | #endif // !USE_AVR_NATIVE_SPI_INLINE 84 | #endif // USE_NATIVE_AVR_SPI 85 | //============================================================================== 86 | #if USE_AVR_SOFTWARE_SPI 87 | #include 88 | static 89 | SoftSPI softSpiBus; 90 | //------------------------------------------------------------------------------ 91 | /** 92 | * initialize SPI pins 93 | */ 94 | void SdSpi::begin() { 95 | softSpiBus.begin(); 96 | } 97 | //------------------------------------------------------------------------------ 98 | /** 99 | * Initialize hardware SPI - dummy for soft SPI 100 | */ 101 | void SdSpi::init(uint8_t sckDivisor) {} 102 | //------------------------------------------------------------------------------ 103 | /** Soft SPI receive byte */ 104 | uint8_t SdSpi::receive() { 105 | return softSpiBus.receive(); 106 | } 107 | //------------------------------------------------------------------------------ 108 | /** Soft SPI read data */ 109 | uint8_t SdSpi::receive(uint8_t* buf, size_t n) { 110 | for (size_t i = 0; i < n; i++) { 111 | buf[i] = receive(); 112 | } 113 | return 0; 114 | } 115 | //------------------------------------------------------------------------------ 116 | /** Soft SPI send byte */ 117 | void SdSpi::send(uint8_t data) { 118 | softSpiBus.send(data); 119 | } 120 | //------------------------------------------------------------------------------ 121 | void SdSpi::send(const uint8_t* buf , size_t n) { 122 | for (size_t i = 0; i < n; i++) { 123 | send(buf[i]); 124 | } 125 | } 126 | #endif // USE_AVR_SOFTWARE_SPI 127 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdSpiArduino.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdSpi Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the Arduino SdSpi Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdSpi Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #if USE_ARDUINO_SPI_LIBRARY 22 | #include 23 | //------------------------------------------------------------------------------ 24 | void SdSpi::begin() { 25 | SPI.begin(); 26 | } 27 | //------------------------------------------------------------------------------ 28 | void SdSpi::init(uint8_t sckDivisor) { 29 | SPI.setBitOrder(MSBFIRST); 30 | SPI.setDataMode(SPI_MODE0); 31 | #ifndef SPI_CLOCK_DIV128 32 | SPI.setClockDivider(sckDivisor); 33 | #else // SPI_CLOCK_DIV128 34 | int v; 35 | if (sckDivisor <= 2) v = SPI_CLOCK_DIV2; 36 | else if (sckDivisor <= 4) v = SPI_CLOCK_DIV4; 37 | else if (sckDivisor <= 8) v = SPI_CLOCK_DIV8; 38 | else if (sckDivisor <= 16) v = SPI_CLOCK_DIV16; 39 | else if (sckDivisor <= 32) v = SPI_CLOCK_DIV32; 40 | else if (sckDivisor <= 64) v = SPI_CLOCK_DIV64; 41 | else v = SPI_CLOCK_DIV128; 42 | SPI.setClockDivider(v); 43 | #endif // SPI_CLOCK_DIV128 44 | } 45 | //------------------------------------------------------------------------------ 46 | /** SPI receive a byte */ 47 | uint8_t SdSpi::receive() { 48 | return SPI.transfer(0XFF); 49 | } 50 | //------------------------------------------------------------------------------ 51 | /** SPI receive multiple bytes */ 52 | uint8_t SdSpi::receive(uint8_t* buf, size_t n) { 53 | for (size_t i = 0; i < n; i++) { 54 | buf[i] = SPI.transfer(0XFF); 55 | } 56 | return 0; 57 | } 58 | //------------------------------------------------------------------------------ 59 | /** SPI send a byte */ 60 | void SdSpi::send(uint8_t b) { 61 | SPI.transfer(b); 62 | } 63 | //------------------------------------------------------------------------------ 64 | /** SPI send multiple bytes */ 65 | void SdSpi::send(const uint8_t* buf , size_t n) { 66 | for (size_t i = 0; i < n; i++) { 67 | SPI.transfer(buf[i]); 68 | } 69 | } 70 | #endif // USE_ARDUINO_SPI_LIBRARY 71 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdSpiMK20DX128.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdSpi Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the Arduino SdSpi Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdSpi Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #if USE_NATIVE_MK20DX128_SPI 22 | // Teensy 3.0 functions 23 | #include 24 | // use 16-bit frame if SPI_USE_8BIT_FRAME is zero 25 | #define SPI_USE_8BIT_FRAME 0 26 | // Limit initial fifo to three entries to avoid fifo overrun 27 | #define SPI_INITIAL_FIFO_DEPTH 3 28 | // define some symbols that are not in mk20dx128.h 29 | #ifndef SPI_SR_RXCTR 30 | #define SPI_SR_RXCTR 0XF0 31 | #endif // SPI_SR_RXCTR 32 | #ifndef SPI_PUSHR_CONT 33 | #define SPI_PUSHR_CONT 0X80000000 34 | #endif // SPI_PUSHR_CONT 35 | #ifndef SPI_PUSHR_CTAS 36 | #define SPI_PUSHR_CTAS(n) (((n) & 7) << 28) 37 | #endif // SPI_PUSHR_CTAS 38 | //------------------------------------------------------------------------------ 39 | /** 40 | * initialize SPI pins 41 | */ 42 | void SdSpi::begin() { 43 | SIM_SCGC6 |= SIM_SCGC6_SPI0; 44 | } 45 | //------------------------------------------------------------------------------ 46 | /** 47 | * Initialize hardware SPI 48 | * 49 | */ 50 | void SdSpi::init(uint8_t sckDivisor) { 51 | uint32_t ctar, ctar0, ctar1; 52 | 53 | if (sckDivisor <= 2) { 54 | // 1/2 speed 55 | ctar = SPI_CTAR_DBR | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); 56 | } else if (sckDivisor <= 4) { 57 | // 1/4 speed 58 | ctar = SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); 59 | } else if (sckDivisor <= 8) { 60 | // 1/8 speed 61 | ctar = SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1); 62 | } else if (sckDivisor <= 12) { 63 | // 1/12 speed 64 | ctar = SPI_CTAR_BR(2) | SPI_CTAR_CSSCK(2); 65 | } else if (sckDivisor <= 16) { 66 | // 1/16 speed 67 | ctar = SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(3); 68 | } else if (sckDivisor <= 32) { 69 | // 1/32 speed 70 | ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4); 71 | } else if (sckDivisor <= 64) { 72 | // 1/64 speed 73 | ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(5); 74 | } else { 75 | // 1/128 speed 76 | ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6); 77 | } 78 | // CTAR0 - 8 bit transfer 79 | ctar0 = ctar | SPI_CTAR_FMSZ(7); 80 | 81 | // CTAR1 - 16 bit transfer 82 | ctar1 = ctar | SPI_CTAR_FMSZ(15); 83 | 84 | if (SPI0_CTAR0 != ctar0 || SPI0_CTAR1 != ctar1) { 85 | SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); 86 | SPI0_CTAR0 = ctar0; 87 | SPI0_CTAR1 = ctar1; 88 | } 89 | SPI0_MCR = SPI_MCR_MSTR; 90 | CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); 91 | CORE_PIN12_CONFIG = PORT_PCR_MUX(2); 92 | CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); 93 | } 94 | //------------------------------------------------------------------------------ 95 | /** SPI receive a byte */ 96 | uint8_t SdSpi::receive() { 97 | SPI0_MCR |= SPI_MCR_CLR_RXF; 98 | SPI0_SR = SPI_SR_TCF; 99 | SPI0_PUSHR = 0xFF; 100 | while (!(SPI0_SR & SPI_SR_TCF)) {} 101 | return SPI0_POPR; 102 | } 103 | //------------------------------------------------------------------------------ 104 | /** SPI receive multiple bytes */ 105 | uint8_t SdSpi::receive(uint8_t* buf, size_t n) { 106 | // clear any data in RX FIFO 107 | SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF; 108 | #if SPI_USE_8BIT_FRAME 109 | // initial number of bytes to push into TX FIFO 110 | int nf = n < SPI_INITIAL_FIFO_DEPTH ? n : SPI_INITIAL_FIFO_DEPTH; 111 | for (int i = 0; i < nf; i++) { 112 | SPI0_PUSHR = 0XFF; 113 | } 114 | // limit for pushing dummy data into TX FIFO 115 | uint8_t* limit = buf + n - nf; 116 | while (buf < limit) { 117 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 118 | SPI0_PUSHR = 0XFF; 119 | *buf++ = SPI0_POPR; 120 | } 121 | // limit for rest of RX data 122 | limit += nf; 123 | while (buf < limit) { 124 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 125 | *buf++ = SPI0_POPR; 126 | } 127 | #else // SPI_USE_8BIT_FRAME 128 | // use 16 bit frame to avoid TD delay between frames 129 | // get one byte if n is odd 130 | if (n & 1) { 131 | *buf++ = receive(); 132 | n--; 133 | } 134 | // initial number of words to push into TX FIFO 135 | int nf = n/2 < SPI_INITIAL_FIFO_DEPTH ? n/2 : SPI_INITIAL_FIFO_DEPTH; 136 | for (int i = 0; i < nf; i++) { 137 | SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF; 138 | } 139 | uint8_t* limit = buf + n - 2*nf; 140 | while (buf < limit) { 141 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 142 | SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF; 143 | uint16_t w = SPI0_POPR; 144 | *buf++ = w >> 8; 145 | *buf++ = w & 0XFF; 146 | } 147 | // limit for rest of RX data 148 | limit += 2*nf; 149 | while (buf < limit) { 150 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 151 | uint16_t w = SPI0_POPR; 152 | *buf++ = w >> 8; 153 | *buf++ = w & 0XFF; 154 | } 155 | #endif // SPI_USE_8BIT_FRAME 156 | return 0; 157 | } 158 | //------------------------------------------------------------------------------ 159 | /** SPI send a byte */ 160 | void SdSpi::send(uint8_t b) { 161 | SPI0_MCR |= SPI_MCR_CLR_RXF; 162 | SPI0_SR = SPI_SR_TCF; 163 | SPI0_PUSHR = b; 164 | while (!(SPI0_SR & SPI_SR_TCF)) {} 165 | } 166 | //------------------------------------------------------------------------------ 167 | /** SPI send multiple bytes */ 168 | void SdSpi::send(const uint8_t* buf , size_t n) { 169 | // clear any data in RX FIFO 170 | SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF; 171 | #if SPI_USE_8BIT_FRAME 172 | // initial number of bytes to push into TX FIFO 173 | int nf = n < SPI_INITIAL_FIFO_DEPTH ? n : SPI_INITIAL_FIFO_DEPTH; 174 | // limit for pushing data into TX fifo 175 | const uint8_t* limit = buf + n; 176 | for (int i = 0; i < nf; i++) { 177 | SPI0_PUSHR = *buf++; 178 | } 179 | // write data to TX FIFO 180 | while (buf < limit) { 181 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 182 | SPI0_PUSHR = *buf++; 183 | SPI0_POPR; 184 | } 185 | // wait for data to be sent 186 | while (nf) { 187 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 188 | SPI0_POPR; 189 | nf--; 190 | } 191 | #else // SPI_USE_8BIT_FRAME 192 | // use 16 bit frame to avoid TD delay between frames 193 | // send one byte if n is odd 194 | if (n & 1) { 195 | send(*buf++); 196 | n--; 197 | } 198 | // initial number of words to push into TX FIFO 199 | int nf = n/2 < SPI_INITIAL_FIFO_DEPTH ? n/2 : SPI_INITIAL_FIFO_DEPTH; 200 | // limit for pushing data into TX fifo 201 | const uint8_t* limit = buf + n; 202 | for (int i = 0; i < nf; i++) { 203 | uint16_t w = (*buf++) << 8; 204 | w |= *buf++; 205 | SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w; 206 | } 207 | // write data to TX FIFO 208 | while (buf < limit) { 209 | uint16_t w = *buf++ << 8; 210 | w |= *buf++; 211 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 212 | SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w; 213 | SPI0_POPR; 214 | } 215 | // wait for data to be sent 216 | while (nf) { 217 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 218 | SPI0_POPR; 219 | nf--; 220 | } 221 | #endif // SPI_USE_8BIT_FRAME 222 | } 223 | #endif // USE_NATIVE_MK20DX128_SPI 224 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdSpiSAM3X.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdSpi Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the Arduino SdSpi Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdSpi Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #if USE_NATIVE_SAM3X_SPI 22 | /** Use SAM3X DMAC if nonzero */ 23 | #define USE_SAM3X_DMAC 1 24 | /** Use extra Bus Matrix arbitration fix if nonzero */ 25 | #define USE_SAM3X_BUS_MATRIX_FIX 0 26 | /** Time in ms for DMA receive timeout */ 27 | #define SAM3X_DMA_TIMEOUT 100 28 | /** chip select register number */ 29 | #define SPI_CHIP_SEL 3 30 | /** DMAC receive channel */ 31 | #define SPI_DMAC_RX_CH 1 32 | /** DMAC transmit channel */ 33 | #define SPI_DMAC_TX_CH 0 34 | /** DMAC Channel HW Interface Number for SPI TX. */ 35 | #define SPI_TX_IDX 1 36 | /** DMAC Channel HW Interface Number for SPI RX. */ 37 | #define SPI_RX_IDX 2 38 | //------------------------------------------------------------------------------ 39 | /** Disable DMA Controller. */ 40 | static void dmac_disable() { 41 | DMAC->DMAC_EN &= (~DMAC_EN_ENABLE); 42 | } 43 | /** Enable DMA Controller. */ 44 | static void dmac_enable() { 45 | DMAC->DMAC_EN = DMAC_EN_ENABLE; 46 | } 47 | /** Disable DMA Channel. */ 48 | static void dmac_channel_disable(uint32_t ul_num) { 49 | DMAC->DMAC_CHDR = DMAC_CHDR_DIS0 << ul_num; 50 | } 51 | /** Enable DMA Channel. */ 52 | static void dmac_channel_enable(uint32_t ul_num) { 53 | DMAC->DMAC_CHER = DMAC_CHER_ENA0 << ul_num; 54 | } 55 | /** Poll for transfer complete. */ 56 | static bool dmac_channel_transfer_done(uint32_t ul_num) { 57 | return (DMAC->DMAC_CHSR & (DMAC_CHSR_ENA0 << ul_num)) ? false : true; 58 | } 59 | //------------------------------------------------------------------------------ 60 | void SdSpi::begin() { 61 | PIO_Configure( 62 | g_APinDescription[PIN_SPI_MOSI].pPort, 63 | g_APinDescription[PIN_SPI_MOSI].ulPinType, 64 | g_APinDescription[PIN_SPI_MOSI].ulPin, 65 | g_APinDescription[PIN_SPI_MOSI].ulPinConfiguration); 66 | PIO_Configure( 67 | g_APinDescription[PIN_SPI_MISO].pPort, 68 | g_APinDescription[PIN_SPI_MISO].ulPinType, 69 | g_APinDescription[PIN_SPI_MISO].ulPin, 70 | g_APinDescription[PIN_SPI_MISO].ulPinConfiguration); 71 | PIO_Configure( 72 | g_APinDescription[PIN_SPI_SCK].pPort, 73 | g_APinDescription[PIN_SPI_SCK].ulPinType, 74 | g_APinDescription[PIN_SPI_SCK].ulPin, 75 | g_APinDescription[PIN_SPI_SCK].ulPinConfiguration); 76 | pmc_enable_periph_clk(ID_SPI0); 77 | #if USE_SAM3X_DMAC 78 | pmc_enable_periph_clk(ID_DMAC); 79 | dmac_disable(); 80 | DMAC->DMAC_GCFG = DMAC_GCFG_ARB_CFG_FIXED; 81 | dmac_enable(); 82 | #if USE_SAM3X_BUS_MATRIX_FIX 83 | MATRIX->MATRIX_WPMR = 0x4d415400; 84 | MATRIX->MATRIX_MCFG[1] = 1; 85 | MATRIX->MATRIX_MCFG[2] = 1; 86 | MATRIX->MATRIX_SCFG[0] = 0x01000010; 87 | MATRIX->MATRIX_SCFG[1] = 0x01000010; 88 | MATRIX->MATRIX_SCFG[7] = 0x01000010; 89 | #endif // USE_SAM3X_BUS_MATRIX_FIX 90 | #endif // USE_SAM3X_DMAC 91 | } 92 | //------------------------------------------------------------------------------ 93 | // start RX DMA 94 | static void spiDmaRX(uint8_t* dst, uint16_t count) { 95 | dmac_channel_disable(SPI_DMAC_RX_CH); 96 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_SADDR = (uint32_t)&SPI0->SPI_RDR; 97 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_DADDR = (uint32_t)dst; 98 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_DSCR = 0; 99 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CTRLA = count | 100 | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE; 101 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR | 102 | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_PER2MEM_DMA_FC | 103 | DMAC_CTRLB_SRC_INCR_FIXED | DMAC_CTRLB_DST_INCR_INCREMENTING; 104 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CFG = DMAC_CFG_SRC_PER(SPI_RX_IDX) | 105 | DMAC_CFG_SRC_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG; 106 | dmac_channel_enable(SPI_DMAC_RX_CH); 107 | } 108 | //------------------------------------------------------------------------------ 109 | // start TX DMA 110 | static void spiDmaTX(const uint8_t* src, uint16_t count) { 111 | static uint8_t ff = 0XFF; 112 | uint32_t src_incr = DMAC_CTRLB_SRC_INCR_INCREMENTING; 113 | if (!src) { 114 | src = &ff; 115 | src_incr = DMAC_CTRLB_SRC_INCR_FIXED; 116 | } 117 | dmac_channel_disable(SPI_DMAC_TX_CH); 118 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_SADDR = (uint32_t)src; 119 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_DADDR = (uint32_t)&SPI0->SPI_TDR; 120 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_DSCR = 0; 121 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CTRLA = count | 122 | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE; 123 | 124 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR | 125 | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2PER_DMA_FC | 126 | src_incr | DMAC_CTRLB_DST_INCR_FIXED; 127 | 128 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CFG = DMAC_CFG_DST_PER(SPI_TX_IDX) | 129 | DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG; 130 | 131 | dmac_channel_enable(SPI_DMAC_TX_CH); 132 | } 133 | //------------------------------------------------------------------------------ 134 | // initialize SPI controller 135 | void SdSpi::init(uint8_t sckDivisor) { 136 | uint8_t scbr = sckDivisor; 137 | Spi* pSpi = SPI0; 138 | // disable SPI 139 | pSpi->SPI_CR = SPI_CR_SPIDIS; 140 | // reset SPI 141 | pSpi->SPI_CR = SPI_CR_SWRST; 142 | // no mode fault detection, set master mode 143 | pSpi->SPI_MR = SPI_PCS(SPI_CHIP_SEL) | SPI_MR_MODFDIS | SPI_MR_MSTR; 144 | // mode 0, 8-bit, 145 | pSpi->SPI_CSR[SPI_CHIP_SEL] = SPI_CSR_SCBR(scbr) | SPI_CSR_NCPHA; 146 | // enable SPI 147 | pSpi->SPI_CR |= SPI_CR_SPIEN; 148 | } 149 | //------------------------------------------------------------------------------ 150 | static inline uint8_t spiTransfer(uint8_t b) { 151 | Spi* pSpi = SPI0; 152 | 153 | pSpi->SPI_TDR = b; 154 | while ((pSpi->SPI_SR & SPI_SR_RDRF) == 0) {} 155 | b = pSpi->SPI_RDR; 156 | return b; 157 | } 158 | //------------------------------------------------------------------------------ 159 | /** SPI receive a byte */ 160 | uint8_t SdSpi::receive() { 161 | return spiTransfer(0XFF); 162 | } 163 | //------------------------------------------------------------------------------ 164 | /** SPI receive multiple bytes */ 165 | uint8_t SdSpi::receive(uint8_t* buf, size_t n) { 166 | Spi* pSpi = SPI0; 167 | int rtn = 0; 168 | #if USE_SAM3X_DMAC 169 | // clear overrun error 170 | uint32_t s = pSpi->SPI_SR; 171 | 172 | spiDmaRX(buf, n); 173 | spiDmaTX(0, n); 174 | 175 | uint32_t m = millis(); 176 | while (!dmac_channel_transfer_done(SPI_DMAC_RX_CH)) { 177 | if ((millis() - m) > SAM3X_DMA_TIMEOUT) { 178 | dmac_channel_disable(SPI_DMAC_RX_CH); 179 | dmac_channel_disable(SPI_DMAC_TX_CH); 180 | rtn = 2; 181 | break; 182 | } 183 | } 184 | if (pSpi->SPI_SR & SPI_SR_OVRES) rtn |= 1; 185 | #else // USE_SAM3X_DMAC 186 | for (size_t i = 0; i < n; i++) { 187 | pSpi->SPI_TDR = 0XFF; 188 | while ((pSpi->SPI_SR & SPI_SR_RDRF) == 0) {} 189 | buf[i] = pSpi->SPI_RDR; 190 | } 191 | #endif // USE_SAM3X_DMAC 192 | return rtn; 193 | } 194 | //------------------------------------------------------------------------------ 195 | /** SPI send a byte */ 196 | void SdSpi::send(uint8_t b) { 197 | spiTransfer(b); 198 | } 199 | //------------------------------------------------------------------------------ 200 | void SdSpi::send(const uint8_t* buf , size_t n) { 201 | Spi* pSpi = SPI0; 202 | #if USE_SAM3X_DMAC 203 | spiDmaTX(buf, n); 204 | while (!dmac_channel_transfer_done(SPI_DMAC_TX_CH)) {} 205 | #else // #if USE_SAM3X_DMAC 206 | while ((pSpi->SPI_SR & SPI_SR_TXEMPTY) == 0) {} 207 | for (size_t i = 0; i < n; i++) { 208 | pSpi->SPI_TDR = buf[i]; 209 | while ((pSpi->SPI_SR & SPI_SR_TDRE) == 0) {} 210 | } 211 | #endif // #if USE_SAM3X_DMAC 212 | while ((pSpi->SPI_SR & SPI_SR_TXEMPTY) == 0) {} 213 | // leave RDR empty 214 | uint8_t b = pSpi->SPI_RDR; 215 | } 216 | #endif // USE_NATIVE_SAM3X_SPI 217 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdStream.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | 21 | #include 22 | 23 | //============================================================================== 24 | /// @cond SHOW_PROTECTED 25 | int16_t SdStreamBase::getch() { 26 | uint8_t c; 27 | int8_t s = read(&c, 1); 28 | if (s != 1) { 29 | if (s < 0) { 30 | setstate(badbit); 31 | } else { 32 | setstate(eofbit); 33 | } 34 | return -1; 35 | } 36 | if (c != '\r' || (getmode() & ios::binary)) return c; 37 | s = read(&c, 1); 38 | if (s == 1 && c == '\n') return c; 39 | if (s == 1) seekCur(-1); 40 | return '\r'; 41 | } 42 | //------------------------------------------------------------------------------ 43 | void SdStreamBase::open(const char* path, ios::openmode mode) { 44 | uint8_t flags; 45 | switch (mode & (app | in | out | trunc)) { 46 | case app | in: 47 | case app | in | out: 48 | flags = O_RDWR | O_APPEND | O_CREAT; 49 | break; 50 | 51 | case app: 52 | case app | out: 53 | flags = O_WRITE | O_APPEND | O_CREAT; 54 | break; 55 | 56 | case in: 57 | flags = O_READ; 58 | break; 59 | 60 | case in | out: 61 | flags = O_RDWR; 62 | break; 63 | 64 | case in | out | trunc: 65 | flags = O_RDWR | O_TRUNC | O_CREAT; 66 | break; 67 | 68 | case out: 69 | case out | trunc: 70 | flags = O_WRITE | O_TRUNC | O_CREAT; 71 | break; 72 | 73 | default: 74 | goto fail; 75 | } 76 | if (mode & ios::ate) flags |= O_AT_END; 77 | if (!SdBaseFile::open(path, flags)) goto fail; 78 | setmode(mode); 79 | clear(); 80 | return; 81 | 82 | fail: 83 | SdBaseFile::close(); 84 | setstate(failbit); 85 | return; 86 | } 87 | //------------------------------------------------------------------------------ 88 | void SdStreamBase::putch(char c) { 89 | if (c == '\n' && !(getmode() & ios::binary)) { 90 | write('\r'); 91 | } 92 | write(c); 93 | if (writeError) setstate(badbit); 94 | } 95 | //------------------------------------------------------------------------------ 96 | void SdStreamBase::putstr(const char* str) { 97 | size_t n = 0; 98 | while (1) { 99 | char c = str[n]; 100 | if (c == '\0' || (c == '\n' && !(getmode() & ios::binary))) { 101 | if (n > 0) write(str, n); 102 | if (c == '\0') break; 103 | write('\r'); 104 | str += n; 105 | n = 0; 106 | } 107 | n++; 108 | } 109 | if (writeError) setstate(badbit); 110 | } 111 | //------------------------------------------------------------------------------ 112 | /** Internal do not use 113 | * \param[in] off 114 | * \param[in] way 115 | */ 116 | bool SdStreamBase::seekoff(off_type off, seekdir way) { 117 | pos_type pos; 118 | switch (way) { 119 | case beg: 120 | pos = off; 121 | break; 122 | 123 | case cur: 124 | pos = curPosition() + off; 125 | break; 126 | 127 | case end: 128 | pos = fileSize() + off; 129 | break; 130 | 131 | default: 132 | return false; 133 | } 134 | return seekpos(pos); 135 | } 136 | //------------------------------------------------------------------------------ 137 | /** Internal do not use 138 | * \param[in] pos 139 | */ 140 | bool SdStreamBase::seekpos(pos_type pos) { 141 | return seekSet(pos); 142 | } 143 | //------------------------------------------------------------------------------ 144 | int SdStreamBase::write(const void* buf, size_t n) { 145 | return SdBaseFile::write(buf, n); 146 | } 147 | //------------------------------------------------------------------------------ 148 | void SdStreamBase::write(char c) { 149 | write(&c, 1); 150 | } 151 | /// @endcond 152 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/SdStream.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef SdStream_h 21 | #define SdStream_h 22 | /** 23 | * \file 24 | * \brief \ref fstream, \ref ifstream, and \ref ofstream classes 25 | */ 26 | #include 27 | #include 28 | //============================================================================== 29 | /** 30 | * \class SdStreamBase 31 | * \brief Base class for SD streams 32 | */ 33 | class SdStreamBase : protected SdBaseFile, virtual public ios { 34 | protected: 35 | /// @cond SHOW_PROTECTED 36 | int16_t getch(); 37 | void putch(char c); 38 | void putstr(const char *str); 39 | void open(const char* path, ios::openmode mode); 40 | /** Internal do not use 41 | * \return mode 42 | */ 43 | ios::openmode getmode() {return m_mode;} 44 | /** Internal do not use 45 | * \param[in] mode 46 | */ 47 | void setmode(ios::openmode mode) {m_mode = mode;} 48 | bool seekoff(off_type off, seekdir way); 49 | bool seekpos(pos_type pos); 50 | int write(const void* buf, size_t n); 51 | void write(char c); 52 | /// @endcond 53 | private: 54 | ios::openmode m_mode; 55 | }; 56 | //============================================================================== 57 | /** 58 | * \class fstream 59 | * \brief SD file input/output stream. 60 | */ 61 | class fstream : public iostream, SdStreamBase { 62 | public: 63 | using iostream::peek; 64 | fstream() {} 65 | /** Constructor with open 66 | * 67 | * \param[in] path path to open 68 | * \param[in] mode open mode 69 | */ 70 | explicit fstream(const char* path, openmode mode = in | out) { 71 | open(path, mode); 72 | } 73 | #if DESTRUCTOR_CLOSES_FILE 74 | ~fstream() {} 75 | #endif // DESTRUCTOR_CLOSES_FILE 76 | /** Clear state and writeError 77 | * \param[in] state new state for stream 78 | */ 79 | void clear(iostate state = goodbit) { 80 | ios::clear(state); 81 | SdBaseFile::writeError = false; 82 | } 83 | /** Close a file and force cached data and directory information 84 | * to be written to the storage device. 85 | */ 86 | void close() {SdBaseFile::close();} 87 | /** Open a fstream 88 | * \param[in] path file to open 89 | * \param[in] mode open mode 90 | * 91 | * Valid open modes are (at end, ios::ate, and/or ios::binary may be added): 92 | * 93 | * ios::in - Open file for reading. 94 | * 95 | * ios::out or ios::out | ios::trunc - Truncate to 0 length, if existent, 96 | * or create a file for writing only. 97 | * 98 | * ios::app or ios::out | ios::app - Append; open or create file for 99 | * writing at end-of-file. 100 | * 101 | * ios::in | ios::out - Open file for update (reading and writing). 102 | * 103 | * ios::in | ios::out | ios::trunc - Truncate to zero length, if existent, 104 | * or create file for update. 105 | * 106 | * ios::in | ios::app or ios::in | ios::out | ios::app - Append; open or 107 | * create text file for update, writing at end of file. 108 | */ 109 | void open(const char* path, openmode mode = in | out) { 110 | SdStreamBase::open(path, mode); 111 | } 112 | /** \return True if stream is open else false. */ 113 | bool is_open () {return SdBaseFile::isOpen();} 114 | 115 | protected: 116 | /// @cond SHOW_PROTECTED 117 | /** Internal - do not use 118 | * \return 119 | */ 120 | int16_t getch() {return SdStreamBase::getch();} 121 | /** Internal - do not use 122 | * \param[out] pos 123 | */ 124 | void getpos(FatPos_t* pos) {SdBaseFile::getpos(pos);} 125 | /** Internal - do not use 126 | * \param[in] c 127 | */ 128 | void putch(char c) {SdStreamBase::putch(c);} 129 | /** Internal - do not use 130 | * \param[in] str 131 | */ 132 | void putstr(const char *str) {SdStreamBase::putstr(str);} 133 | /** Internal - do not use 134 | * \param[in] pos 135 | */ 136 | bool seekoff(off_type off, seekdir way) { 137 | return SdStreamBase::seekoff(off, way); 138 | } 139 | bool seekpos(pos_type pos) {return SdStreamBase::seekpos(pos);} 140 | void setpos(FatPos_t* pos) {SdBaseFile::setpos(pos);} 141 | bool sync() {return SdStreamBase::sync();} 142 | pos_type tellpos() {return SdStreamBase::curPosition();} 143 | /// @endcond 144 | }; 145 | //============================================================================== 146 | /** 147 | * \class ifstream 148 | * \brief SD file input stream. 149 | */ 150 | class ifstream : public istream, SdStreamBase { 151 | public: 152 | using istream::peek; 153 | ifstream() {} 154 | /** Constructor with open 155 | * \param[in] path file to open 156 | * \param[in] mode open mode 157 | */ 158 | explicit ifstream(const char* path, openmode mode = in) { 159 | open(path, mode); 160 | } 161 | #if DESTRUCTOR_CLOSES_FILE 162 | ~ifstream() {} 163 | #endif // DESTRUCTOR_CLOSES_FILE 164 | /** Close a file and force cached data and directory information 165 | * to be written to the storage device. 166 | */ 167 | void close() {SdBaseFile::close();} 168 | /** \return True if stream is open else false. */ 169 | bool is_open() {return SdBaseFile::isOpen();} 170 | /** Open an ifstream 171 | * \param[in] path file to open 172 | * \param[in] mode open mode 173 | * 174 | * \a mode See fstream::open() for valid modes. 175 | */ 176 | void open(const char* path, openmode mode = in) { 177 | SdStreamBase::open(path, mode | in); 178 | } 179 | 180 | protected: 181 | /// @cond SHOW_PROTECTED 182 | /** Internal - do not use 183 | * \return 184 | */ 185 | int16_t getch() {return SdStreamBase::getch();} 186 | /** Internal - do not use 187 | * \param[out] pos 188 | */ 189 | void getpos(FatPos_t* pos) {SdBaseFile::getpos(pos);} 190 | /** Internal - do not use 191 | * \param[in] pos 192 | */ 193 | bool seekoff(off_type off, seekdir way) { 194 | return SdStreamBase::seekoff(off, way); 195 | } 196 | bool seekpos(pos_type pos) {return SdStreamBase::seekpos(pos);} 197 | void setpos(FatPos_t* pos) {SdBaseFile::setpos(pos);} 198 | pos_type tellpos() {return SdStreamBase::curPosition();} 199 | /// @endcond 200 | }; 201 | //============================================================================== 202 | /** 203 | * \class ofstream 204 | * \brief SD card output stream. 205 | */ 206 | class ofstream : public ostream, SdStreamBase { 207 | public: 208 | ofstream() {} 209 | /** Constructor with open 210 | * \param[in] path file to open 211 | * \param[in] mode open mode 212 | */ 213 | explicit ofstream(const char* path, ios::openmode mode = out) { 214 | open(path, mode); 215 | } 216 | #if DESTRUCTOR_CLOSES_FILE 217 | ~ofstream() {} 218 | #endif // DESTRUCTOR_CLOSES_FILE 219 | /** Clear state and writeError 220 | * \param[in] state new state for stream 221 | */ 222 | void clear(iostate state = goodbit) { 223 | ios::clear(state); 224 | SdBaseFile::writeError = false; 225 | } 226 | /** Close a file and force cached data and directory information 227 | * to be written to the storage device. 228 | */ 229 | void close() {SdBaseFile::close();} 230 | /** Open an ofstream 231 | * \param[in] path file to open 232 | * \param[in] mode open mode 233 | * 234 | * \a mode See fstream::open() for valid modes. 235 | */ 236 | void open(const char* path, openmode mode = out) { 237 | SdStreamBase::open(path, mode | out); 238 | } 239 | /** \return True if stream is open else false. */ 240 | bool is_open() {return SdBaseFile::isOpen();} 241 | 242 | protected: 243 | /// @cond SHOW_PROTECTED 244 | /** 245 | * Internal do not use 246 | * \param[in] c 247 | */ 248 | void putch(char c) {SdStreamBase::putch(c);} 249 | void putstr(const char* str) {SdStreamBase::putstr(str);} 250 | bool seekoff(off_type off, seekdir way) { 251 | return SdStreamBase::seekoff(off, way); 252 | } 253 | bool seekpos(pos_type pos) {return SdStreamBase::seekpos(pos);} 254 | /** 255 | * Internal do not use 256 | * \param[in] b 257 | */ 258 | bool sync() {return SdStreamBase::sync();} 259 | pos_type tellpos() {return SdStreamBase::curPosition();} 260 | /// @endcond 261 | }; 262 | //------------------------------------------------------------------------------ 263 | #endif // SdStream_h 264 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/bufstream.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef bufstream_h 21 | #define bufstream_h 22 | /** 23 | * \file 24 | * \brief \ref ibufstream and \ref obufstream classes 25 | */ 26 | #include 27 | //============================================================================== 28 | /** 29 | * \class ibufstream 30 | * \brief parse a char string 31 | */ 32 | class ibufstream : public istream { 33 | public: 34 | /** Constructor */ 35 | ibufstream() : m_buf(0), m_len(0) {} 36 | /** Constructor 37 | * \param[in] str pointer to string to be parsed 38 | * Warning: The string will not be copied so must stay in scope. 39 | */ 40 | explicit ibufstream(const char* str) { 41 | init(str); 42 | } 43 | /** Initialize an ibufstream 44 | * \param[in] str pointer to string to be parsed 45 | * Warning: The string will not be copied so must stay in scope. 46 | */ 47 | void init(const char* str) { 48 | m_buf = str; 49 | m_len = strlen(m_buf); 50 | m_pos = 0; 51 | clear(); 52 | } 53 | 54 | protected: 55 | /// @cond SHOW_PROTECTED 56 | int16_t getch() { 57 | if (m_pos < m_len) return m_buf[m_pos++]; 58 | setstate(eofbit); 59 | return -1; 60 | } 61 | void getpos(FatPos_t *pos) { 62 | pos->position = m_pos; 63 | } 64 | bool seekoff(off_type off, seekdir way) {return false;} 65 | bool seekpos(pos_type pos) { 66 | if (pos < m_len) { 67 | m_pos = pos; 68 | return true; 69 | } 70 | return false; 71 | } 72 | void setpos(FatPos_t *pos) { 73 | m_pos = pos->position; 74 | } 75 | pos_type tellpos() { 76 | return m_pos; 77 | } 78 | /// @endcond 79 | private: 80 | const char* m_buf; 81 | size_t m_len; 82 | size_t m_pos; 83 | }; 84 | //============================================================================== 85 | /** 86 | * \class obufstream 87 | * \brief format a char string 88 | */ 89 | class obufstream : public ostream { 90 | public: 91 | /** constructor */ 92 | obufstream() : m_in(0) {} 93 | /** Constructor 94 | * \param[in] buf buffer for formatted string 95 | * \param[in] size buffer size 96 | */ 97 | obufstream(char *buf, size_t size) { 98 | init(buf, size); 99 | } 100 | /** Initialize an obufstream 101 | * \param[in] buf buffer for formatted string 102 | * \param[in] size buffer size 103 | */ 104 | void init(char *buf, size_t size) { 105 | m_buf = buf; 106 | buf[0] = '\0'; 107 | m_size = size; 108 | m_in = 0; 109 | } 110 | /** \return a pointer to the buffer */ 111 | char* buf() {return m_buf;} 112 | /** \return the length of the formatted string */ 113 | size_t length() {return m_in;} 114 | 115 | protected: 116 | /// @cond SHOW_PROTECTED 117 | void putch(char c) { 118 | if (m_in >= (m_size - 1)) { 119 | setstate(badbit); 120 | return; 121 | } 122 | m_buf[m_in++] = c; 123 | m_buf[m_in]= '\0'; 124 | } 125 | void putstr(const char *str) { 126 | while (*str) putch(*str++); 127 | } 128 | bool seekoff(off_type off, seekdir way) {return false;} 129 | bool seekpos(pos_type pos) { 130 | if (pos > m_in) return false; 131 | m_in = pos; 132 | m_buf[m_in] = '\0'; 133 | return true; 134 | } 135 | bool sync() {return true;} 136 | 137 | pos_type tellpos() { 138 | return m_in; 139 | } 140 | /// @endcond 141 | private: 142 | char *m_buf; 143 | size_t m_size; 144 | size_t m_in; 145 | }; 146 | #endif // bufstream_h 147 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/AnalogLogger/AnalogLogger.ino: -------------------------------------------------------------------------------- 1 | // A simple data logger for the Arduino analog pins with optional DS1307 2 | // uses RTClib from https://github.com/adafruit/RTClib 3 | #include 4 | #include // define FreeRam() 5 | 6 | #define SD_CHIP_SELECT SS // SD chip select pin 7 | #define USE_DS1307 0 // set nonzero to use DS1307 RTC 8 | #define LOG_INTERVAL 1000 // mills between entries 9 | #define SENSOR_COUNT 3 // number of analog pins to log 10 | #define ECHO_TO_SERIAL 1 // echo data to serial port if nonzero 11 | #define WAIT_TO_START 1 // Wait for serial input in setup() 12 | #define ADC_DELAY 10 // ADC delay for high impedence sensors 13 | 14 | // file system object 15 | SdFat sd; 16 | 17 | // text file for logging 18 | ofstream logfile; 19 | 20 | // Serial print stream 21 | ArduinoOutStream cout(Serial); 22 | 23 | // buffer to format data - makes it eaiser to echo to Serial 24 | char buf[80]; 25 | //------------------------------------------------------------------------------ 26 | #if SENSOR_COUNT > 6 27 | #error SENSOR_COUNT too large 28 | #endif // SENSOR_COUNT 29 | //------------------------------------------------------------------------------ 30 | // store error strings in flash to save RAM 31 | #define error(s) sd.errorHalt_P(PSTR(s)) 32 | //------------------------------------------------------------------------------ 33 | #if USE_DS1307 34 | // use RTClib from Adafruit 35 | // https://github.com/adafruit/RTClib 36 | 37 | // The Arduino IDE has a bug that causes Wire and RTClib to be loaded even 38 | // if USE_DS1307 is false. 39 | 40 | #error remove this line and uncomment the next two lines. 41 | //#include 42 | //#include 43 | RTC_DS1307 RTC; // define the Real Time Clock object 44 | //------------------------------------------------------------------------------ 45 | // call back for file timestamps 46 | void dateTime(uint16_t* date, uint16_t* time) { 47 | DateTime now = RTC.now(); 48 | 49 | // return date using FAT_DATE macro to format fields 50 | *date = FAT_DATE(now.year(), now.month(), now.day()); 51 | 52 | // return time using FAT_TIME macro to format fields 53 | *time = FAT_TIME(now.hour(), now.minute(), now.second()); 54 | } 55 | //------------------------------------------------------------------------------ 56 | // format date/time 57 | ostream& operator << (ostream& os, DateTime& dt) { 58 | os << dt.year() << '/' << int(dt.month()) << '/' << int(dt.day()) << ','; 59 | os << int(dt.hour()) << ':' << setfill('0') << setw(2) << int(dt.minute()); 60 | os << ':' << setw(2) << int(dt.second()) << setfill(' '); 61 | return os; 62 | } 63 | #endif // USE_DS1307 64 | //------------------------------------------------------------------------------ 65 | void setup() { 66 | Serial.begin(9600); 67 | while (!Serial){} // wait for Leonardo 68 | 69 | // pstr stores strings in flash to save RAM 70 | cout << endl << pstr("FreeRam: ") << FreeRam() << endl; 71 | 72 | #if WAIT_TO_START 73 | cout << pstr("Type any character to start\n"); 74 | while (Serial.read() <= 0) {} 75 | delay(400); // catch Due reset problem 76 | #endif // WAIT_TO_START 77 | 78 | #if USE_DS1307 79 | // connect to RTC 80 | Wire.begin(); 81 | if (!RTC.begin()) error("RTC failed"); 82 | 83 | // set date time callback function 84 | SdFile::dateTimeCallback(dateTime); 85 | DateTime now = RTC.now(); 86 | cout << now << endl; 87 | #endif // USE_DS1307 88 | 89 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 90 | if (!sd.begin(SD_CHIP_SELECT, SPI_HALF_SPEED)) sd.initErrorHalt(); 91 | 92 | // create a new file in root, the current working directory 93 | char name[] = "LOGGER00.CSV"; 94 | 95 | for (uint8_t i = 0; i < 100; i++) { 96 | name[6] = i/10 + '0'; 97 | name[7] = i%10 + '0'; 98 | if (sd.exists(name)) continue; 99 | logfile.open(name); 100 | break; 101 | } 102 | if (!logfile.is_open()) error("file.open"); 103 | 104 | cout << pstr("Logging to: ") << name << endl; 105 | cout << pstr("Type any character to stop\n\n"); 106 | 107 | // format header in buffer 108 | obufstream bout(buf, sizeof(buf)); 109 | 110 | bout << pstr("millis"); 111 | 112 | #if USE_DS1307 113 | bout << pstr(",date,time"); 114 | #endif // USE_DS1307 115 | 116 | for (uint8_t i = 0; i < SENSOR_COUNT; i++) { 117 | bout << pstr(",sens") << int(i); 118 | } 119 | logfile << buf << endl; 120 | 121 | #if ECHO_TO_SERIAL 122 | cout << buf << endl; 123 | #endif // ECHO_TO_SERIAL 124 | } 125 | //------------------------------------------------------------------------------ 126 | void loop() { 127 | uint32_t m; 128 | 129 | // wait for time to be a multiple of interval 130 | do { 131 | m = millis(); 132 | } while (m % LOG_INTERVAL); 133 | 134 | // use buffer stream to format line 135 | obufstream bout(buf, sizeof(buf)); 136 | 137 | // start with time in millis 138 | bout << m; 139 | 140 | #if USE_DS1307 141 | DateTime now = RTC.now(); 142 | bout << ',' << now; 143 | #endif // USE_DS1307 144 | 145 | // read analog pins and format data 146 | for (uint8_t ia = 0; ia < SENSOR_COUNT; ia++) { 147 | #if ADC_DELAY 148 | analogRead(ia); 149 | delay(ADC_DELAY); 150 | #endif // ADC_DELAY 151 | bout << ',' << analogRead(ia); 152 | } 153 | bout << endl; 154 | 155 | // log data and flush to SD 156 | logfile << buf << flush; 157 | 158 | // check for error 159 | if (!logfile) error("write data failed"); 160 | 161 | #if ECHO_TO_SERIAL 162 | cout << buf; 163 | #endif // ECHO_TO_SERIAL 164 | 165 | // don't log two points in the same millis 166 | if (m == millis()) delay(1); 167 | 168 | if (!Serial.available()) return; 169 | logfile.close(); 170 | cout << pstr("Done!"); 171 | while (1); 172 | } 173 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/HelloWorld/HelloWorld.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // create a serial output stream 4 | ArduinoOutStream cout(Serial); 5 | 6 | void setup() { 7 | Serial.begin(9600); 8 | 9 | while (!Serial) {} // wait for Leonardo 10 | delay(2000); 11 | 12 | cout << "Hello, World!\n"; 13 | } 14 | 15 | void loop() {} 16 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/MiniSerial/MiniSerial.ino: -------------------------------------------------------------------------------- 1 | // This example illustrates use of SdFat's 2 | // minimal unbuffered AVR Serial support. 3 | // 4 | // This is useful for debug and saves RAM 5 | // Will not work on Due, Leonardo, or Teensy 6 | #include 7 | #include 8 | #ifndef UDR0 9 | #error no AVR serial port0 10 | #endif 11 | void setup() { 12 | MiniSerial.begin(9600); 13 | MiniSerial.println(FreeRam()); 14 | MiniSerial.println(F("Type any Character")); 15 | while(MiniSerial.read() < 0) {} 16 | MiniSerial.println(F("Done")); 17 | } 18 | void loop() {} 19 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/OpenNext/OpenNext.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Open all files in the root dir and print their filename and modify date/time 3 | */ 4 | #include 5 | 6 | // SD chip select pin 7 | const uint8_t chipSelect = SS; 8 | 9 | // file system object 10 | SdFat sd; 11 | 12 | SdFile file; 13 | 14 | // define a serial output stream 15 | ArduinoOutStream cout(Serial); 16 | //------------------------------------------------------------------------------ 17 | void setup() { 18 | Serial.begin(9600); 19 | while (!Serial) {} // wait for Leonardo 20 | delay(1000); 21 | 22 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 23 | // breadboards. use SPI_FULL_SPEED for better performance. 24 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 25 | 26 | // open next file in root. The volume working directory, vwd, is root 27 | while (file.openNext(sd.vwd(), O_READ)) { 28 | file.printName(&Serial); 29 | cout << ' '; 30 | file.printModifyDateTime(&Serial); 31 | cout << endl; 32 | file.close(); 33 | } 34 | cout << "\nDone!" << endl; 35 | } 36 | //------------------------------------------------------------------------------ 37 | void loop() {} 38 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/PrintBenchmark/PrintBenchmark.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch is a simple Print benchmark. 3 | */ 4 | #include 5 | #include 6 | 7 | // SD chip select pin 8 | const uint8_t chipSelect = SS; 9 | 10 | // number of lines to print 11 | const uint16_t N_PRINT = 20000; 12 | 13 | // file system 14 | SdFat sd; 15 | 16 | // test file 17 | SdFile file; 18 | 19 | // Serial output stream 20 | ArduinoOutStream cout(Serial); 21 | //------------------------------------------------------------------------------ 22 | // store error strings in flash to save RAM 23 | #define error(s) sd.errorHalt_P(PSTR(s)) 24 | //------------------------------------------------------------------------------ 25 | void setup() { 26 | Serial.begin(9600); 27 | while (!Serial) { 28 | // wait for Leonardo 29 | } 30 | } 31 | //------------------------------------------------------------------------------ 32 | void loop() { 33 | uint32_t maxLatency; 34 | uint32_t minLatency; 35 | uint32_t totalLatency; 36 | 37 | while (Serial.read() >= 0) { 38 | } 39 | // pstr stores strings in flash to save RAM 40 | cout << pstr("Type any character to start\n"); 41 | while (Serial.read() <= 0) { 42 | } 43 | delay(400); // catch Due reset problem 44 | 45 | cout << pstr("Free RAM: ") << FreeRam() << endl; 46 | 47 | // initialize the SD card at SPI_FULL_SPEED for best performance. 48 | // try SPI_HALF_SPEED if bus errors occur. 49 | if (!sd.begin(chipSelect, SPI_FULL_SPEED)) sd.initErrorHalt(); 50 | 51 | cout << pstr("Type is FAT") << int(sd.vol()->fatType()) << endl; 52 | 53 | // open or create file - truncate existing file. 54 | if (!file.open("BENCH.TXT", O_CREAT | O_TRUNC | O_RDWR)) { 55 | error("open failed"); 56 | } 57 | cout << pstr("Starting print test. Please wait.\n\n"); 58 | 59 | // do write test 60 | for (int test = 0; test < 3; test++) { 61 | 62 | switch(test) { 63 | case 0: 64 | cout << pstr("Test of println(uint16_t)\n"); 65 | break; 66 | 67 | case 1: 68 | cout << pstr("Test of printField(uint16_t, char)\n"); 69 | break; 70 | 71 | case 2: 72 | cout << pstr("Test of println(double)\n"); 73 | break; 74 | } 75 | file.truncate(0); 76 | maxLatency = 0; 77 | minLatency = 999999; 78 | totalLatency = 0; 79 | uint32_t t = millis(); 80 | for (uint16_t i = 0; i < N_PRINT; i++) { 81 | uint32_t m = micros(); 82 | 83 | switch(test) { 84 | case 0: 85 | file.println(i); 86 | break; 87 | 88 | case 1: 89 | file.printField(i, '\n'); 90 | break; 91 | 92 | case 2: 93 | file.println((double)0.01*i); 94 | break; 95 | } 96 | 97 | if (file.writeError) { 98 | error("write failed"); 99 | } 100 | m = micros() - m; 101 | if (maxLatency < m) maxLatency = m; 102 | if (minLatency > m) minLatency = m; 103 | totalLatency += m; 104 | } 105 | file.sync(); 106 | t = millis() - t; 107 | double s = file.fileSize(); 108 | cout << pstr("Time ") << 0.001*t << pstr(" sec\n"); 109 | cout << pstr("File size ") << 0.001*s << pstr(" KB\n"); 110 | cout << pstr("Write ") << s/t << pstr(" KB/sec\n"); 111 | cout << pstr("Maximum latency: ") << maxLatency; 112 | cout << pstr(" usec, Minimum Latency: ") << minLatency; 113 | cout << pstr(" usec, Avg Latency: "); 114 | cout << totalLatency/N_PRINT << pstr(" usec\n\n"); 115 | } 116 | file.close(); 117 | cout << pstr("Done!\n\n"); 118 | } 119 | 120 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/QuickStart/QuickStart.ino: -------------------------------------------------------------------------------- 1 | // Quick hardware test 2 | #include 3 | // Test with reduced SPI speed for breadboards. 4 | // Change spiSpeed to SPI_FULL_SPEED for better performance 5 | // Use SPI_QUARTER_SPEED for even slower SPI bus speed 6 | const uint8_t spiSpeed = SPI_HALF_SPEED; 7 | //------------------------------------------------------------------------------ 8 | // Normally SdFat is used in applications in place 9 | // of Sd2Card, SdVolume, and SdFile for root. 10 | Sd2Card card; 11 | SdVolume volume; 12 | SdFile root; 13 | 14 | // Serial streams 15 | ArduinoOutStream cout(Serial); 16 | 17 | // input buffer for line 18 | char cinBuf[40]; 19 | ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); 20 | 21 | // SD card chip select 22 | int chipSelect; 23 | 24 | void cardOrSpeed() { 25 | cout << pstr( 26 | "Try another SD card or reduce the SPI bus speed.\n" 27 | "The current SPI speed is: "); 28 | uint8_t divisor = 1; 29 | for (uint8_t i = 0; i < spiSpeed; i++) divisor *= 2; 30 | cout << F_CPU * 0.5e-6 / divisor << pstr(" MHz\n"); 31 | cout << pstr("Edit spiSpeed in this sketch to change it.\n"); 32 | } 33 | 34 | void reformatMsg() { 35 | cout << pstr("Try reformatting the card. For best results use\n"); 36 | cout << pstr("the SdFormatter sketch in SdFat/examples or download\n"); 37 | cout << pstr("and use SDFormatter from www.sdcard.org/consumer.\n"); 38 | } 39 | 40 | void setup() { 41 | Serial.begin(9600); 42 | while (!Serial) {} // wait for Leonardo 43 | 44 | cout << pstr( 45 | "\nSD chip select is the key hardware option.\n" 46 | "Common values are:\n" 47 | "Arduino Ethernet shield, pin 4\n" 48 | "Sparkfun SD shield, pin 8\n" 49 | "Adafruit SD shields and modules, pin 10\n"); 50 | } 51 | 52 | bool firstTry = true; 53 | void loop() { 54 | // read any existing Serial data 55 | while (Serial.read() >= 0) {} 56 | 57 | if (!firstTry) cout << pstr("\nRestarting\n"); 58 | firstTry = false; 59 | 60 | cout << pstr("\nEnter the chip select pin number: "); 61 | cin.readline(); 62 | if (cin >> chipSelect) { 63 | cout << chipSelect << endl; 64 | } else { 65 | cout << pstr("\nInvalid pin number\n"); 66 | return; 67 | } 68 | if (!card.init(spiSpeed, chipSelect)) { 69 | cout << pstr( 70 | "\nSD initialization failed.\n" 71 | "Do not reformat the card!\n" 72 | "Is the card correctly inserted?\n" 73 | "Is chipSelect set to the correct value?\n" 74 | "Is there a wiring/soldering problem?\n"); 75 | cout << pstr("errorCode: ") << hex << showbase << int(card.errorCode()); 76 | cout << pstr(", errorData: ") << int(card.errorData()); 77 | cout << dec << noshowbase << endl; 78 | return; 79 | } 80 | cout << pstr("\nCard successfully initialized.\n"); 81 | cout << endl; 82 | 83 | uint32_t size = card.cardSize(); 84 | if (size == 0) { 85 | cout << pstr("Can't determine the card size.\n"); 86 | cardOrSpeed(); 87 | return; 88 | } 89 | uint32_t sizeMB = 0.000512 * size + 0.5; 90 | cout << pstr("Card size: ") << sizeMB; 91 | cout << pstr(" MB (MB = 1,000,000 bytes)\n"); 92 | cout << endl; 93 | 94 | if (!volume.init(&card)) { 95 | if (card.errorCode()) { 96 | cout << pstr("Can't read the card.\n"); 97 | cardOrSpeed(); 98 | } else { 99 | cout << pstr("Can't find a valid FAT16/FAT32 partition.\n"); 100 | reformatMsg(); 101 | } 102 | return; 103 | } 104 | cout << pstr("Volume is FAT") << int(volume.fatType()); 105 | cout << pstr(", Cluster size (bytes): ") << 512L * volume.blocksPerCluster(); 106 | cout << endl << endl; 107 | 108 | root.close(); 109 | if (!root.openRoot(&volume)) { 110 | cout << pstr("Can't open root directory.\n"); 111 | reformatMsg(); 112 | return; 113 | } 114 | cout << pstr("Files found (name date time size):\n"); 115 | root.ls(LS_R | LS_DATE | LS_SIZE); 116 | 117 | if ((sizeMB > 1100 && volume.blocksPerCluster() < 64) 118 | || (sizeMB < 2200 && volume.fatType() == 32)) { 119 | cout << pstr("\nThis card should be reformatted for best performance.\n"); 120 | cout << pstr("Use a cluster size of 32 KB for cards larger than 1 GB.\n"); 121 | cout << pstr("Only cards larger than 2 GB should be formatted FAT32.\n"); 122 | reformatMsg(); 123 | return; 124 | } 125 | // read any existing Serial data 126 | while (Serial.read() >= 0) {} 127 | cout << pstr("\nSuccess! Type any character to restart.\n"); 128 | while (Serial.read() < 0) {} 129 | } -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/RawWrite/RawWrite.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch illustrates raw write functions in SdFat that 3 | * can be used for high speed data logging. These functions 4 | * are used in the WaveRP library to record audio with the 5 | * Adafruit Wave Shield using the built-in Arduino ADC. 6 | * 7 | * The WaveRP library captures data from the ADC in an ISR 8 | * that is driven driven by timer one. Data is collected in 9 | * two 512 byte buffers and written to the SD card. 10 | * 11 | * This sketch simulates logging from a source that produces 12 | * data at a constant rate of one block every MICROS_PER_BLOCK. 13 | * 14 | * If a high quality SanDisk card is used with this sketch 15 | * no overruns occur and the maximum block write time is 16 | * under 2000 micros. 17 | * 18 | * Note: WaveRP creates a very large file then truncates it 19 | * to the length that is used for a recording. It only takes 20 | * a few seconds to erase a 500 MB file since the card only 21 | * marks the blocks as erased; no data transfer is required. 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | // SD chip select pin 28 | const uint8_t chipSelect = SS; 29 | 30 | // number of blocks in the contiguous file 31 | const uint32_t BLOCK_COUNT = 10000UL; 32 | 33 | // time to produce a block of data 34 | const uint32_t MICROS_PER_BLOCK = 10000; 35 | 36 | // file system 37 | SdFat sd; 38 | 39 | // test file 40 | SdFile file; 41 | 42 | // file extent 43 | uint32_t bgnBlock, endBlock; 44 | 45 | // Serial output stream 46 | ArduinoOutStream cout(Serial); 47 | //------------------------------------------------------------------------------ 48 | // store error strings in flash to save RAM 49 | #define error(s) sd.errorHalt_P(PSTR(s)) 50 | //------------------------------------------------------------------------------ 51 | // log of first overruns 52 | #define OVER_DIM 20 53 | struct { 54 | uint32_t block; 55 | uint32_t micros; 56 | } over[OVER_DIM]; 57 | //------------------------------------------------------------------------------ 58 | void setup(void) { 59 | Serial.begin(9600); 60 | while (!Serial) {} // wait for Leonardo 61 | } 62 | //------------------------------------------------------------------------------ 63 | void loop(void) { 64 | while (Serial.read() >= 0) {} 65 | // pstr stores strings in flash to save RAM 66 | cout << pstr("Type any character to start\n"); 67 | while (Serial.read() <= 0) {} 68 | delay(400); // catch Due reset problem 69 | 70 | cout << pstr("Free RAM: ") << FreeRam() << endl; 71 | 72 | // initialize the SD card at SPI_FULL_SPEED for best performance. 73 | // try SPI_HALF_SPEED if bus errors occur. 74 | if (!sd.begin(chipSelect, SPI_FULL_SPEED)) sd.initErrorHalt(); 75 | 76 | // delete possible existing file 77 | sd.remove("RAW.TXT"); 78 | 79 | // create a contiguous file 80 | if (!file.createContiguous(sd.vwd(), "RAW.TXT", 512UL*BLOCK_COUNT)) { 81 | error("createContiguous failed"); 82 | } 83 | // get the location of the file's blocks 84 | if (!file.contiguousRange(&bgnBlock, &endBlock)) { 85 | error("contiguousRange failed"); 86 | } 87 | //*********************NOTE************************************** 88 | // NO SdFile calls are allowed while cache is used for raw writes 89 | //*************************************************************** 90 | 91 | // clear the cache and use it as a 512 byte buffer 92 | uint8_t* pCache = (uint8_t*)sd.vol()->cacheClear(); 93 | 94 | // fill cache with eight lines of 64 bytes each 95 | memset(pCache, ' ', 512); 96 | for (uint16_t i = 0; i < 512; i += 64) { 97 | // put line number at end of line then CR/LF 98 | pCache[i + 61] = '0' + (i/64); 99 | pCache[i + 62] = '\r'; 100 | pCache[i + 63] = '\n'; 101 | } 102 | 103 | cout << pstr("Start raw write of ") << file.fileSize() << pstr(" bytes at\n"); 104 | cout << 512000000UL/MICROS_PER_BLOCK << pstr(" bytes per second\n"); 105 | cout << pstr("Please wait ") << (BLOCK_COUNT*MICROS_PER_BLOCK)/1000000UL; 106 | cout << pstr(" seconds\n"); 107 | 108 | // tell card to setup for multiple block write with pre-erase 109 | if (!sd.card()->erase(bgnBlock, endBlock)) error("card.erase failed"); 110 | if (!sd.card()->writeStart(bgnBlock, BLOCK_COUNT)) { 111 | error("writeStart failed"); 112 | } 113 | // init stats 114 | uint16_t overruns = 0; 115 | uint32_t maxWriteTime = 0; 116 | uint32_t t = micros(); 117 | uint32_t tNext = t; 118 | 119 | // write data 120 | for (uint32_t b = 0; b < BLOCK_COUNT; b++) { 121 | // write must be done by this time 122 | tNext += MICROS_PER_BLOCK; 123 | 124 | // put block number at start of first line in block 125 | uint32_t n = b; 126 | for (int8_t d = 5; d >= 0; d--){ 127 | pCache[d] = n || d == 5 ? n % 10 + '0' : ' '; 128 | n /= 10; 129 | } 130 | // write a 512 byte block 131 | uint32_t tw = micros(); 132 | if (!sd.card()->writeData(pCache)) error("writeData failed"); 133 | tw = micros() - tw; 134 | 135 | // check for max write time 136 | if (tw > maxWriteTime) { 137 | maxWriteTime = tw; 138 | } 139 | // check for overrun 140 | if (micros() > tNext) { 141 | if (overruns < OVER_DIM) { 142 | over[overruns].block = b; 143 | over[overruns].micros = tw; 144 | } 145 | overruns++; 146 | // advance time to reflect overrun 147 | tNext = micros(); 148 | } 149 | else { 150 | // wait for time to write next block 151 | while(micros() < tNext); 152 | } 153 | } 154 | // total write time 155 | t = micros() - t; 156 | 157 | // end multiple block write mode 158 | if (!sd.card()->writeStop()) error("writeStop failed"); 159 | 160 | cout << pstr("Done\n"); 161 | cout << pstr("Elapsed time: ") << setprecision(3)<< 1.e-6*t; 162 | cout << pstr(" seconds\n"); 163 | cout << pstr("Max write time: ") << maxWriteTime << pstr(" micros\n"); 164 | cout << pstr("Overruns: ") << overruns << endl; 165 | if (overruns) { 166 | uint8_t n = overruns > OVER_DIM ? OVER_DIM : overruns; 167 | cout << pstr("fileBlock,micros") << endl; 168 | for (uint8_t i = 0; i < n; i++) { 169 | cout << over[i].block << ',' << over[i].micros << endl; 170 | } 171 | } 172 | // close file for next pass of loop 173 | file.close(); 174 | Serial.println(); 175 | } -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/ReadWriteSdFat/ReadWriteSdFat.ino: -------------------------------------------------------------------------------- 1 | // Ported to SdFat from the native Arduino SD library example by Bill Greiman 2 | // On the Ethernet Shield, CS is pin 4. SdFat handles setting SS 3 | const int chipSelect = 4; 4 | /* 5 | SD card read/write 6 | 7 | This example shows how to read and write data to and from an SD card file 8 | The circuit: 9 | * SD card attached to SPI bus as follows: 10 | ** MOSI - pin 11 11 | ** MISO - pin 12 12 | ** CLK - pin 13 13 | ** CS - pin 4 14 | 15 | created Nov 2010 16 | by David A. Mellis 17 | updated 2 Dec 2010 18 | by Tom Igoe 19 | modified by Bill Greiman 11 Apr 2011 20 | This example code is in the public domain. 21 | 22 | */ 23 | #include 24 | SdFat sd; 25 | SdFile myFile; 26 | 27 | void setup() { 28 | Serial.begin(9600); 29 | while (!Serial) {} // wait for Leonardo 30 | Serial.println("Type any character to start"); 31 | while (Serial.read() <= 0) {} 32 | delay(400); // catch Due reset problem 33 | 34 | // Initialize SdFat or print a detailed error message and halt 35 | // Use half speed like the native library. 36 | // change to SPI_FULL_SPEED for more performance. 37 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 38 | 39 | // open the file for write at end like the Native SD library 40 | if (!myFile.open("test.txt", O_RDWR | O_CREAT | O_AT_END)) { 41 | sd.errorHalt("opening test.txt for write failed"); 42 | } 43 | // if the file opened okay, write to it: 44 | Serial.print("Writing to test.txt..."); 45 | myFile.println("testing 1, 2, 3."); 46 | 47 | // close the file: 48 | myFile.close(); 49 | Serial.println("done."); 50 | 51 | // re-open the file for reading: 52 | if (!myFile.open("test.txt", O_READ)) { 53 | sd.errorHalt("opening test.txt for read failed"); 54 | } 55 | Serial.println("test.txt:"); 56 | 57 | // read from the file until there's nothing else in it: 58 | int data; 59 | while ((data = myFile.read()) >= 0) Serial.write(data); 60 | // close the file: 61 | myFile.close(); 62 | } 63 | 64 | void loop() { 65 | // nothing happens after setup 66 | } 67 | 68 | 69 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/SD_Size/SD_Size.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Sketch to compare size of Arduino SD library with SdFat V2. 3 | * See SdFatSize.pde for SdFat sketch. 4 | */ 5 | #include 6 | #include 7 | 8 | File file; 9 | //------------------------------------------------------------------------------ 10 | void setup() { 11 | Serial.begin(9600); 12 | while (!Serial) {} // wait for Leonardo 13 | 14 | if (!SD.begin()) { 15 | Serial.println("begin failed"); 16 | return; 17 | } 18 | file = SD.open("TEST_SD.TXT", FILE_WRITE); 19 | 20 | file.println("Hello"); 21 | 22 | file.close(); 23 | Serial.println("Done"); 24 | } 25 | //------------------------------------------------------------------------------ 26 | void loop() {} 27 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/SdFatSize/SdFatSize.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Sketch to compare size of SdFat V2 with Arduino SD library. 3 | * See SD_Size.pde for Arduino SD sketch. 4 | * 5 | */ 6 | #include 7 | 8 | SdFat sd; 9 | 10 | SdFile file; 11 | //------------------------------------------------------------------------------ 12 | void setup() { 13 | Serial.begin(9600); 14 | while (!Serial) {} // wait for Leonardo 15 | 16 | if (!sd.begin()) { 17 | Serial.println("begin failed"); 18 | return; 19 | } 20 | file.open("SIZE_TST.TXT", O_RDWR | O_CREAT | O_AT_END); 21 | 22 | file.println("Hello"); 23 | 24 | file.close(); 25 | Serial.println("Done"); 26 | } 27 | //------------------------------------------------------------------------------ 28 | void loop() {} 29 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/SdInfo/SdInfo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch attempts to initialize an SD card and analyze its structure. 3 | */ 4 | #include 5 | /* 6 | * SD chip select pin. Common values are: 7 | * 8 | * Arduino Ethernet shield, pin 4. 9 | * SparkFun SD shield, pin 8. 10 | * Adafruit SD shields and modules, pin 10. 11 | * Default SD chip select is the SPI SS pin. 12 | */ 13 | const uint8_t SdChipSelect = SS; 14 | 15 | Sd2Card card; 16 | SdVolume vol; 17 | 18 | // serial output steam 19 | ArduinoOutStream cout(Serial); 20 | 21 | // global for card size 22 | uint32_t cardSize; 23 | 24 | // global for card erase size 25 | uint32_t eraseSize; 26 | //------------------------------------------------------------------------------ 27 | // store error strings in flash 28 | #define sdErrorMsg(msg) sdErrorMsg_P(PSTR(msg)); 29 | void sdErrorMsg_P(const char* str) { 30 | cout << pgm(str) << endl; 31 | if (card.errorCode()) { 32 | cout << pstr("SD errorCode: "); 33 | cout << hex << int(card.errorCode()) << endl; 34 | cout << pstr("SD errorData: "); 35 | cout << int(card.errorData()) << dec << endl; 36 | } 37 | } 38 | //------------------------------------------------------------------------------ 39 | uint8_t cidDmp() { 40 | cid_t cid; 41 | if (!card.readCID(&cid)) { 42 | sdErrorMsg("readCID failed"); 43 | return false; 44 | } 45 | cout << pstr("\nManufacturer ID: "); 46 | cout << hex << int(cid.mid) << dec << endl; 47 | cout << pstr("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl; 48 | cout << pstr("Product: "); 49 | for (uint8_t i = 0; i < 5; i++) { 50 | cout << cid.pnm[i]; 51 | } 52 | cout << pstr("\nVersion: "); 53 | cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl; 54 | cout << pstr("Serial number: ") << cid.psn << endl; 55 | cout << pstr("Manufacturing date: "); 56 | cout << int(cid.mdt_month) << '/'; 57 | cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl; 58 | cout << endl; 59 | return true; 60 | } 61 | //------------------------------------------------------------------------------ 62 | uint8_t csdDmp() { 63 | csd_t csd; 64 | uint8_t eraseSingleBlock; 65 | if (!card.readCSD(&csd)) { 66 | sdErrorMsg("readCSD failed"); 67 | return false; 68 | } 69 | if (csd.v1.csd_ver == 0) { 70 | eraseSingleBlock = csd.v1.erase_blk_en; 71 | eraseSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; 72 | } else if (csd.v2.csd_ver == 1) { 73 | eraseSingleBlock = csd.v2.erase_blk_en; 74 | eraseSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low; 75 | } else { 76 | cout << pstr("csd version error\n"); 77 | return false; 78 | } 79 | eraseSize++; 80 | cout << pstr("cardSize: ") << 0.000512*cardSize; 81 | cout << pstr(" MB (MB = 1,000,000 bytes)\n"); 82 | 83 | cout << pstr("flashEraseSize: ") << int(eraseSize) << pstr(" blocks\n"); 84 | cout << pstr("eraseSingleBlock: "); 85 | if (eraseSingleBlock) { 86 | cout << pstr("true\n"); 87 | } else { 88 | cout << pstr("false\n"); 89 | } 90 | return true; 91 | } 92 | //------------------------------------------------------------------------------ 93 | // print partition table 94 | uint8_t partDmp() { 95 | cache_t *p = vol.cacheClear(); 96 | if (!p) { 97 | sdErrorMsg("cacheClear failed"); 98 | return false; 99 | } 100 | if (!card.readBlock(0, p->data)) { 101 | sdErrorMsg("read MBR failed"); 102 | return false; 103 | } 104 | cout << pstr("\nSD Partition Table\n"); 105 | cout << pstr("part,boot,type,start,length\n"); 106 | for (uint8_t ip = 1; ip < 5; ip++) { 107 | part_t *pt = &p->mbr.part[ip - 1]; 108 | cout << int(ip) << ',' << hex << int(pt->boot) << ',' << int(pt->type); 109 | cout << dec << ',' << pt->firstSector <<',' << pt->totalSectors << endl; 110 | } 111 | return true; 112 | } 113 | //------------------------------------------------------------------------------ 114 | void volDmp() { 115 | cout << pstr("\nVolume is FAT") << int(vol.fatType()) << endl; 116 | cout << pstr("blocksPerCluster: ") << int(vol.blocksPerCluster()) << endl; 117 | cout << pstr("clusterCount: ") << vol.clusterCount() << endl; 118 | uint32_t volFree = vol.freeClusterCount(); 119 | cout << pstr("freeClusters: ") << volFree << endl; 120 | float fs = 0.000512*volFree*vol.blocksPerCluster(); 121 | cout << pstr("freeSpace: ") << fs << pstr(" MB (MB = 1,000,000 bytes)\n"); 122 | cout << pstr("fatStartBlock: ") << vol.fatStartBlock() << endl; 123 | cout << pstr("fatCount: ") << int(vol.fatCount()) << endl; 124 | cout << pstr("blocksPerFat: ") << vol.blocksPerFat() << endl; 125 | cout << pstr("rootDirStart: ") << vol.rootDirStart() << endl; 126 | cout << pstr("dataStartBlock: ") << vol.dataStartBlock() << endl; 127 | if (vol.dataStartBlock() % eraseSize) { 128 | cout << pstr("Data area is not aligned on flash erase boundaries!\n"); 129 | cout << pstr("Download and use formatter from www.sdcard.org/consumer!\n"); 130 | } 131 | } 132 | //------------------------------------------------------------------------------ 133 | void setup() { 134 | Serial.begin(9600); 135 | while(!Serial) {} // wait for Leonardo 136 | 137 | // use uppercase in hex and use 0X base prefix 138 | cout << uppercase << showbase << endl; 139 | 140 | // pstr stores strings in flash to save RAM 141 | cout << pstr("SdFat version: ") << SD_FAT_VERSION << endl; 142 | } 143 | //------------------------------------------------------------------------------ 144 | void loop() { 145 | // read any existing Serial data 146 | while (Serial.read() >= 0) {} 147 | 148 | // pstr stores strings in flash to save RAM 149 | cout << pstr("\ntype any character to start\n"); 150 | while (Serial.read() <= 0) {} 151 | delay(400); // catch Due reset problem 152 | 153 | uint32_t t = millis(); 154 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 155 | // breadboards. use SPI_FULL_SPEED for better performance. 156 | if (!card.init(SPI_HALF_SPEED, SdChipSelect)) { 157 | sdErrorMsg("\ncard.init failed"); 158 | return; 159 | } 160 | t = millis() - t; 161 | 162 | cardSize = card.cardSize(); 163 | if (cardSize == 0) { 164 | sdErrorMsg("cardSize failed"); 165 | return; 166 | } 167 | cout << pstr("\ninit time: ") << t << " ms" << endl; 168 | cout << pstr("\nCard type: "); 169 | switch (card.type()) { 170 | case SD_CARD_TYPE_SD1: 171 | cout << pstr("SD1\n"); 172 | break; 173 | 174 | case SD_CARD_TYPE_SD2: 175 | cout << pstr("SD2\n"); 176 | break; 177 | 178 | case SD_CARD_TYPE_SDHC: 179 | if (cardSize < 70000000) { 180 | cout << pstr("SDHC\n"); 181 | } else { 182 | cout << pstr("SDXC\n"); 183 | } 184 | break; 185 | 186 | default: 187 | cout << pstr("Unknown\n"); 188 | } 189 | if (!cidDmp()) return; 190 | if (!csdDmp()) return; 191 | if (!partDmp()) return; 192 | if (!vol.init(&card)) { 193 | sdErrorMsg("\nvol.init failed"); 194 | return; 195 | } 196 | volDmp(); 197 | } -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/StressTest/StressTest.ino: -------------------------------------------------------------------------------- 1 | // This stress test will create and write files until the SD is full. 2 | #include 3 | 4 | // SD chip select pin. 5 | const uint8_t SD_CS_PIN = SS; 6 | 7 | // Set write buffer size. 8 | #ifdef __arm__ 9 | #ifndef CORE_TEENSY 10 | // Due 11 | const size_t BUF_SIZE = 32768; 12 | #else // CORE_TEENSY 13 | // Teensy 3.0 14 | const size_t BUF_SIZE = 8192; 15 | #endif // CORE_TEENSY 16 | #elif defined(RAMEND) && RAMEND > 5000 17 | // AVR with more than 4 KB RAM 18 | const size_t BUF_SIZE = 4096; 19 | #else // __arm__ 20 | // other 21 | const size_t BUF_SIZE = 512; 22 | #endif // __arm__ 23 | 24 | const size_t FILE_SIZE_KB = 10240; 25 | const uint16_t BUFS_PER_FILE = (1024L*FILE_SIZE_KB/BUF_SIZE); 26 | 27 | SdFat sd; 28 | 29 | SdFile file; 30 | 31 | uint8_t buf[BUF_SIZE]; 32 | char name[13]; 33 | //------------------------------------------------------------------------------ 34 | void setup() { 35 | Serial.begin(9600); 36 | Serial.print("BUF_SIZE "); 37 | Serial.println(BUF_SIZE); 38 | Serial.println("Type any character to start"); 39 | while (Serial.read() < 0) {} 40 | 41 | if (!sd.begin(SD_CS_PIN))sd.errorHalt("sd.begin"); 42 | 43 | // Fill buf with known value. 44 | for (size_t i = 0; i < BUF_SIZE; i++) buf[i] = i; 45 | 46 | // Wait to begin. 47 | do {delay(10);} while (Serial.read() >= 0); 48 | Serial.println("Type any character to stop after next file"); 49 | } 50 | //------------------------------------------------------------------------------ 51 | void loop() { 52 | // Free KB on SD. 53 | uint32_t freeKB = sd.vol()->freeClusterCount()*sd.vol()->blocksPerCluster()/2; 54 | 55 | Serial.print("Free KB: "); 56 | Serial.println(freeKB); 57 | if (freeKB < 2*FILE_SIZE_KB) { 58 | Serial.println(" Done!"); 59 | while(1); 60 | } 61 | sprintf(name, "%lu.DAT", freeKB); 62 | if (!file.open(name, O_WRITE | O_CREAT | O_TRUNC)) { 63 | sd.errorHalt("Open error!"); 64 | } 65 | for (uint16_t i = 0; i < BUFS_PER_FILE; i++) { 66 | if (file.write(buf, BUF_SIZE) != BUF_SIZE) { 67 | sd.errorHalt("Write error!"); 68 | } 69 | } 70 | file.close(); 71 | if (Serial.available()) { 72 | Serial.println("Stopped!"); 73 | while(1); 74 | } 75 | } -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/Timestamp/Timestamp.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch tests the dateTimeCallback() function 3 | * and the timestamp() function. 4 | */ 5 | #include 6 | 7 | SdFat sd; 8 | 9 | SdFile file; 10 | 11 | // Default SD chip select is SS pin 12 | const uint8_t chipSelect = SS; 13 | 14 | // create Serial stream 15 | ArduinoOutStream cout(Serial); 16 | //------------------------------------------------------------------------------ 17 | // store error strings in flash to save RAM 18 | #define error(s) sd.errorHalt_P(PSTR(s)) 19 | //------------------------------------------------------------------------------ 20 | /* 21 | * date/time values for debug 22 | * normally supplied by a real-time clock or GPS 23 | */ 24 | // date 1-Oct-09 25 | uint16_t year = 2009; 26 | uint8_t month = 10; 27 | uint8_t day = 1; 28 | 29 | // time 20:30:40 30 | uint8_t hour = 20; 31 | uint8_t minute = 30; 32 | uint8_t second = 40; 33 | //------------------------------------------------------------------------------ 34 | /* 35 | * User provided date time callback function. 36 | * See SdFile::dateTimeCallback() for usage. 37 | */ 38 | void dateTime(uint16_t* date, uint16_t* time) { 39 | // User gets date and time from GPS or real-time 40 | // clock in real callback function 41 | 42 | // return date using FAT_DATE macro to format fields 43 | *date = FAT_DATE(year, month, day); 44 | 45 | // return time using FAT_TIME macro to format fields 46 | *time = FAT_TIME(hour, minute, second); 47 | } 48 | //------------------------------------------------------------------------------ 49 | /* 50 | * Function to print all timestamps. 51 | */ 52 | void printTimestamps(SdFile& f) { 53 | dir_t d; 54 | if (!f.dirEntry(&d)) error("f.dirEntry failed"); 55 | 56 | cout << pstr("Creation: "); 57 | f.printFatDate(d.creationDate); 58 | cout << ' '; 59 | f.printFatTime(d.creationTime); 60 | cout << endl; 61 | 62 | cout << pstr("Modify: "); 63 | f.printFatDate(d.lastWriteDate); 64 | cout <<' '; 65 | f.printFatTime(d.lastWriteTime); 66 | cout << endl; 67 | 68 | cout << pstr("Access: "); 69 | f.printFatDate(d.lastAccessDate); 70 | cout << endl; 71 | } 72 | //------------------------------------------------------------------------------ 73 | void setup(void) { 74 | Serial.begin(9600); 75 | while (!Serial) {} // wait for Leonardo 76 | 77 | cout << pstr("Type any character to start\n"); 78 | while (!Serial.available()); 79 | delay(400); // catch Due reset problem 80 | 81 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 82 | // breadboards. use SPI_FULL_SPEED for better performance. 83 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 84 | 85 | // remove files if they exist 86 | sd.remove("CALLBACK.TXT"); 87 | sd.remove("DEFAULT.TXT"); 88 | sd.remove("STAMP.TXT"); 89 | 90 | // create a new file with default timestamps 91 | if (!file.open("DEFAULT.TXT", O_CREAT | O_WRITE)) { 92 | error("open DEFAULT.TXT failed"); 93 | } 94 | cout << pstr("\nOpen with default times\n"); 95 | printTimestamps(file); 96 | 97 | // close file 98 | file.close(); 99 | /* 100 | * Test the date time callback function. 101 | * 102 | * dateTimeCallback() sets the function 103 | * that is called when a file is created 104 | * or when a file's directory entry is 105 | * modified by sync(). 106 | * 107 | * The callback can be disabled by the call 108 | * SdFile::dateTimeCallbackCancel() 109 | */ 110 | // set date time callback function 111 | SdFile::dateTimeCallback(dateTime); 112 | 113 | // create a new file with callback timestamps 114 | if (!file.open("CALLBACK.TXT", O_CREAT | O_WRITE)) { 115 | error("open CALLBACK.TXT failed"); 116 | } 117 | cout << ("\nOpen with callback times\n"); 118 | printTimestamps(file); 119 | 120 | // change call back date 121 | day += 1; 122 | 123 | // must add two to see change since FAT second field is 5-bits 124 | second += 2; 125 | 126 | // modify file by writing a byte 127 | file.write('t'); 128 | 129 | // force dir update 130 | file.sync(); 131 | 132 | cout << pstr("\nTimes after write\n"); 133 | printTimestamps(file); 134 | 135 | // close file 136 | file.close(); 137 | /* 138 | * Test timestamp() function 139 | * 140 | * Cancel callback so sync will not 141 | * change access/modify timestamp 142 | */ 143 | SdFile::dateTimeCallbackCancel(); 144 | 145 | // create a new file with default timestamps 146 | if (!file.open("STAMP.TXT", O_CREAT | O_WRITE)) { 147 | error("open STAMP.TXT failed"); 148 | } 149 | // set creation date time 150 | if (!file.timestamp(T_CREATE, 2009, 11, 10, 1, 2, 3)) { 151 | error("set create time failed"); 152 | } 153 | // set write/modification date time 154 | if (!file.timestamp(T_WRITE, 2009, 11, 11, 4, 5, 6)) { 155 | error("set write time failed"); 156 | } 157 | // set access date 158 | if (!file.timestamp(T_ACCESS, 2009, 11, 12, 7, 8, 9)) { 159 | error("set access time failed"); 160 | } 161 | cout << pstr("\nTimes after timestamp() calls\n"); 162 | printTimestamps(file); 163 | 164 | file.close(); 165 | cout << pstr("\nDone\n"); 166 | } 167 | 168 | void loop(void){} -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/TwoCards/TwoCards.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Example use of two SD cards. 3 | */ 4 | #include 5 | #include 6 | #if !USE_MULTIPLE_CARDS 7 | #error You must set USE_MULTIPLE_CARDS nonzero in SdFatConfig.h 8 | #endif 9 | 10 | SdFat sd1; 11 | const uint8_t SD1_CS = 10; // chip select for sd1 12 | 13 | SdFat sd2; 14 | const uint8_t SD2_CS = 9; // chip select for sd2 15 | 16 | const uint8_t BUF_DIM = 100; 17 | uint8_t buf[BUF_DIM]; 18 | 19 | const uint32_t FILE_SIZE = 1000000; 20 | const uint16_t NWRITE = FILE_SIZE/BUF_DIM; 21 | //------------------------------------------------------------------------------ 22 | // print error msg, any SD error codes, and halt. 23 | // store messages in flash 24 | #define errorExit(msg) errorHalt_P(PSTR(msg)) 25 | #define initError(msg) initErrorHalt_P(PSTR(msg)) 26 | //------------------------------------------------------------------------------ 27 | void setup() { 28 | Serial.begin(9600); 29 | while (!Serial) {} // wait for Leonardo 30 | PgmPrint("FreeRam: "); 31 | 32 | Serial.println(FreeRam()); 33 | 34 | // fill buffer with known data 35 | for (int i = 0; i < sizeof(buf); i++) buf[i] = i; 36 | 37 | PgmPrintln("type any character to start"); 38 | while (Serial.read() <= 0) {} 39 | delay(400); // catch Due reset problem 40 | 41 | // disable sd2 while initializing sd1 42 | pinMode(SD2_CS, OUTPUT); 43 | digitalWrite(SD2_CS, HIGH); 44 | 45 | // initialize the first card 46 | if (!sd1.begin(SD1_CS)) { 47 | sd1.initError("sd1:"); 48 | } 49 | // create DIR1 on sd1 if it does not exist 50 | if (!sd1.exists("/DIR1")) { 51 | if (!sd1.mkdir("/DIR1")) sd1.errorExit("sd1.mkdir"); 52 | } 53 | // initialize the second card 54 | if (!sd2.begin(SD2_CS)) { 55 | sd2.initError("sd2:"); 56 | } 57 | // create DIR2 on sd2 if it does not exist 58 | if (!sd2.exists("/DIR2")) { 59 | if (!sd2.mkdir("/DIR2")) sd2.errorExit("sd2.mkdir"); 60 | } 61 | // list root directory on both cards 62 | PgmPrintln("------sd1 root-------"); 63 | sd1.ls(); 64 | PgmPrintln("------sd2 root-------"); 65 | sd2.ls(); 66 | 67 | // make /DIR1 the default directory for sd1 68 | if (!sd1.chdir("/DIR1")) sd1.errorExit("sd1.chdir"); 69 | 70 | // make /DIR2 the default directory for sd2 71 | if (!sd2.chdir("/DIR2")) sd2.errorExit("sd2.chdir"); 72 | 73 | // list current directory on both cards 74 | PgmPrintln("------sd1 DIR1-------"); 75 | sd1.ls(); 76 | PgmPrintln("------sd2 DIR2-------"); 77 | sd2.ls(); 78 | PgmPrintln("---------------------"); 79 | 80 | // remove RENAME.BIN from /DIR2 directory of sd2 81 | if (sd2.exists("RENAME.BIN")) { 82 | if (!sd2.remove("RENAME.BIN")) { 83 | sd2.errorExit("remove RENAME.BIN"); 84 | } 85 | } 86 | // set the current working directory for open() to sd1 87 | sd1.chvol(); 88 | 89 | // create or open /DIR1/TEST.BIN and truncate it to zero length 90 | SdFile file1; 91 | if (!file1.open("TEST.BIN", O_RDWR | O_CREAT | O_TRUNC)) { 92 | sd1.errorExit("file1"); 93 | } 94 | PgmPrintln("Writing TEST.BIN to sd1"); 95 | 96 | // write data to /DIR1/TEST.BIN on sd1 97 | for (int i = 0; i < NWRITE; i++) { 98 | if (file1.write(buf, sizeof(buf)) != sizeof(buf)) { 99 | sd1.errorExit("sd1.write"); 100 | } 101 | } 102 | // set the current working directory for open() to sd2 103 | sd2.chvol(); 104 | 105 | // create or open /DIR2/COPY.BIN and truncate it to zero length 106 | SdFile file2; 107 | if (!file2.open("COPY.BIN", O_WRITE | O_CREAT | O_TRUNC)) { 108 | sd2.errorExit("file2"); 109 | } 110 | PgmPrintln("Copying TEST.BIN to COPY.BIN"); 111 | 112 | // copy file1 to file2 113 | file1.rewind(); 114 | uint32_t t = millis(); 115 | 116 | while (1) { 117 | int n = file1.read(buf, sizeof(buf)); 118 | if (n < 0) sd1.errorExit("read1"); 119 | if (n == 0) break; 120 | if (file2.write(buf, n) != n) sd2.errorExit("write2"); 121 | } 122 | t = millis() - t; 123 | PgmPrint("File size: "); 124 | Serial.println(file2.fileSize()); 125 | PgmPrint("Copy time: "); 126 | Serial.print(t); 127 | PgmPrintln(" millis"); 128 | 129 | // close TEST.BIN 130 | file1.close(); 131 | 132 | // rename the copy 133 | file2.close(); 134 | if (!sd2.rename("COPY.BIN", "RENAME.BIN")) { 135 | sd2.errorExit("sd2.rename"); 136 | } 137 | PgmPrintln("Done"); 138 | } 139 | //------------------------------------------------------------------------------ 140 | void loop() {} 141 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/append/append.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Append Example 3 | * 4 | * This sketch shows how to use open for append. 5 | * The sketch will append 100 line each time it opens the file. 6 | * The sketch will open and close the file 100 times. 7 | */ 8 | #include 9 | 10 | // SD chip select pin 11 | const uint8_t chipSelect = SS; 12 | 13 | // file system object 14 | SdFat sd; 15 | 16 | // create Serial stream 17 | ArduinoOutStream cout(Serial); 18 | 19 | // store error strings in flash to save RAM 20 | #define error(s) sd.errorHalt_P(PSTR(s)) 21 | //------------------------------------------------------------------------------ 22 | void setup() { 23 | // filename for this example 24 | char name[] = "APPEND.TXT"; 25 | 26 | Serial.begin(9600); 27 | while (!Serial) {} // wait for Leonardo 28 | 29 | // pstr() stores strings in flash to save RAM 30 | cout << endl << pstr("Type any character to start\n"); 31 | while (Serial.read() <= 0) {} 32 | delay(400); // Catch Due reset problem 33 | 34 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 35 | // breadboards. use SPI_FULL_SPEED for better performance. 36 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 37 | 38 | cout << pstr("Appending to: ") << name; 39 | 40 | for (uint8_t i = 0; i < 100; i++) { 41 | // open stream for append 42 | ofstream sdout(name, ios::out | ios::app); 43 | if (!sdout) error("open failed"); 44 | 45 | // append 100 lines to the file 46 | for (uint8_t j = 0; j < 100; j++) { 47 | // use int() so byte will print as decimal number 48 | sdout << "line " << int(j) << " of pass " << int(i); 49 | sdout << " millis = " << millis() << endl; 50 | } 51 | // close the stream 52 | sdout.close(); 53 | 54 | if (!sdout) error("append data failed"); 55 | 56 | // output progress indicator 57 | if (i % 25 == 0) cout << endl; 58 | cout << '.'; 59 | } 60 | cout << endl << "Done" << endl; 61 | } 62 | //------------------------------------------------------------------------------ 63 | void loop() {} 64 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/average/average.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Calculate the sum and average of a list of floating point numbers 3 | */ 4 | #include 5 | 6 | // SD chip select pin 7 | const uint8_t chipSelect = SS; 8 | 9 | // object for the SD file system 10 | SdFat sd; 11 | 12 | // define a serial output stream 13 | ArduinoOutStream cout(Serial); 14 | //------------------------------------------------------------------------------ 15 | void writeTestFile() { 16 | // open the output file 17 | ofstream sdout("AVG_TEST.TXT"); 18 | 19 | // write a series of float numbers 20 | for (int16_t i = -1001; i < 2000; i += 13) { 21 | sdout << 0.1 * i << endl; 22 | } 23 | if (!sdout) sd.errorHalt("sdout failed"); 24 | 25 | sdout.close(); 26 | } 27 | //------------------------------------------------------------------------------ 28 | void calcAverage() { 29 | uint16_t n = 0; // count of input numbers 30 | double num; // current input number 31 | double sum = 0; // sum of input numbers 32 | 33 | // open the input file 34 | ifstream sdin("AVG_TEST.TXT"); 35 | 36 | // check for an open failure 37 | if (!sdin) sd.errorHalt("sdin failed"); 38 | 39 | // read and sum the numbers 40 | while (sdin >> num) { 41 | n++; 42 | sum += num; 43 | } 44 | 45 | // print the results 46 | cout << "sum of " << n << " numbers = " << sum << endl; 47 | cout << "average = " << sum/n << endl; 48 | } 49 | //------------------------------------------------------------------------------ 50 | void setup() { 51 | Serial.begin(9600); 52 | while (!Serial) {} // wait for Leonardo 53 | 54 | // pstr stores strings in flash to save RAM 55 | cout << pstr("Type any character to start\n"); 56 | while (Serial.read() <= 0) {} 57 | delay(400); // Catch Due reset problem 58 | 59 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 60 | // breadboards. use SPI_FULL_SPEED for better performance. 61 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 62 | 63 | // write the test file 64 | writeTestFile(); 65 | 66 | // read the test file and calculate the average 67 | calcAverage(); 68 | } 69 | //------------------------------------------------------------------------------ 70 | void loop() {} 71 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/bench/bench.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch is a simple binary write/read benchmark. 3 | */ 4 | #include 5 | #include 6 | 7 | // SD chip select pin 8 | const uint8_t chipSelect = SS; 9 | 10 | #define FILE_SIZE_MB 5 11 | #define FILE_SIZE (1000000UL*FILE_SIZE_MB) 12 | #define BUF_SIZE 100 13 | 14 | uint8_t buf[BUF_SIZE]; 15 | 16 | // file system 17 | SdFat sd; 18 | 19 | // test file 20 | SdFile file; 21 | 22 | // Serial output stream 23 | ArduinoOutStream cout(Serial); 24 | //------------------------------------------------------------------------------ 25 | // store error strings in flash to save RAM 26 | #define error(s) sd.errorHalt_P(PSTR(s)) 27 | //------------------------------------------------------------------------------ 28 | void setup() { 29 | Serial.begin(9600); 30 | while (!Serial){} // wait for Leonardo 31 | cout << pstr("\nUse a freshly formatted SD for best performance.\n"); 32 | } 33 | //------------------------------------------------------------------------------ 34 | void loop() { 35 | uint32_t maxLatency; 36 | uint32_t minLatency; 37 | uint32_t totalLatency; 38 | 39 | // discard any input 40 | while (Serial.read() >= 0) {} 41 | 42 | // pstr stores strings in flash to save RAM 43 | cout << pstr("Type any character to start\n"); 44 | while (Serial.read() <= 0) {} 45 | delay(400); // catch Due reset problem 46 | 47 | cout << pstr("Free RAM: ") << FreeRam() << endl; 48 | 49 | // initialize the SD card at SPI_FULL_SPEED for best performance. 50 | // try SPI_HALF_SPEED if bus errors occur. 51 | if (!sd.begin(chipSelect, SPI_FULL_SPEED)) sd.initErrorHalt(); 52 | 53 | cout << pstr("Type is FAT") << int(sd.vol()->fatType()) << endl; 54 | 55 | // open or create file - truncate existing file. 56 | if (!file.open("BENCH.DAT", O_CREAT | O_TRUNC | O_RDWR)) { 57 | error("open failed"); 58 | } 59 | 60 | // fill buf with known data 61 | for (uint16_t i = 0; i < (BUF_SIZE-2); i++) { 62 | buf[i] = 'A' + (i % 26); 63 | } 64 | buf[BUF_SIZE-2] = '\r'; 65 | buf[BUF_SIZE-1] = '\n'; 66 | 67 | cout << pstr("File size ") << FILE_SIZE_MB << pstr("MB\n"); 68 | cout << pstr("Buffer size ") << BUF_SIZE << pstr(" bytes\n"); 69 | cout << pstr("Starting write test. Please wait up to a minute\n"); 70 | 71 | // do write test 72 | uint32_t n = FILE_SIZE/sizeof(buf); 73 | maxLatency = 0; 74 | minLatency = 9999999; 75 | totalLatency = 0; 76 | uint32_t t = millis(); 77 | for (uint32_t i = 0; i < n; i++) { 78 | uint32_t m = micros(); 79 | if (file.write(buf, sizeof(buf)) != sizeof(buf)) { 80 | error("write failed"); 81 | } 82 | m = micros() - m; 83 | if (maxLatency < m) maxLatency = m; 84 | if (minLatency > m) minLatency = m; 85 | totalLatency += m; 86 | } 87 | file.sync(); 88 | t = millis() - t; 89 | double s = file.fileSize(); 90 | cout << pstr("Write ") << s/t << pstr(" KB/sec\n"); 91 | cout << pstr("Maximum latency: ") << maxLatency; 92 | cout << pstr(" usec, Minimum Latency: ") << minLatency; 93 | cout << pstr(" usec, Avg Latency: ") << totalLatency/n << pstr(" usec\n\n"); 94 | cout << pstr("Starting read test. Please wait up to a minute\n"); 95 | // do read test 96 | file.rewind(); 97 | maxLatency = 0; 98 | minLatency = 9999999; 99 | totalLatency = 0; 100 | t = millis(); 101 | for (uint32_t i = 0; i < n; i++) { 102 | buf[BUF_SIZE-1] = 0; 103 | uint32_t m = micros(); 104 | if (file.read(buf, sizeof(buf)) != sizeof(buf)) { 105 | error("read failed"); 106 | } 107 | m = micros() - m; 108 | if (maxLatency < m) maxLatency = m; 109 | if (minLatency > m) minLatency = m; 110 | totalLatency += m; 111 | if (buf[BUF_SIZE-1] != '\n') { 112 | error("data check"); 113 | } 114 | } 115 | t = millis() - t; 116 | cout << pstr("Read ") << s/t << pstr(" KB/sec\n"); 117 | cout << pstr("Maximum latency: ") << maxLatency; 118 | cout << pstr(" usec, Minimum Latency: ") << minLatency; 119 | cout << pstr(" usec, Avg Latency: ") << totalLatency/n << pstr(" usec\n\n"); 120 | cout << pstr("Done\n\n"); 121 | file.close(); 122 | } -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/benchSD/benchSD.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch is a simple binary write/read benchmark 3 | * for the standard Arduino SD.h library. 4 | */ 5 | #include 6 | #include 7 | 8 | 9 | // SD chip select pin 10 | const uint8_t chipSelect = SS; 11 | 12 | #define FILE_SIZE_MB 5 13 | #define FILE_SIZE (1000000UL*FILE_SIZE_MB) 14 | #define BUF_SIZE 100 15 | 16 | uint8_t buf[BUF_SIZE]; 17 | 18 | 19 | // test file 20 | File file; 21 | 22 | //------------------------------------------------------------------------------ 23 | // store error strings in flash to save RAM 24 | void error(char* s) { 25 | Serial.println(s); 26 | while(1); 27 | } 28 | //------------------------------------------------------------------------------ 29 | void setup() { 30 | Serial.begin(9600); 31 | while (!Serial){} // wait for Leonardo 32 | } 33 | //------------------------------------------------------------------------------ 34 | void loop() { 35 | uint32_t maxLatency; 36 | uint32_t minLatency; 37 | uint32_t totalLatency; 38 | 39 | // discard any input 40 | while (Serial.read() >= 0) {} 41 | 42 | // pstr stores strings in flash to save RAM 43 | Serial.println(F("Type any character to start")); 44 | while (Serial.read() <= 0) {} 45 | delay(400); // catch Due reset problem 46 | 47 | if (!SD.begin(chipSelect)) error("begin"); 48 | 49 | // open or create file - truncate existing file. 50 | file = SD.open("BENCH.DAT", FILE_WRITE | O_TRUNC); 51 | // file = SD.open("BENCH.DAT", O_CREAT | O_TRUNC | O_CREAT); 52 | if (!file) { 53 | error("open failed"); 54 | } 55 | 56 | // fill buf with known data 57 | for (uint16_t i = 0; i < (BUF_SIZE-2); i++) { 58 | buf[i] = 'A' + (i % 26); 59 | } 60 | buf[BUF_SIZE-2] = '\r'; 61 | buf[BUF_SIZE-1] = '\n'; 62 | 63 | Serial.print(F("File size ")); 64 | Serial.print(FILE_SIZE_MB); 65 | Serial.println(F("MB")); 66 | Serial.print(F("Buffer size ")); 67 | Serial.print(BUF_SIZE); 68 | Serial.println(F(" bytes")); 69 | Serial.println(F("Starting write test. Please wait up to a minute")); 70 | 71 | // do write test 72 | uint32_t n = FILE_SIZE/sizeof(buf); 73 | maxLatency = 0; 74 | minLatency = 999999; 75 | totalLatency = 0; 76 | uint32_t t = millis(); 77 | for (uint32_t i = 0; i < n; i++) { 78 | uint32_t m = micros(); 79 | if (file.write(buf, sizeof(buf)) != sizeof(buf)) { 80 | error("write failed"); 81 | } 82 | m = micros() - m; 83 | if (maxLatency < m) maxLatency = m; 84 | if (minLatency > m) minLatency = m; 85 | totalLatency += m; 86 | } 87 | file.flush(); 88 | t = millis() - t; 89 | double s = file.size(); 90 | Serial.print(F("Write ")); 91 | Serial.print(s/t); 92 | Serial.print(F(" KB/sec\n")); 93 | Serial.print(F("Maximum latency: ")); 94 | Serial.print(maxLatency); 95 | Serial.print(F(" usec, Minimum Latency: ")); 96 | Serial.print(minLatency); 97 | Serial.print(F(" usec, Avg Latency: ")); 98 | Serial.print(totalLatency/n); 99 | Serial.print(F(" usec\n\n")); 100 | Serial.println(F("Starting read test. Please wait up to a minute")); 101 | // do read test 102 | file.seek(0); 103 | maxLatency = 0; 104 | minLatency = 99999; 105 | totalLatency = 0; 106 | t = millis(); 107 | for (uint32_t i = 0; i < n; i++) { 108 | buf[BUF_SIZE-1] = 0; 109 | uint32_t m = micros(); 110 | if (file.read(buf, sizeof(buf)) != sizeof(buf)) { 111 | error("read failed"); 112 | } 113 | m = micros() - m; 114 | if (maxLatency < m) maxLatency = m; 115 | if (minLatency > m) minLatency = m; 116 | totalLatency += m; 117 | if (buf[BUF_SIZE-1] != '\n') { 118 | error("data check"); 119 | } 120 | } 121 | t = millis() - t; 122 | Serial.print(F("Read ")); 123 | Serial.print(s/t); 124 | Serial.print(F(" KB/sec\n")); 125 | Serial.print(F("Maximum latency: ")); 126 | Serial.print(maxLatency); 127 | Serial.print(F(" usec, Minimum Latency: ")); 128 | Serial.print(minLatency); 129 | Serial.print(F(" usec, Avg Latency: ")); 130 | Serial.print(totalLatency/n); 131 | Serial.print(F(" usec\n\n")); 132 | Serial.print(F("Done\n\n")); 133 | file.close(); 134 | } -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/bufstream/bufstream.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Use of ibufsteam to parse a line and obufstream to format a line 3 | */ 4 | #include 5 | 6 | // create a serial output stream 7 | ArduinoOutStream cout(Serial); 8 | //------------------------------------------------------------------------------ 9 | void setup() { 10 | char buf[20]; // buffer for formatted line 11 | int i, j, k; // values from parsed line 12 | 13 | Serial.begin(9600); 14 | while (!Serial) {} // wait for Leonardo 15 | delay(2000); 16 | 17 | // initialize input string 18 | ibufstream bin("123 456 789"); 19 | 20 | // parse the string "123 456 789" 21 | bin >> i >> j >> k; 22 | 23 | // initialize output buffer 24 | obufstream bout(buf, sizeof(buf)); 25 | 26 | // format the output string 27 | bout << k << ',' << j << ',' << i << endl; 28 | 29 | // write the string to serial 30 | cout << buf; 31 | } 32 | 33 | void loop() {} 34 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/cin_cout/cin_cout.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Demo of ArduinoInStream and ArduinoOutStream 3 | */ 4 | #include 5 | 6 | // create serial output stream 7 | ArduinoOutStream cout(Serial); 8 | 9 | // input buffer for line 10 | char cinBuf[40]; 11 | 12 | // create serial input stream 13 | ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); 14 | //------------------------------------------------------------------------------ 15 | void setup() { 16 | Serial.begin(9600); 17 | while (!Serial) {} // wait for Leonardo 18 | } 19 | //------------------------------------------------------------------------------ 20 | void loop() { 21 | int32_t n; 22 | 23 | cout << "\nenter an integer\n"; 24 | 25 | cin.readline(); 26 | 27 | if (cin >> n) { 28 | cout << "The number is: " << n; 29 | } else { 30 | // will fail if no digits or not in range [-2147483648, 2147483647] 31 | cout << "Invalid input: " << cinBuf; 32 | } 33 | cout << endl; 34 | } 35 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/eventlog/eventlog.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Append a line to a file - demo of pathnames and streams 3 | */ 4 | #include 5 | 6 | // SD chip select pin 7 | const uint8_t chipSelect = SS; 8 | 9 | // file system object 10 | SdFat sd; 11 | 12 | // define a serial output stream 13 | ArduinoOutStream cout(Serial); 14 | //------------------------------------------------------------------------------ 15 | /* 16 | * Append a line to LOGFILE.TXT 17 | */ 18 | void logEvent(const char *msg) { 19 | // create dir if needed 20 | sd.mkdir("LOGS/2011/JAN"); 21 | 22 | // create or open a file for append 23 | ofstream sdlog("LOGS/2011/JAN/LOGFILE.TXT", ios::out | ios::app); 24 | 25 | // append a line to the file 26 | sdlog << msg << endl; 27 | 28 | // check for errors 29 | if (!sdlog) sd.errorHalt("append failed"); 30 | 31 | sdlog.close(); 32 | } 33 | //------------------------------------------------------------------------------ 34 | void setup() { 35 | Serial.begin(9600); 36 | while (!Serial) {} // wait for Leonardo 37 | 38 | // pstr stores strings in flash to save RAM 39 | cout << pstr("Type any character to start\n"); 40 | while (Serial.read() <= 0) {} 41 | delay(400); // catch Due reset problem 42 | 43 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 44 | // breadboards. use SPI_FULL_SPEED for better performance. 45 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 46 | 47 | // append a line to the logfile 48 | logEvent("Another line for the logfile"); 49 | 50 | cout << "Done - check /LOGS/2011/JAN/LOGFILE.TXT on the SD" << endl; 51 | } 52 | //------------------------------------------------------------------------------ 53 | void loop() {} 54 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/fgets/fgets.ino: -------------------------------------------------------------------------------- 1 | // Demo of fgets function to read lines from a file. 2 | #include 3 | 4 | // SD chip select pin 5 | const uint8_t chipSelect = SS; 6 | 7 | SdFat sd; 8 | // print stream 9 | ArduinoOutStream cout(Serial); 10 | //------------------------------------------------------------------------------ 11 | // store error strings in flash memory 12 | #define error(s) sd.errorHalt_P(PSTR(s)) 13 | //------------------------------------------------------------------------------ 14 | void demoFgets() { 15 | char line[25]; 16 | int n; 17 | // open test file 18 | SdFile rdfile("FGETS.TXT", O_READ); 19 | 20 | // check for open error 21 | if (!rdfile.isOpen()) error("demoFgets"); 22 | 23 | cout << endl << pstr( 24 | "Lines with '>' end with a '\\n' character\n" 25 | "Lines with '#' do not end with a '\\n' character\n" 26 | "\n"); 27 | 28 | // read lines from the file 29 | while ((n = rdfile.fgets(line, sizeof(line))) > 0) { 30 | if (line[n - 1] == '\n') { 31 | cout << '>' << line; 32 | } else { 33 | cout << '#' << line << endl; 34 | } 35 | } 36 | } 37 | //------------------------------------------------------------------------------ 38 | void makeTestFile() { 39 | // create or open test file 40 | SdFile wrfile("FGETS.TXT", O_WRITE | O_CREAT | O_TRUNC); 41 | 42 | // check for open error 43 | if (!wrfile.isOpen()) error("MakeTestFile"); 44 | 45 | // write test file 46 | wrfile.write_P(PSTR( 47 | "Line with CRLF\r\n" 48 | "Line with only LF\n" 49 | "Long line that will require an extra read\n" 50 | "\n" // empty line 51 | "Line at EOF without NL" 52 | )); 53 | wrfile.close(); 54 | } 55 | //------------------------------------------------------------------------------ 56 | void setup(void) { 57 | Serial.begin(9600); 58 | while (!Serial) {} // Wait for Leonardo 59 | 60 | cout << pstr("Type any character to start\n"); 61 | while (Serial.read() <= 0) {} 62 | delay(400); // catch Due reset problem 63 | 64 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 65 | // breadboards. use SPI_FULL_SPEED for better performance. 66 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 67 | 68 | makeTestFile(); 69 | 70 | demoFgets(); 71 | 72 | cout << pstr("\nDone\n"); 73 | } 74 | void loop(void) {} 75 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/fgetsRewrite/fgetsRewrite.ino: -------------------------------------------------------------------------------- 1 | // Demo of rewriting a line read by fgets 2 | #include 3 | 4 | // SD card chip select pin 5 | const uint8_t chipSelect = SS; 6 | 7 | // file system 8 | SdFat sd; 9 | 10 | // print stream 11 | ArduinoOutStream cout(Serial); 12 | //------------------------------------------------------------------------------ 13 | // store error strings in flash memory 14 | #define error(s) sd.errorHalt_P(PSTR(s)) 15 | //------------------------------------------------------------------------------ 16 | void demoFgets() { 17 | char line[25]; 18 | int c; 19 | uint32_t pos; 20 | 21 | // open test file 22 | SdFile rdfile("FGETS.TXT", O_RDWR); 23 | 24 | // check for open error 25 | if (!rdfile.isOpen()) error("demoFgets"); 26 | 27 | // list file 28 | cout << pstr("-----Before Rewrite\r\n"); 29 | while ((c = rdfile.read()) >= 0) Serial.write(c); 30 | 31 | rdfile.rewind(); 32 | // read lines from the file to get position 33 | while (1) { 34 | pos = rdfile.curPosition(); 35 | if (rdfile.fgets(line, sizeof(line)) < 0) { 36 | error("Line not found"); 37 | } 38 | // find line that contains "Line C" 39 | if (strstr(line, "Line C"))break; 40 | } 41 | 42 | // rewrite line with 'C' 43 | if (!rdfile.seekSet(pos))error("seekSet"); 44 | rdfile.println("Line R"); 45 | rdfile.rewind(); 46 | 47 | // list file 48 | cout << pstr("\r\n-----After Rewrite\r\n"); 49 | while ((c = rdfile.read()) >= 0) Serial.write(c); 50 | 51 | // close so rewrite is not lost 52 | rdfile.close(); 53 | } 54 | //------------------------------------------------------------------------------ 55 | void makeTestFile() { 56 | // create or open test file 57 | SdFile wrfile("FGETS.TXT", O_WRITE | O_CREAT | O_TRUNC); 58 | 59 | // check for open error 60 | if (!wrfile.isOpen()) error("MakeTestFile"); 61 | 62 | // write test file 63 | wrfile.write_P(PSTR( 64 | "Line A\r\n" 65 | "Line B\r\n" 66 | "Line C\r\n" 67 | "Line D\r\n" 68 | "Line E\r\n" 69 | )); 70 | wrfile.close(); 71 | } 72 | //------------------------------------------------------------------------------ 73 | void setup(void) { 74 | Serial.begin(9600); 75 | while (!Serial){} // wait for Leonardo 76 | 77 | cout << pstr("Type any character to start\n"); 78 | while (Serial.read() <= 0) {} 79 | delay(400); // catch Due reset problem 80 | 81 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 82 | // breadboards. use SPI_FULL_SPEED for better performance. 83 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 84 | 85 | makeTestFile(); 86 | 87 | demoFgets(); 88 | 89 | cout << pstr("\nDone\n"); 90 | } 91 | void loop(void) {} 92 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/formatting/formatting.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Print a table with various formatting options 3 | * Format dates 4 | */ 5 | #include 6 | 7 | // create Serial stream 8 | ArduinoOutStream cout(Serial); 9 | //------------------------------------------------------------------------------ 10 | // print a table to demonstrate format manipulators 11 | void example(void) { 12 | const int max = 10; 13 | const int width = 4; 14 | 15 | for (int row = 1; row <= max; row++) { 16 | for (int col = 1; col <= max; col++) { 17 | cout << setw(width) << row * col << (col == max ? '\n' : ' '); 18 | } 19 | } 20 | cout << endl; 21 | } 22 | //------------------------------------------------------------------------------ 23 | // print a date as mm/dd/yyyy with zero fill in mm and dd 24 | // shows how to set and restore the fill character 25 | void showDate(int m, int d, int y) { 26 | // convert two digit year 27 | if (y < 100) y += 2000; 28 | 29 | // set new fill to '0' save old fill character 30 | char old = cout.fill('0'); 31 | 32 | // print date 33 | cout << setw(2) << m << '/' << setw(2) << d << '/' << y << endl; 34 | 35 | // restore old fill character 36 | cout.fill(old); 37 | } 38 | //------------------------------------------------------------------------------ 39 | void setup(void) { 40 | Serial.begin(9600); 41 | 42 | while (!Serial) {} // wait for Leonardo 43 | delay(2000); 44 | 45 | cout << endl << "default formatting" << endl; 46 | example(); 47 | 48 | cout << showpos << "showpos" << endl; 49 | example(); 50 | 51 | cout << hex << left << showbase << "hex left showbase" << endl; 52 | example(); 53 | 54 | cout << internal << setfill('0') << uppercase; 55 | cout << "uppercase hex internal showbase fill('0')" < 10 | 11 | // SD chip select pin 12 | const uint8_t chipSelect = SS; 13 | 14 | // file system object 15 | SdFat sd; 16 | 17 | // create a serial stream 18 | ArduinoOutStream cout(Serial); 19 | //------------------------------------------------------------------------------ 20 | void makeTestFile() { 21 | ofstream sdout("GETLINE.TXT"); 22 | // use flash for text to save RAM 23 | sdout << pstr( 24 | "short line\n" 25 | "\n" 26 | "17 character line\n" 27 | "too long for buffer\n" 28 | "line with no nl"); 29 | 30 | sdout.close(); 31 | } 32 | //------------------------------------------------------------------------------ 33 | void testGetline() { 34 | const int line_buffer_size = 18; 35 | char buffer[line_buffer_size]; 36 | ifstream sdin("GETLINE.TXT"); 37 | int line_number = 0; 38 | 39 | while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) { 40 | int count = sdin.gcount(); 41 | if (sdin.fail()) { 42 | cout << "Partial long line"; 43 | sdin.clear(sdin.rdstate() & ~ios_base::failbit); 44 | } else if (sdin.eof()) { 45 | cout << "Partial final line"; // sdin.fail() is false 46 | } else { 47 | count--; // Don’t include newline in count 48 | cout << "Line " << ++line_number; 49 | } 50 | cout << " (" << count << " chars): " << buffer << endl; 51 | } 52 | } 53 | //------------------------------------------------------------------------------ 54 | void setup(void) { 55 | Serial.begin(9600); 56 | while (!Serial) {} // wait for Leonardo 57 | 58 | // pstr stores strings in flash to save RAM 59 | cout << pstr("Type any character to start\n"); 60 | while (Serial.read() <= 0) {} 61 | delay(400); // catch Due reset problem 62 | 63 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 64 | // breadboards. use SPI_FULL_SPEED for better performance. 65 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 66 | 67 | // make the test file 68 | makeTestFile(); 69 | 70 | // run the example 71 | testGetline(); 72 | cout << "\nDone!\n"; 73 | } 74 | //------------------------------------------------------------------------------ 75 | void loop(void) {} 76 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/readCSV/readCSV.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This example reads a simple CSV, comma-separated values, file. 3 | * Each line of the file has three values, a long and two floats. 4 | */ 5 | #include 6 | 7 | // SD chip select pin 8 | const uint8_t chipSelect = SS; 9 | 10 | // file system object 11 | SdFat sd; 12 | 13 | // create Serial stream 14 | ArduinoOutStream cout(Serial); 15 | 16 | char fileName[] = "3V_FILE.CSV"; 17 | //------------------------------------------------------------------------------ 18 | // store error strings in flash to save RAM 19 | #define error(s) sd.errorHalt_P(PSTR(s)) 20 | //------------------------------------------------------------------------------ 21 | // read and print CSV test file 22 | void readFile() { 23 | long lg; 24 | float f1, f2; 25 | char c1, c2; 26 | 27 | // open input file 28 | ifstream sdin(fileName); 29 | 30 | // check for open error 31 | if (!sdin.is_open()) error("open"); 32 | 33 | // read until input fails 34 | while (sdin >> lg >> c1 >> f1 >> c2 >> f2) { 35 | 36 | // error in line if not commas 37 | if (c1 != ',' || c2 != ',') error("comma"); 38 | 39 | // print in six character wide columns 40 | cout << setw(6) << lg << setw(6) << f1 << setw(6) << f2 << endl; 41 | } 42 | // Error in an input line if file is not at EOF. 43 | if (!sdin.eof()) error("readFile"); 44 | } 45 | //------------------------------------------------------------------------------ 46 | // write test file 47 | void writeFile() { 48 | 49 | // create or open and truncate output file 50 | ofstream sdout(fileName); 51 | 52 | // write file from string stored in flash 53 | sdout << pstr( 54 | "1,2.3,4.5\n" 55 | "6,7.8,9.0\n" 56 | "9,8.7,6.5\n" 57 | "-4,-3.2,-1\n") << flush; 58 | 59 | // check for any errors 60 | if (!sdout) error("writeFile"); 61 | 62 | sdout.close(); 63 | } 64 | //------------------------------------------------------------------------------ 65 | void setup() { 66 | Serial.begin(9600); 67 | while (!Serial) {} // wait for Leonardo 68 | cout << pstr("Type any character to start\n"); 69 | while (Serial.read() <= 0) {} 70 | delay(400); // catch Due reset problem 71 | 72 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 73 | // breadboards. use SPI_FULL_SPEED for better performance 74 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 75 | 76 | // create test file 77 | writeFile(); 78 | 79 | cout << endl; 80 | 81 | // read and print test 82 | readFile(); 83 | 84 | cout << "\nDone!" << endl; 85 | } 86 | void loop() {} 87 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/readlog/readlog.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Read the logfile created by the eventlog.pde example. 3 | * Demo of pathnames and working directories 4 | */ 5 | #include 6 | 7 | // SD chip select pin 8 | const uint8_t chipSelect = SS; 9 | 10 | // file system object 11 | SdFat sd; 12 | 13 | // define a serial output stream 14 | ArduinoOutStream cout(Serial); 15 | //------------------------------------------------------------------------------ 16 | void setup() { 17 | int c; 18 | Serial.begin(9600); 19 | while (!Serial) {} // wait for Leonardo 20 | 21 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 22 | // breadboards. use SPI_FULL_SPEED for better performance. 23 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 24 | 25 | // set current working directory 26 | if (!sd.chdir("LOGS/2011/JAN/")) { 27 | sd.errorHalt("chdir failed. Did you run eventlog.pde?"); 28 | } 29 | // open file in current working directory 30 | ifstream file("LOGFILE.TXT"); 31 | 32 | if (!file.is_open()) sd.errorHalt("open failed"); 33 | 34 | // copy the file to Serial 35 | while ((c = file.get()) >= 0) cout << (char)c; 36 | 37 | cout << "Done" << endl; 38 | } 39 | //------------------------------------------------------------------------------ 40 | void loop() {} -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/examples/rename/rename.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch demonstrates use of SdFile::rename() 3 | * and SdFat::rename(). 4 | */ 5 | #include 6 | 7 | // SD chip select pin 8 | const uint8_t chipSelect = SS; 9 | 10 | // file system 11 | SdFat sd; 12 | 13 | // Serial print stream 14 | ArduinoOutStream cout(Serial); 15 | //------------------------------------------------------------------------------ 16 | // store error strings in flash to save RAM 17 | #define error(s) sd.errorHalt_P(PSTR(s)) 18 | //------------------------------------------------------------------------------ 19 | void setup() { 20 | Serial.begin(9600); 21 | while (!Serial) {} // wait for Leonardo 22 | 23 | cout << pstr("Insert an empty SD. Type any character to start.") << endl; 24 | while (Serial.read() <= 0) {} 25 | delay(400); // catch Due reset problem 26 | 27 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 28 | // breadboards. use SPI_FULL_SPEED for better performance. 29 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); 30 | 31 | // create a file and write one line to the file 32 | SdFile file("NAME1.TXT", O_WRITE | O_CREAT); 33 | if (!file.isOpen()) error("NAME1"); 34 | file.println("A test line for NAME1.TXT"); 35 | 36 | // rename the file NAME2.TXT and add a line. 37 | // sd.vwd() is the volume working directory, root. 38 | if (!file.rename(sd.vwd(), "NAME2.TXT")) error("NAME2"); 39 | file.println("A test line for NAME2.TXT"); 40 | 41 | // list files 42 | cout << pstr("------") << endl; 43 | sd.ls(LS_R); 44 | 45 | // make a new directory - "DIR1" 46 | if (!sd.mkdir("DIR1")) error("DIR1"); 47 | 48 | // move file into DIR1, rename it NAME3.TXT and add a line 49 | if (!file.rename(sd.vwd(), "DIR1/NAME3.TXT")) error("NAME3"); 50 | file.println("A line for DIR1/NAME3.TXT"); 51 | 52 | // list files 53 | cout << pstr("------") << endl; 54 | sd.ls(LS_R); 55 | 56 | // make directory "DIR2" 57 | if (!sd.mkdir("DIR2")) error("DIR2"); 58 | 59 | // close file before rename(oldPath, newPath) 60 | file.close(); 61 | 62 | // move DIR1 into DIR2 and rename it DIR3 63 | if (!sd.rename("DIR1", "DIR2/DIR3")) error("DIR2/DIR3"); 64 | 65 | // open file for append in new location and add a line 66 | if (!file.open("DIR2/DIR3/NAME3.TXT", O_WRITE | O_APPEND)) { 67 | error("DIR2/DIR3/NAME3.TXT"); 68 | } 69 | file.println("A line for DIR2/DIR3/NAME3.TXT"); 70 | 71 | // list files 72 | cout << pstr("------") << endl; 73 | sd.ls(LS_R); 74 | 75 | cout << pstr("Done") << endl; 76 | } 77 | void loop() {} 78 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/iostream.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef iostream_h 21 | #define iostream_h 22 | /** 23 | * \file 24 | * \brief \ref iostream class 25 | */ 26 | #include 27 | #include 28 | /** Skip white space 29 | * \param[in] is the Stream 30 | * \return The stream 31 | */ 32 | inline istream& ws(istream& is) { 33 | is.skipWhite(); 34 | return is; 35 | } 36 | /** insert endline 37 | * \param[in] os The Stream 38 | * \return The stream 39 | */ 40 | inline ostream& endl(ostream& os) { 41 | os.put('\n'); 42 | #if ENDL_CALLS_FLUSH 43 | os.flush(); 44 | #endif // ENDL_CALLS_FLUSH 45 | return os; 46 | } 47 | /** flush manipulator 48 | * \param[in] os The stream 49 | * \return The stream 50 | */ 51 | inline ostream& flush(ostream& os) { 52 | os.flush(); 53 | return os; 54 | } 55 | /** 56 | * \struct setfill 57 | * \brief type for setfill manipulator 58 | */ 59 | struct setfill { 60 | /** fill character */ 61 | char c; 62 | /** constructor 63 | * 64 | * \param[in] arg new fill character 65 | */ 66 | explicit setfill(char arg) : c(arg) {} 67 | }; 68 | /** setfill manipulator 69 | * \param[in] os the stream 70 | * \param[in] arg set setfill object 71 | * \return the stream 72 | */ 73 | inline ostream &operator<< (ostream &os, const setfill &arg) { 74 | os.fill(arg.c); 75 | return os; 76 | } 77 | /** setfill manipulator 78 | * \param[in] obj the stream 79 | * \param[in] arg set setfill object 80 | * \return the stream 81 | */ 82 | inline istream &operator>>(istream &obj, const setfill &arg) { 83 | obj.fill(arg.c); 84 | return obj; 85 | } 86 | //------------------------------------------------------------------------------ 87 | /** \struct setprecision 88 | * \brief type for setprecision manipulator 89 | */ 90 | struct setprecision { 91 | /** precision */ 92 | unsigned int p; 93 | /** constructor 94 | * \param[in] arg new precision 95 | */ 96 | explicit setprecision(unsigned int arg) : p(arg) {} 97 | }; 98 | /** setprecision manipulator 99 | * \param[in] os the stream 100 | * \param[in] arg set setprecision object 101 | * \return the stream 102 | */ 103 | inline ostream &operator<< (ostream &os, const setprecision &arg) { 104 | os.precision(arg.p); 105 | return os; 106 | } 107 | /** setprecision manipulator 108 | * \param[in] is the stream 109 | * \param[in] arg set setprecision object 110 | * \return the stream 111 | */ 112 | inline istream &operator>>(istream &is, const setprecision &arg) { 113 | is.precision(arg.p); 114 | return is; 115 | } 116 | //------------------------------------------------------------------------------ 117 | /** \struct setw 118 | * \brief type for setw manipulator 119 | */ 120 | struct setw { 121 | /** width */ 122 | unsigned w; 123 | /** constructor 124 | * \param[in] arg new width 125 | */ 126 | explicit setw(unsigned arg) : w(arg) {} 127 | }; 128 | /** setw manipulator 129 | * \param[in] os the stream 130 | * \param[in] arg set setw object 131 | * \return the stream 132 | */ 133 | inline ostream &operator<< (ostream &os, const setw &arg) { 134 | os.width(arg.w); 135 | return os; 136 | } 137 | /** setw manipulator 138 | * \param[in] is the stream 139 | * \param[in] arg set setw object 140 | * \return the stream 141 | */ 142 | inline istream &operator>>(istream &is, const setw &arg) { 143 | is.width(arg.w); 144 | return is; 145 | } 146 | //============================================================================== 147 | /** 148 | * \class iostream 149 | * \brief Input/Output stream 150 | */ 151 | class iostream : public istream, public ostream { 152 | }; 153 | #endif // iostream_h 154 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/ostream.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #ifndef PSTR 22 | #define PSTR(x) x 23 | #endif 24 | //------------------------------------------------------------------------------ 25 | void ostream::do_fill(unsigned len) { 26 | for (; len < width(); len++) putch(fill()); 27 | width(0); 28 | } 29 | //------------------------------------------------------------------------------ 30 | void ostream::fill_not_left(unsigned len) { 31 | if ((flags() & adjustfield) != left) { 32 | do_fill(len); 33 | } 34 | } 35 | //------------------------------------------------------------------------------ 36 | char* ostream::fmtNum(uint32_t n, char *ptr, uint8_t base) { 37 | char a = flags() & uppercase ? 'A' - 10 : 'a' - 10; 38 | do { 39 | uint32_t m = n; 40 | n /= base; 41 | char c = m - base * n; 42 | *--ptr = c < 10 ? c + '0' : c + a; 43 | } while (n); 44 | return ptr; 45 | } 46 | //------------------------------------------------------------------------------ 47 | void ostream::putBool(bool b) { 48 | if (flags() & boolalpha) { 49 | if (b) { 50 | putPgm(PSTR("true")); 51 | } else { 52 | putPgm(PSTR("false")); 53 | } 54 | } else { 55 | putChar(b ? '1' : '0'); 56 | } 57 | } 58 | //------------------------------------------------------------------------------ 59 | void ostream::putChar(char c) { 60 | fill_not_left(1); 61 | putch(c); 62 | do_fill(1); 63 | } 64 | //------------------------------------------------------------------------------ 65 | void ostream::putDouble(double n) { 66 | uint8_t nd = precision(); 67 | double round = 0.5; 68 | char sign; 69 | char buf[13]; // room for sign, 10 digits, '.', and zero byte 70 | char *end = buf + sizeof(buf) - 1; 71 | char *str = end; 72 | // terminate string 73 | *end = '\0'; 74 | 75 | // get sign and make nonnegative 76 | if (n < 0.0) { 77 | sign = '-'; 78 | n = -n; 79 | } else { 80 | sign = flags() & showpos ? '+' : '\0'; 81 | } 82 | // check for larger than uint32_t 83 | if (n > 4.0E9) { 84 | putPgm(PSTR("BIG FLT")); 85 | return; 86 | } 87 | // round up and separate in and fraction parts 88 | for (uint8_t i = 0; i < nd; ++i) round *= 0.1; 89 | n += round; 90 | uint32_t intPart = n; 91 | double fractionPart = n - intPart; 92 | 93 | // format intPart and decimal point 94 | if (nd || (flags() & showpoint)) *--str = '.'; 95 | str = fmtNum(intPart, str, 10); 96 | 97 | // calculate length for fill 98 | uint8_t len = sign ? 1 : 0; 99 | len += nd + end - str; 100 | 101 | // extract adjust field 102 | fmtflags adj = flags() & adjustfield; 103 | if (adj == internal) { 104 | if (sign) putch(sign); 105 | do_fill(len); 106 | } else { 107 | // do fill for internal or right 108 | fill_not_left(len); 109 | if (sign) *--str = sign; 110 | } 111 | putstr(str); 112 | // output fraction 113 | while (nd-- > 0) { 114 | fractionPart *= 10.0; 115 | int digit = static_cast(fractionPart); 116 | putch(digit + '0'); 117 | fractionPart -= digit; 118 | } 119 | // do fill if not done above 120 | do_fill(len); 121 | } 122 | //------------------------------------------------------------------------------ 123 | void ostream::putNum(int32_t n) { 124 | bool neg = n < 0 && flagsToBase() == 10; 125 | if (neg) n = -n; 126 | putNum(n, neg); 127 | } 128 | //------------------------------------------------------------------------------ 129 | void ostream::putNum(uint32_t n, bool neg) { 130 | char buf[13]; 131 | char* end = buf + sizeof(buf) - 1; 132 | char* num; 133 | char* str; 134 | uint8_t base = flagsToBase(); 135 | *end = '\0'; 136 | str = num = fmtNum(n, end, base); 137 | if (base == 10) { 138 | if (neg) { 139 | *--str = '-'; 140 | } else if (flags() & showpos) { 141 | *--str = '+'; 142 | } 143 | } else if (flags() & showbase) { 144 | if (flags() & hex) { 145 | *--str = flags() & uppercase ? 'X' : 'x'; 146 | } 147 | *--str = '0'; 148 | } 149 | uint8_t len = end - str; 150 | fmtflags adj = flags() & adjustfield; 151 | if (adj == internal) { 152 | while (str < num) putch(*str++); 153 | } 154 | if (adj != left) { 155 | do_fill(len); 156 | } 157 | putstr(str); 158 | do_fill(len); 159 | } 160 | //------------------------------------------------------------------------------ 161 | void ostream::putPgm(const char* str) { 162 | int n; 163 | for (n = 0; pgm_read_byte(&str[n]); n++) {} 164 | fill_not_left(n); 165 | for (uint8_t c; (c = pgm_read_byte(str)); str++) { 166 | putch(c); 167 | } 168 | do_fill(n); 169 | } 170 | //------------------------------------------------------------------------------ 171 | void ostream::putStr(const char *str) { 172 | unsigned n = strlen(str); 173 | fill_not_left(n); 174 | putstr(str); 175 | do_fill(n); 176 | } 177 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/ostream.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef ostream_h 21 | #define ostream_h 22 | /** 23 | * \file 24 | * \brief \ref ostream class 25 | */ 26 | #include 27 | //------------------------------------------------------------------------------ 28 | /** macro for flash inserter */ 29 | #define pstr(str) pgm(PSTR(str)) 30 | /** \struct pgm 31 | * \brief type for string in flash 32 | */ 33 | struct pgm { 34 | /** Pointer to flash string */ 35 | char *ptr; 36 | /** constructor 37 | * \param[in] str initializer for pointer. 38 | */ 39 | explicit pgm(char* str) : ptr(str) {} 40 | /** constructor 41 | * \param[in] str initializer for pointer. 42 | */ 43 | explicit pgm(const char *str) : ptr(const_cast(str)) {} 44 | }; 45 | //============================================================================== 46 | /** 47 | * \class ostream 48 | * \brief Output Stream 49 | */ 50 | class ostream : public virtual ios { 51 | public: 52 | ostream() {} 53 | 54 | /** call manipulator 55 | * \param[in] pf function to call 56 | * \return the stream 57 | */ 58 | ostream& operator<< (ostream& (*pf)(ostream& str)) { 59 | return pf(*this); 60 | } 61 | /** call manipulator 62 | * \param[in] pf function to call 63 | * \return the stream 64 | */ 65 | ostream& operator<< (ios_base& (*pf)(ios_base& str)) { 66 | pf(*this); 67 | return *this; 68 | } 69 | /** Output bool 70 | * \param[in] arg value to output 71 | * \return the stream 72 | */ 73 | ostream &operator<< (bool arg) { 74 | putBool(arg); 75 | return *this; 76 | } 77 | /** Output string 78 | * \param[in] arg string to output 79 | * \return the stream 80 | */ 81 | ostream &operator<< (const char *arg) { 82 | putStr(arg); 83 | return *this; 84 | } 85 | /** Output string 86 | * \param[in] arg string to output 87 | * \return the stream 88 | */ 89 | ostream &operator<< (const signed char *arg) { 90 | putStr((const char*)arg); 91 | return *this; 92 | } 93 | /** Output string 94 | * \param[in] arg string to output 95 | * \return the stream 96 | */ 97 | ostream &operator<< (const unsigned char *arg) { 98 | putStr((const char*)arg); 99 | return *this; 100 | } 101 | /** Output character 102 | * \param[in] arg character to output 103 | * \return the stream 104 | */ 105 | ostream &operator<< (char arg) { 106 | putChar(arg); 107 | return *this; 108 | } 109 | /** Output character 110 | * \param[in] arg character to output 111 | * \return the stream 112 | */ 113 | ostream &operator<< (signed char arg) { 114 | putChar(static_cast(arg)); 115 | return *this; 116 | } 117 | /** Output character 118 | * \param[in] arg character to output 119 | * \return the stream 120 | */ 121 | ostream &operator<< (unsigned char arg) { 122 | putChar(static_cast(arg)); 123 | return *this; 124 | } 125 | /** Output double 126 | * \param[in] arg value to output 127 | * \return the stream 128 | */ 129 | ostream &operator<< (double arg) { 130 | putDouble(arg); 131 | return *this; 132 | } 133 | /** Output float 134 | * \param[in] arg value to output 135 | * \return the stream 136 | */ 137 | ostream &operator<< (float arg) { 138 | putDouble(arg); 139 | return *this; 140 | } 141 | /** Output signed short 142 | * \param[in] arg value to output 143 | * \return the stream 144 | */ 145 | ostream &operator<< (short arg) { // NOLINT 146 | putNum((int32_t)arg); 147 | return *this; 148 | } 149 | /** Output unsigned short 150 | * \param[in] arg value to output 151 | * \return the stream 152 | */ 153 | ostream &operator<< (unsigned short arg) { // NOLINT 154 | putNum((uint32_t)arg); 155 | return *this; 156 | } 157 | /** Output signed int 158 | * \param[in] arg value to output 159 | * \return the stream 160 | */ 161 | ostream &operator<< (int arg) { 162 | putNum((int32_t)arg); 163 | return *this; 164 | } 165 | /** Output unsigned int 166 | * \param[in] arg value to output 167 | * \return the stream 168 | */ 169 | ostream &operator<< (unsigned int arg) { 170 | putNum((uint32_t)arg); 171 | return *this; 172 | } 173 | /** Output signed long 174 | * \param[in] arg value to output 175 | * \return the stream 176 | */ 177 | ostream &operator<< (long arg) { // NOLINT 178 | putNum(arg); 179 | return *this; 180 | } 181 | /** Output unsigned long 182 | * \param[in] arg value to output 183 | * \return the stream 184 | */ 185 | ostream &operator<< (unsigned long arg) { // NOLINT 186 | putNum(arg); 187 | return *this; 188 | } 189 | /** Output pointer 190 | * \param[in] arg value to output 191 | * \return the stream 192 | */ 193 | ostream& operator<< (const void* arg) { 194 | putNum(reinterpret_cast(arg)); 195 | return *this; 196 | } 197 | /** Output a string from flash using the pstr() macro 198 | * \param[in] arg pgm struct pointing to string 199 | * \return the stream 200 | */ 201 | ostream &operator<< (pgm arg) { 202 | putPgm(arg.ptr); 203 | return *this; 204 | } 205 | /** Output a string from flash using the Arduino F() macro. 206 | * \param[in] arg pointing to flash string 207 | * \return the stream 208 | */ 209 | ostream &operator<< (const __FlashStringHelper *arg) { 210 | putPgm(reinterpret_cast(arg)); 211 | return *this; 212 | } 213 | /** 214 | * Puts a character in a stream. 215 | * 216 | * The unformatted output function inserts the element \a ch. 217 | * It returns *this. 218 | * 219 | * \param[in] ch The character 220 | * \return A reference to the ostream object. 221 | */ 222 | ostream& put(char ch) { 223 | putch(ch); 224 | return *this; 225 | } 226 | // ostream& write(char *str, streamsize count); 227 | /** 228 | * Flushes the buffer associated with this stream. The flush function 229 | * calls the sync function of the associated file. 230 | * \return A reference to the ostream object. 231 | */ 232 | ostream& flush() { 233 | if (!sync()) setstate(badbit); 234 | return *this; 235 | } 236 | /** 237 | * \return the stream position 238 | */ 239 | pos_type tellp() {return tellpos();} 240 | /** 241 | * Set the stream position 242 | * \param[in] pos The absolute position in which to move the write pointer. 243 | * \return Is always *this. Failure is indicated by the state of *this. 244 | */ 245 | ostream& seekp(pos_type pos) { 246 | if (!seekpos(pos)) setstate(failbit); 247 | return *this; 248 | } 249 | /** 250 | * Set the stream position. 251 | * 252 | * \param[in] off An offset to move the write pointer relative to way. 253 | * \a off is a signed 32-bit int so the offset is limited to +- 2GB. 254 | * \param[in] way One of ios::beg, ios::cur, or ios::end. 255 | * \return Is always *this. Failure is indicated by the state of *this. 256 | */ 257 | ostream& seekp(off_type off, seekdir way) { 258 | if (!seekoff(off, way)) setstate(failbit); 259 | return *this; 260 | } 261 | 262 | protected: 263 | /// @cond SHOW_PROTECTED 264 | /** Put character with binary/text conversion 265 | * \param[in] ch character to write 266 | */ 267 | virtual void putch(char ch) = 0; 268 | virtual void putstr(const char *str) = 0; 269 | virtual bool seekoff(off_type pos, seekdir way) = 0; 270 | virtual bool seekpos(pos_type pos) = 0; 271 | virtual bool sync() = 0; 272 | 273 | virtual pos_type tellpos() = 0; 274 | /// @endcond 275 | private: 276 | void do_fill(unsigned len); 277 | void fill_not_left(unsigned len); 278 | char* fmtNum(uint32_t n, char *ptr, uint8_t base); 279 | void putBool(bool b); 280 | void putChar(char c); 281 | void putDouble(double n); 282 | void putNum(uint32_t n, bool neg = false); 283 | void putNum(int32_t n); 284 | void putPgm(const char* str); 285 | void putStr(const char* str); 286 | }; 287 | #endif // ostream_h 288 | -------------------------------------------------------------------------------- /OpenBCI_8bit_SDfat_Library/SdFat/utility/SoftSPI.h: -------------------------------------------------------------------------------- 1 | /* Arduino DigitalIO Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the Arduino DigitalIO Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino DigitalIO Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * @file 22 | * @brief Software SPI. 23 | * 24 | * @defgroup softSPI Software SPI 25 | * @details Software SPI Template Class. 26 | * @{ 27 | */ 28 | 29 | #ifndef SoftSPI_h 30 | #define SoftSPI_h 31 | #include 32 | //------------------------------------------------------------------------------ 33 | /** Nop for timing. */ 34 | #define nop asm volatile ("nop\n\t") 35 | //------------------------------------------------------------------------------ 36 | /** Pin Mode for MISO is input.*/ 37 | const bool MISO_MODE = false; 38 | /** Pullups disabled for MISO are disabled. */ 39 | const bool MISO_LEVEL = false; 40 | /** Pin Mode for MOSI is output.*/ 41 | const bool MOSI_MODE = true; 42 | /** Pin Mode for SCK is output. */ 43 | const bool SCK_MODE = true; 44 | //------------------------------------------------------------------------------ 45 | /** 46 | * @class SoftSPI 47 | * @brief Fast software SPI. 48 | */ 49 | template 50 | class SoftSPI { 51 | public: 52 | //----------------------------------------------------------------------------- 53 | /** Initialize SoftSPI pins. */ 54 | void begin() { 55 | fastPinConfig(MisoPin, MISO_MODE, MISO_LEVEL); 56 | fastPinConfig(MosiPin, MOSI_MODE, !MODE_CPHA(Mode)); 57 | fastPinConfig(SckPin, SCK_MODE, MODE_CPOL(Mode)); 58 | } 59 | //---------------------------------------------------------------------------- 60 | /** Soft SPI receive byte. 61 | * @return Data byte received. 62 | */ 63 | inline __attribute__((always_inline)) 64 | uint8_t receive() { 65 | uint8_t data = 0; 66 | receiveBit(7, &data); 67 | receiveBit(6, &data); 68 | receiveBit(5, &data); 69 | receiveBit(4, &data); 70 | receiveBit(3, &data); 71 | receiveBit(2, &data); 72 | receiveBit(1, &data); 73 | receiveBit(0, &data); 74 | return data; 75 | } 76 | //---------------------------------------------------------------------------- 77 | /** Soft SPI send byte. 78 | * @param[in] data Data byte to send. 79 | */ 80 | inline __attribute__((always_inline)) 81 | void send(uint8_t data) { 82 | sendBit(7, data); 83 | sendBit(6, data); 84 | sendBit(5, data); 85 | sendBit(4, data); 86 | sendBit(3, data); 87 | sendBit(2, data); 88 | sendBit(1, data); 89 | sendBit(0, data); 90 | } 91 | //---------------------------------------------------------------------------- 92 | /** Soft SPI transfer byte. 93 | * @param[in] txData Data byte to send. 94 | * @return Data byte received. 95 | */ 96 | inline __attribute__((always_inline)) 97 | uint8_t transfer(uint8_t txData) { 98 | uint8_t rxData = 0; 99 | transferBit(7, &rxData, txData); 100 | transferBit(6, &rxData, txData); 101 | transferBit(5, &rxData, txData); 102 | transferBit(4, &rxData, txData); 103 | transferBit(3, &rxData, txData); 104 | transferBit(2, &rxData, txData); 105 | transferBit(1, &rxData, txData); 106 | transferBit(0, &rxData, txData); 107 | return rxData; 108 | } 109 | private: 110 | //---------------------------------------------------------------------------- 111 | inline __attribute__((always_inline)) 112 | bool MODE_CPHA(uint8_t mode) {return (mode & 1) != 0;} 113 | inline __attribute__((always_inline)) 114 | bool MODE_CPOL(uint8_t mode) {return (mode & 2) != 0;} 115 | inline __attribute__((always_inline)) 116 | void receiveBit(uint8_t bit, uint8_t* data) { 117 | if (MODE_CPHA(Mode)) { 118 | fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); 119 | } 120 | nop;nop; 121 | fastDigitalWrite(SckPin, 122 | MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); 123 | if (fastDigitalRead(MisoPin)) *data |= 1 << bit; 124 | if (!MODE_CPHA(Mode)) { 125 | fastDigitalWrite(SckPin, MODE_CPOL(Mode)); 126 | } 127 | } 128 | //---------------------------------------------------------------------------- 129 | inline __attribute__((always_inline)) 130 | void sendBit(uint8_t bit, uint8_t data) { 131 | if (MODE_CPHA(Mode)) { 132 | fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); 133 | } 134 | fastDigitalWrite(MosiPin, data & (1 << bit)); 135 | fastDigitalWrite(SckPin, 136 | MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); 137 | nop;nop; 138 | if (!MODE_CPHA(Mode)) { 139 | fastDigitalWrite(SckPin, MODE_CPOL(Mode)); 140 | } 141 | } 142 | //---------------------------------------------------------------------------- 143 | inline __attribute__((always_inline)) 144 | void transferBit(uint8_t bit, uint8_t* rxData, uint8_t txData) { 145 | if (MODE_CPHA(Mode)) { 146 | fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); 147 | } 148 | fastDigitalWrite(MosiPin, txData & (1 << bit)); 149 | fastDigitalWrite(SckPin, 150 | MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); 151 | if (fastDigitalRead(MisoPin)) *rxData |= 1 << bit; 152 | if (!MODE_CPHA(Mode)) { 153 | fastDigitalWrite(SckPin, MODE_CPOL(Mode)); 154 | } 155 | } 156 | //---------------------------------------------------------------------------- 157 | }; 158 | #endif // SoftSPI_h 159 | /** @} */ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Firmware for OpenBCI 8bit system 2 | ================= 3 | 4 | **OpenBCI_8bit_Device** 5 | Device code for the OpenBCI Board mounted RFduino 6 | **OpenBCI_8bit_Host** 7 | Host code for the OpenBCI Dongle mounted RFduino 8 | **OpenBCI_8bit_Library/OpenBCI_8** 9 | OpenBCI library for 8bit board 10 | Install in your documents/arduino/libraries folder 11 | **OpenBCI_8bit_RFduino_Library/RFduino** 12 | RFduino hardware libraries with custom OpenBCI support 13 | Install according to RFduino instructions https://github.com/OpenBCI/OpenBCI_8bit/blob/master/OpenBCI_8bit_RFduino_Library/RFduino/README.md 14 | **OpenBCI_8bit_SD** 15 | Arduino code for the OpenBCI 8bit Board 16 | **OpenBCI_8bit_SDfat_Library/SdFat** 17 | Install in your documents/arduino/libraries folder 18 | 19 | 20 | The OpenBCI 8bit system is an open-source biopotential acquisisiton system. It incorporates an ADS1299 (analog to digital converter IC), LIS3DH (triple axis accelerometer), Micro SD card, RFduino radio module, and an ATmega328 with Arduino UNO bootloader. The Device code is for the OpenBCI Board Radio Module, and the Host code is for the OpenBCI Dongle Radio Module. 21 | Using the OpenBCI USB Dongle, it is possible to upload the OpenBCI_8bit_streamData_Filter to the target ATmega on the OpenBCI 8bit board. This version implements an optional high pass and 60Hz notch filter using a modified biquad library included. 22 | 23 | Copy the Biquad folder to your Documents/Arduino/Libraries folder, and the OpenBCI_8bit_streamData_Filter folder to your Documents/Arduino folder. Select UNO from the boards menue int Arduino IDE, and the correct serial port of the Dongle. All OpenBCI hardware comes flashed with the latest firmware. Upgrading the OpenBCI Board firmware is possible over-the-air using the OpenBCI Dongle. Dongle (Host) and Board (Device) firmware is also upgradable using advanced version of the Arduino IDE and installing custom RFduino libraries included here 24 | Copy the RFduino directory from this repository in Arduino 25 | (on Windows, C:\arduino-1.5.4\hardware\arduino) 26 | (on OSX, /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino) 27 | 28 | Note that to use the OpenBCI system, you will generally use the OpenBCI USB Dongle. The dongle requries that you install the FTDI drivers for your particular operating system: http://www.ftdichip.com/FTDrivers.htm 29 | 30 | Arduino code developed by Chip Audette, modified by Joel Murphy, Luke Travis, Conor Russomanno. Summer 2014 31 | 32 | RFduino code developed by Joel Murphy, Leif Percifield, Conor Russomanno. Summer 2014 33 | 34 | this software is provided as is. there is no attached warranty, or any claim of it's functionality. wysiwyg. 35 | free to use and share. 36 | --------------------------------------------------------------------------------