Skip to content

Commit 1c643fb

Browse files
facchinmeriknyquist
authored andcommittedMar 1, 2017
Add CurieSerialFlash wrapper over SerialFlash library
The examples declare the correct CS pin and use the overloaded begin() method, passing SPI1 as port The link in the last line of the header opens the library manager to allow easy import of the father library
1 parent e9984d9 commit 1c643fb

File tree

6 files changed

+969
-0
lines changed

6 files changed

+969
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#if !defined (__arc__)
2+
#error These examples only work with onboard SPI flash on Arduino/Genuino 101 board
3+
#endif
4+
#include "SerialFlash.h"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
/*
2+
* This is free and unencumbered software released into the public domain.
3+
*
4+
* Anyone is free to copy, modify, publish, use, compile, sell, or
5+
* distribute this software, either in source code form or as a compiled
6+
* binary, for any purpose, commercial or non-commercial, and by any
7+
* means.
8+
*
9+
* In jurisdictions that recognize copyright laws, the author or authors
10+
* of this software dedicate any and all copyright interest in the
11+
* software to the public domain. We make this dedication for the benefit
12+
* of the public at large and to the detriment of our heirs and
13+
* successors. We intend this dedication to be an overt act of
14+
* relinquishment in perpetuity of all present and future rights to this
15+
* software under copyright law.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20+
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21+
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22+
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23+
* OTHER DEALINGS IN THE SOFTWARE.
24+
*
25+
* For more information, please refer to <http://unlicense.org>
26+
* -------------------------------------------------------------------------
27+
*
28+
* This is example code to 1) format an SPI Flash chip, and 2) copy raw
29+
* audio files (mono channel, 16 bit signed, 44100Hz) to it using the
30+
* SerialFlash library. The audio can then be played back using the
31+
* AudioPlaySerialflashRaw object in the Teensy Audio library.
32+
*
33+
* To convert a .wav file to the proper .RAW format, use sox:
34+
* sox input.wav -r 44100 -b 16 --norm -e signed-integer -t raw OUTPUT.RAW remix 1,2
35+
*
36+
* Note that the OUTPUT.RAW filename must be all caps and contain only the following
37+
* characters: A-Z, 0-9, comma, period, colon, dash, underscore. (The SerialFlash
38+
* library converts filenames to caps, so to avoid confusion we just enforce it here).
39+
*
40+
* It is a little difficult to see what is happening; aswe are using the Serial port
41+
* to upload files, we can't just throw out debug information. Instead, we use the LED
42+
* (pin 13) to convey state.
43+
*
44+
* While the chip is being formatted, the LED (pin 13) will toggle at 1Hz rate. When
45+
* the formatting is done, it flashes quickly (10Hz) for one second, then stays on
46+
* solid. When nothing has been received for 3 seconds, the upload is assumed to be
47+
* completed, and the light goes off.
48+
*
49+
* Use the 'rawfile-uploader.py' python script (included in the extras folder) to upload
50+
* the files. You can start the script as soon as the Teensy is turned on, and the
51+
* USB serial upload will just buffer and wait until the flash is formatted.
52+
*
53+
* This code was written by Wyatt Olson <wyatt@digitalcave.ca> (originally as part
54+
* of Drum Master http://drummaster.digitalcave.ca and later modified into a
55+
* standalone sample).
56+
*
57+
* Enjoy!
58+
*
59+
* SerialFlash library API: https://github.com/PaulStoffregen/SerialFlash
60+
*
61+
* This example depens on http://librarymanager/all#SerialFlash&SPI (clickme!)
62+
*/
63+
64+
#include <CurieSerialFlash.h>
65+
#include <SPI.h>
66+
67+
//Buffer sizes
68+
#define USB_BUFFER_SIZE 128
69+
#define FLASH_BUFFER_SIZE 4096
70+
71+
//Max filename length (8.3 plus a null char terminator)
72+
#define FILENAME_STRING_SIZE 13
73+
74+
//State machine
75+
#define STATE_START 0
76+
#define STATE_SIZE 1
77+
#define STATE_CONTENT 2
78+
79+
//Special bytes in the communication protocol
80+
#define BYTE_START 0x7e
81+
#define BYTE_ESCAPE 0x7d
82+
#define BYTE_SEPARATOR 0x7c
83+
84+
#define CSPIN 21
85+
86+
void setup(){
87+
Serial.begin(9600); //Teensy serial is always at full USB speed and buffered... the baud rate here is required but ignored
88+
89+
pinMode(13, OUTPUT);
90+
91+
SerialFlash.begin(SPI1, CSPIN);
92+
93+
//We start by formatting the flash...
94+
uint8_t id[5];
95+
SerialFlash.readID(id);
96+
SerialFlash.eraseAll();
97+
98+
//Flash LED at 1Hz while formatting
99+
while (!SerialFlash.ready()) {
100+
delay(500);
101+
digitalWrite(13, HIGH);
102+
delay(500);
103+
digitalWrite(13, LOW);
104+
}
105+
106+
//Quickly flash LED a few times when completed, then leave the light on solid
107+
for(uint8_t i = 0; i < 10; i++){
108+
delay(100);
109+
digitalWrite(13, HIGH);
110+
delay(100);
111+
digitalWrite(13, LOW);
112+
}
113+
digitalWrite(13, HIGH);
114+
115+
//We are now going to wait for the upload program
116+
while(!Serial.available());
117+
118+
SerialFlashFile flashFile;
119+
120+
uint8_t state = STATE_START;
121+
uint8_t escape = 0;
122+
uint8_t fileSizeIndex = 0;
123+
uint32_t fileSize = 0;
124+
char filename[FILENAME_STRING_SIZE];
125+
126+
char usbBuffer[USB_BUFFER_SIZE];
127+
uint8_t flashBuffer[FLASH_BUFFER_SIZE];
128+
129+
uint16_t flashBufferIndex = 0;
130+
uint8_t filenameIndex = 0;
131+
132+
uint32_t lastReceiveTime = millis();
133+
134+
//We assume the serial receive part is finished when we have not received something for 3 seconds
135+
while(Serial.available() || lastReceiveTime + 3000 > millis()){
136+
uint16_t available = Serial.readBytes(usbBuffer, USB_BUFFER_SIZE);
137+
if (available){
138+
lastReceiveTime = millis();
139+
}
140+
141+
for (uint16_t usbBufferIndex = 0; usbBufferIndex < available; usbBufferIndex++){
142+
uint8_t b = usbBuffer[usbBufferIndex];
143+
144+
if (state == STATE_START){
145+
//Start byte. Repeat start is fine.
146+
if (b == BYTE_START){
147+
for (uint8_t i = 0; i < FILENAME_STRING_SIZE; i++){
148+
filename[i] = 0x00;
149+
}
150+
filenameIndex = 0;
151+
}
152+
//Valid characters are A-Z, 0-9, comma, period, colon, dash, underscore
153+
else if ((b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9') || b == '.' || b == ',' || b == ':' || b == '-' || b == '_'){
154+
filename[filenameIndex++] = b;
155+
if (filenameIndex >= FILENAME_STRING_SIZE){
156+
//Error name too long
157+
flushError();
158+
return;
159+
}
160+
}
161+
//Filename end character
162+
else if (b == BYTE_SEPARATOR){
163+
if (filenameIndex == 0){
164+
//Error empty filename
165+
flushError();
166+
return;
167+
}
168+
169+
//Change state
170+
state = STATE_SIZE;
171+
fileSizeIndex = 0;
172+
fileSize = 0;
173+
174+
}
175+
//Invalid character
176+
else {
177+
//Error bad filename
178+
flushError();
179+
return;
180+
}
181+
}
182+
//We read 4 bytes as a uint32_t for file size
183+
else if (state == STATE_SIZE){
184+
if (fileSizeIndex < 4){
185+
fileSize = (fileSize << 8) + b;
186+
fileSizeIndex++;
187+
}
188+
else if (b == BYTE_SEPARATOR){
189+
state = STATE_CONTENT;
190+
flashBufferIndex = 0;
191+
escape = 0;
192+
193+
if (SerialFlash.exists(filename)){
194+
SerialFlash.remove(filename); //It doesn't reclaim the space, but it does let you create a new file with the same name.
195+
}
196+
197+
//Create a new file and open it for writing
198+
if (SerialFlash.create(filename, fileSize)) {
199+
flashFile = SerialFlash.open(filename);
200+
if (!flashFile) {
201+
//Error flash file open
202+
flushError();
203+
return;
204+
}
205+
}
206+
else {
207+
//Error flash create (no room left?)
208+
flushError();
209+
return;
210+
}
211+
}
212+
else {
213+
//Error invalid length requested
214+
flushError();
215+
return;
216+
}
217+
}
218+
else if (state == STATE_CONTENT){
219+
//Previous byte was escaped; unescape and add to buffer
220+
if (escape){
221+
escape = 0;
222+
flashBuffer[flashBufferIndex++] = b ^ 0x20;
223+
}
224+
//Escape the next byte
225+
else if (b == BYTE_ESCAPE){
226+
//Serial.println("esc");
227+
escape = 1;
228+
}
229+
//End of file
230+
else if (b == BYTE_START){
231+
//Serial.println("End of file");
232+
state = STATE_START;
233+
flashFile.write(flashBuffer, flashBufferIndex);
234+
flashFile.close();
235+
flashBufferIndex = 0;
236+
}
237+
//Normal byte; add to buffer
238+
else {
239+
flashBuffer[flashBufferIndex++] = b;
240+
}
241+
242+
//The buffer is filled; write to SD card
243+
if (flashBufferIndex >= FLASH_BUFFER_SIZE){
244+
flashFile.write(flashBuffer, FLASH_BUFFER_SIZE);
245+
flashBufferIndex = 0;
246+
}
247+
}
248+
}
249+
}
250+
251+
//Success! Turn the light off.
252+
digitalWrite(13, LOW);
253+
}
254+
255+
void loop(){
256+
//Do nothing.
257+
}
258+
259+
void flushError(){
260+
uint32_t lastReceiveTime = millis();
261+
char usbBuffer[USB_BUFFER_SIZE];
262+
//We assume the serial receive part is finished when we have not received something for 3 seconds
263+
while(Serial.available() || lastReceiveTime + 3000 > millis()){
264+
if (Serial.readBytes(usbBuffer, USB_BUFFER_SIZE)){
265+
lastReceiveTime = millis();
266+
}
267+
}
268+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// This example depens on http://librarymanager/all#SerialFlash&SPI (clickme!)
2+
3+
#include <CurieSerialFlash.h>
4+
#include <SPI.h>
5+
6+
const int FlashChipSelect = 21; // digital pin for flash chip CS pin
7+
8+
SerialFlashFile file;
9+
10+
const unsigned long testIncrement = 4096;
11+
12+
void setup() {
13+
//uncomment these if using Teensy audio shield
14+
//SPI.setSCK(14); // Audio shield has SCK on pin 14
15+
//SPI.setMOSI(7); // Audio shield has MOSI on pin 7
16+
17+
//uncomment these if you have other SPI chips connected
18+
//to keep them disabled while using only SerialFlash
19+
//pinMode(4, INPUT_PULLUP);
20+
//pinMode(10, INPUT_PULLUP);
21+
22+
Serial.begin(9600);
23+
24+
// wait up to 10 seconds for Arduino Serial Monitor
25+
unsigned long startMillis = millis();
26+
while (!Serial && (millis() - startMillis < 10000)) ;
27+
delay(100);
28+
29+
SerialFlash.begin(SPI1, FlashChipSelect);
30+
unsigned char id[5];
31+
SerialFlash.readID(id);
32+
unsigned long size = SerialFlash.capacity(id);
33+
34+
if (size > 0) {
35+
Serial.print("Flash Memory has ");
36+
Serial.print(size);
37+
Serial.println(" bytes.");
38+
Serial.println("Erasing ALL Flash Memory:");
39+
// Estimate the (lengthy) wait time.
40+
Serial.print(" estimated wait: ");
41+
int seconds = (float)size / eraseBytesPerSecond(id) + 0.5;
42+
Serial.print(seconds);
43+
Serial.println(" seconds.");
44+
Serial.println(" Yes, full chip erase is SLOW!");
45+
SerialFlash.eraseAll();
46+
unsigned long dotMillis = millis();
47+
unsigned char dotcount = 0;
48+
while (SerialFlash.ready() == false) {
49+
if (millis() - dotMillis > 1000) {
50+
dotMillis = dotMillis + 1000;
51+
Serial.print(".");
52+
dotcount = dotcount + 1;
53+
if (dotcount >= 60) {
54+
Serial.println();
55+
dotcount = 0;
56+
}
57+
}
58+
}
59+
if (dotcount > 0) Serial.println();
60+
Serial.println("Erase completed");
61+
unsigned long elapsed = millis() - startMillis;
62+
Serial.print(" actual wait: ");
63+
Serial.print(elapsed / 1000ul);
64+
Serial.println(" seconds.");
65+
}
66+
}
67+
68+
float eraseBytesPerSecond(const unsigned char *id) {
69+
if (id[0] == 0x20) return 152000.0; // Micron
70+
if (id[0] == 0x01) return 500000.0; // Spansion
71+
if (id[0] == 0xEF) return 419430.0; // Winbond
72+
if (id[0] == 0xC2) return 279620.0; // Macronix
73+
return 320000.0; // guess?
74+
}
75+
76+
77+
void loop() {
78+
79+
}
80+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// This example depens on http://librarymanager/all#SerialFlash&SPI (clickme!)
2+
3+
#include <CurieSerialFlash.h>
4+
#include <SPI.h>
5+
6+
#define FSIZE 256
7+
8+
const char *filename = "myfile.txt";
9+
const char *contents = "0123456789ABCDEF";
10+
11+
const int FlashChipSelect = 21; // digital pin for flash chip CS pin
12+
13+
void setup() {
14+
Serial.begin(9600);
15+
16+
// wait for Arduino Serial Monitor
17+
while (!Serial) ;
18+
delay(100);
19+
20+
// Init. SPI Flash chip
21+
if (!SerialFlash.begin(SPI1, FlashChipSelect)) {
22+
Serial.println("Unable to access SPI Flash chip");
23+
}
24+
25+
SerialFlashFile file;
26+
27+
// Create the file if it doesn't exist
28+
if (!create_if_not_exists(filename)) {
29+
Serial.println("Not enough space to create file " + String(filename));
30+
return;
31+
}
32+
33+
// Open the file and write test data
34+
file = SerialFlash.open(filename);
35+
file.write(contents, strlen(contents) + 1);
36+
Serial.println("String \"" + String(contents) + "\" written to file " + String(filename));
37+
}
38+
39+
bool create_if_not_exists (const char *filename) {
40+
if (!SerialFlash.exists(filename)) {
41+
Serial.println("Creating file " + String(filename));
42+
return SerialFlash.create(filename, FSIZE);
43+
}
44+
45+
Serial.println("File " + String(filename) + " already exists");
46+
return true;
47+
}
48+
49+
void loop() {
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// This example depens on http://librarymanager/all#SerialFlash&SPI (clickme!)
2+
3+
#include <CurieSerialFlash.h>
4+
#include <SPI.h>
5+
6+
const int FlashChipSelect = 21; // digital pin for flash chip CS pin
7+
8+
void setup() {
9+
//uncomment these if using Teensy audio shield
10+
//SPI.setSCK(14); // Audio shield has SCK on pin 14
11+
//SPI.setMOSI(7); // Audio shield has MOSI on pin 7
12+
13+
//uncomment these if you have other SPI chips connected
14+
//to keep them disabled while using only SerialFlash
15+
//pinMode(4, INPUT_PULLUP);
16+
//pinMode(10, INPUT_PULLUP);
17+
18+
Serial.begin(9600);
19+
20+
// wait for Arduino Serial Monitor
21+
while (!Serial) ;
22+
delay(100);
23+
Serial.println("All Files on SPI Flash chip:");
24+
25+
if (!SerialFlash.begin(SPI1, FlashChipSelect)) {
26+
error("Unable to access SPI Flash chip");
27+
}
28+
29+
SerialFlash.opendir();
30+
unsigned int count = 0;
31+
while (1) {
32+
char filename[64];
33+
unsigned long filesize;
34+
35+
if (SerialFlash.readdir(filename, sizeof(filename), filesize)) {
36+
Serial.print(" ");
37+
Serial.print(filename);
38+
spaces(20 - strlen(filename));
39+
Serial.print(" ");
40+
Serial.print(filesize);
41+
Serial.print(" bytes");
42+
Serial.println();
43+
} else {
44+
break; // no more files
45+
}
46+
}
47+
}
48+
49+
void spaces(int num) {
50+
for (int i=0; i < num; i++) {
51+
Serial.print(" ");
52+
}
53+
}
54+
55+
void loop() {
56+
}
57+
58+
void error(const char *message) {
59+
while (1) {
60+
Serial.println(message);
61+
delay(2500);
62+
}
63+
}

‎libraries/CurieSerialFlash/examples/RawHardwareTest/RawHardwareTest.ino

+504
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.