-
Notifications
You must be signed in to change notification settings - Fork 4
Feature/spi flash #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
fkhabur
wants to merge
24
commits into
main
Choose a base branch
from
feature/spi-flash
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
abae48d
Initial Commit
OceancattUCSC 7fca79c
added Libary dependency and some basic methods
OceancattUCSC 6ffd79c
update gitignore
OceancattUCSC edf819e
added basic functions and headers
OceancattUCSC 46ad0b5
combining prateeks old code
prateekgupta5 b0fdd99
Mostly complete with spiflash additional layers (no tick, read, write)
prateekgupta5 4830c73
added function call checks for buffer and kLog
OceancattUCSC 7d3682a
updated read function with error handling
OceancattUCSC 99c71e0
added file for writing unittests
OceancattUCSC 3688621
made changes to lib file and moved untitest files
OceancattUCSC d4ee06e
Update spiFlash.h
OceancattUCSC cd98ae9
added actual hardare interaction (v1) -Prateek
prateekgupta5 08111a5
link fail
OceancattUCSC d91ffe6
in spiFlash.cpp: Modify spiFlash::startUp to return boolean status --…
prateekgupta5 76c630b
Change startUp method return type to bool -- Prateek
prateekgupta5 77db70d
made splitflash.h be alphbetical, and spliflashtester also made
fkhabur de35981
Modify spiFlash constructor, remove spiflash::setCS_PIN
prateekgupta5 8f62f96
Refactor spiFlash class constructor and methods
prateekgupta5 38d4421
Add NOBOARD_TEST definition for stdio unit tests
prateekgupta5 bb2b5ca
Delete blaze-lite/core/lib/spi_flash/flash_config.h
prateekgupta5 0d17d35
Delete .vscode/c_cpp_properties.json
prateekgupta5 039d5f1
Merge branch 'main' into feature/spi-flash
prateekgupta5 20c1bce
Refactor spliFlashTester to make constructor/destructor more concise,…
prateekgupta5 ed36f30
Rename spliFlashTester to SpiFlashTester, made the file include a test
prateekgupta5 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,199 @@ | ||
| /* | ||
| * spiFlash.cpp - SPI Flash library for Blaze | ||
| * To use: | ||
| include the corresponding header file in your main program, DO NOT directly call this cpp file | ||
| */ | ||
| #include "spiFlash.h" | ||
|
|
||
| #include <queue> | ||
| #include <tuple> | ||
| #include <stdint.h> | ||
| #include <unistd.h> | ||
| #include <string.h> | ||
| #include <cmath> | ||
| #include <vector> | ||
| #include <fstream> | ||
| #include <iostream> | ||
| #include <fcntl.h> | ||
|
|
||
|
|
||
| const uint8_t CS_PIN = PB8; | ||
| Adafruit_FlashTransport_SPI flash_Transport(CS_PIN, SPI); | ||
| Adafruit_SPIFlash flash_(&flash_Transport); | ||
|
|
||
| FatVolume fatfs; | ||
|
|
||
| // File32 root; | ||
| // File32 file; | ||
| File32 fd, kfd; | ||
|
|
||
| //TODO: Make private methods to simplify code | ||
|
|
||
| //Constructor: | ||
| spiFlash::spiFlash (const size_t buffer_size, const size_t k_buffer_size) | ||
| : buffer_size(buffer_size), k_buffer_size(k_buffer_size), buffer_offset(0), k_buffer_offset(0) { | ||
| obuff = new char[ buffer_size]; | ||
| kbuff = new char[k_buffer_size]; | ||
| queuedos = std::priority_queue<std::tuple<char, size_t, char*>, std::vector<std::tuple<char, size_t, char*>>, cmp_io_priority>(); | ||
| } | ||
|
|
||
| spiFlash::~spiFlash () { | ||
| kflush(); | ||
| flush(); | ||
|
|
||
| #ifdef NOBOARD_TEST | ||
| ::close(fd); | ||
| ::close(kfd); | ||
| #endif | ||
|
|
||
| delete[] obuff; | ||
| delete[] kbuff; | ||
|
|
||
| } | ||
|
|
||
| //hardware setup function (this should be called in the main file setup loop): | ||
| //https://github.com/adafruit/Adafruit_SPIFlash/blob/master/examples/SdFat_datalogging/SdFat_datalogging.ino | ||
| bool spiFlash::startUp() { | ||
| if (!flash_.begin()) { | ||
| Serial.println("Error, failed to initialize flash_ chip!"); | ||
| // while (1) { | ||
| // delay(1); | ||
| // } | ||
| return false; | ||
| } | ||
| Serial.print("Flash chip JEDEC ID: 0x"); | ||
| Serial.println(flash_.getJEDECID(), HEX); | ||
|
|
||
| // First call begin to mount the filesystem. Check that it returns true | ||
| // to make sure the filesystem was mounted. | ||
| if (!fatfs.begin(&flash_)) { | ||
| Serial.println("Error, failed to mount newly formatted filesystem!"); | ||
| Serial.println("Was the flash_ chip formatted with the fatfs_format example?"); | ||
| // while (1) delay(1); | ||
| return false; | ||
| } | ||
| Serial.println("Mounted filesystem!"); | ||
| return true; | ||
| } | ||
|
|
||
| //Get Methods: | ||
| uint8_t spiFlash::getCS_PIN() { return CS_PIN; } | ||
|
|
||
| // //Set Methods: | ||
| // void spiFlash::setCS_PIN(const uint8_t pin) { CS_PIN = pin; } | ||
|
|
||
| //functionality methods: | ||
| ssize_t spiFlash::read(const size_t offset, const size_t bytes, char* buffer){ | ||
| // //error handling | ||
| // if (bytes == 0) return 0; //no bytes to read | ||
| // if (buffer == nullptr) return -1; //null data pointer | ||
| // if (lseek(fd, offset, SEEK_SET) == -1 ) return -2; //seek error | ||
|
|
||
| // ssize_t bytes_read = ::read(fd, buffer, bytes); | ||
|
|
||
| // return bytes_read; | ||
| } | ||
|
|
||
| char spiFlash::queue(size_t bytes, char* data, char priority) { | ||
| queuedos.push(std::tie<char, size_t, char*>(priority, bytes, data)); | ||
| return 0; | ||
| } | ||
|
|
||
| char spiFlash::buffer (const size_t bytes, const char* data) { | ||
| //function call error handling | ||
| if (bytes == 0) return 0; //no bytes to write | ||
| if (data == nullptr) return -1; //null data pointer | ||
| if (obuff == nullptr) return -2; //null buffer pointer | ||
|
|
||
| ssize_t err = 0; | ||
| size_t offset = 0, temp = 0; | ||
|
|
||
| memcpy(obuff + buffer_offset, data, temp = std::min(bytes, buffer_size - buffer_offset)); | ||
| buffer_offset += (offset += temp); | ||
|
|
||
| while ((bytes - offset > 0) && (err == 0)) { | ||
| if (err = flush() < 0) return err; | ||
| flush(); | ||
|
|
||
| memcpy(obuff, data + offset, temp = std::min(bytes - offset, buffer_size)); | ||
| buffer_offset += temp; | ||
| offset += temp; | ||
| } | ||
|
|
||
| return err; | ||
| } | ||
|
|
||
| //return value < 0 means error | ||
| ssize_t spiFlash::write (const size_t bytes, const char* data) { | ||
| #ifdef NOBOARD_TEST | ||
| return ::write(fd, data, bytes); | ||
| #else | ||
| return fd.write(data, bytes); | ||
| #endif | ||
| } | ||
|
|
||
| ssize_t spiFlash::kwrite (const size_t bytes, const char* data) { | ||
| #ifdef NOBOARD_TEST | ||
| return ::write(kfd, data, bytes); | ||
| #else | ||
| return kfd.write(data, bytes); | ||
| #endif | ||
| } | ||
|
|
||
| char spiFlash::flush (void) { | ||
| ssize_t err = write(buffer_offset, obuff); | ||
| if (err < 0) return err; | ||
|
|
||
| memset(obuff, 0, buffer_size); | ||
| buffer_offset = 0; | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| ssize_t spiFlash::kLog (const size_t bytes, const char* data) { | ||
| //function call error handling | ||
| if (bytes == 0) return 0; //no bytes to write | ||
| if (data == nullptr) return -1; //null data pointer | ||
| if (kbuff == nullptr) return -2; //null buffer pointer | ||
|
|
||
| ssize_t err = 0; | ||
| size_t offset = 0, temp = 0; | ||
|
|
||
| memcpy(kbuff + k_buffer_offset, data, temp = std::min(bytes, k_buffer_size - k_buffer_offset)); | ||
| k_buffer_offset += (offset += temp); | ||
|
|
||
| while (bytes - offset > 0) { | ||
| if (err = kflush() < 0) return err; | ||
| memcpy(kbuff, data + offset, temp = std::min(bytes - offset, k_buffer_size - k_buffer_offset)); | ||
| k_buffer_offset += temp; | ||
| offset += temp; | ||
| } | ||
|
|
||
| return err; | ||
| } | ||
|
|
||
| char spiFlash::kflush (void) { | ||
| ssize_t err = kwrite (k_buffer_offset, kbuff); | ||
| if (err < 0) return err; | ||
| memset(kbuff, 0, k_buffer_size); | ||
| k_buffer_offset = 0; | ||
| return err; | ||
| } | ||
|
|
||
| //TODO: implement error tracking | ||
| ssize_t spiFlash::tick (void) { | ||
| if(queuedos.empty()) return 0; | ||
|
|
||
| bool isMandatory = std::get<0>(queuedos.top()) == spiFlash::P_MANDATORY; | ||
| ssize_t numBytes = this->buffer(std::get<1>(queuedos.top()), std::get<2>(queuedos.top())); | ||
| queuedos.pop(); | ||
|
|
||
| for(; std::get<0>(queuedos.top()) == spiFlash::P_MANDATORY; queuedos.pop()) numBytes += this->buffer(std::get<1>(queuedos.top()), std::get<2>(queuedos.top())); | ||
|
|
||
| if(isMandatory) this->flush(); | ||
| return numBytes; | ||
| } | ||
|
|
||
| bool spiFlash::cmp_io_priority:: operator()(const std::tuple<char, size_t, char*>& l, const std::tuple<char, size_t, char*>& r) const { | ||
| return std::get<0>(l) > std::get<0>(r); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| #ifndef SPI_FLASH_H | ||
| #define SPI_FLASH_H | ||
|
|
||
| #include <Arduino.h> | ||
| #include <SPI.h> | ||
| #include <SdFat.h> | ||
|
|
||
| #include <Adafruit_SPIFlash.h> | ||
|
|
||
| #include <queue> | ||
| #include <tuple> | ||
| #include <stdint.h> | ||
| #include <unistd.h> | ||
| #include <string.h> | ||
| #include <cmath> | ||
| #include <vector> | ||
| #include <fstream> | ||
| #include <iostream> | ||
|
|
||
| //TODO: Documentation | ||
| class spiFlash { | ||
| public: | ||
|
|
||
| static constexpr const char | ||
| P_MANDATORY = 0, //just force writes this at next tick | ||
| P_URGENT = 1, | ||
| P_IMPORTANT = 2, | ||
| P_STD = 3, | ||
| P_UNIMPORTANT = 4, | ||
| P_OPTIONAL = 5 | ||
| ; | ||
| //Constructor: | ||
| spiFlash (const size_t buffer_size = 512, const size_t k_buffer_size = 512) ; | ||
|
|
||
| //destructor: | ||
| ~spiFlash(); | ||
|
|
||
| //setup function: | ||
| bool startUp(); | ||
|
|
||
| //Get Methods: | ||
| uint8_t getCS_PIN(); | ||
|
|
||
| //functionality methods: | ||
|
|
||
| char buffer (const size_t bytes, const char* data); | ||
|
|
||
| char flush (void); | ||
|
|
||
| ssize_t kLog (const size_t bytes, const char* data); | ||
|
|
||
| char kflush (void); | ||
|
|
||
| ssize_t kwrite (const size_t bytes, const char* data); | ||
|
|
||
| char queue (size_t bytes, char* data, char priority = P_UNIMPORTANT); | ||
|
|
||
| ssize_t read (const size_t offset, const size_t bytes, char* buffer); | ||
|
|
||
| ssize_t tick (void); | ||
|
|
||
| ssize_t write (const size_t bytes, const char* data); | ||
|
|
||
| //types | ||
| struct cmp_io_priority { | ||
| bool operator()(const std::tuple<char, size_t, char*>& l, const std::tuple<char, size_t, char*>& r) const ; | ||
| }; | ||
|
|
||
| const size_t buffer_size; | ||
| const size_t k_buffer_size; | ||
|
|
||
| private: | ||
| uint8_t CS_PIN; | ||
|
|
||
| std::priority_queue< | ||
| // priority size data | ||
| std::tuple<char, size_t, char*>, | ||
| std::vector<std::tuple<char, size_t, char*>>, | ||
| cmp_io_priority | ||
| > queuedos; | ||
|
|
||
| char* obuff; | ||
| size_t buffer_offset; | ||
|
|
||
| char* kbuff; | ||
| size_t k_buffer_offset; | ||
|
|
||
| #ifdef NOBOARD_TEST | ||
| int fd, kfd; | ||
| #endif | ||
| }; | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| #include "spiFlash.h" | ||
| #include <string.h> | ||
|
|
||
| class SpiFlashTester{ | ||
| private: | ||
| void printResult(const char* testName, bool passed) { | ||
| Serial.print(testName); | ||
| Serial.print(": "); | ||
| Serial.println(passed ? "PASS" : "FAIL"); | ||
| } | ||
|
|
||
| void testStartUp(){ | ||
| spiFlash spiFlash(256, 128); | ||
| bool ok = spiFlash.startUp(); | ||
| printResult("StartUp test: ", ok); | ||
| } | ||
|
|
||
| void testReadWrite(){ | ||
| spiFlash spiFlash(256, 128); | ||
| spiFlash.startUp(); | ||
|
|
||
| const char msg = "HELLO ROCKET TEAM!!"; | ||
| char readback[sizeof(msg)] = {0}; // open memory for our data | ||
|
|
||
| ssize_t written = spiFlash.write(sizeof(msg), msg); // save what the flash interprets from our message | ||
| ssize_t read = spiFlash.read(0, sizeof(msg), readback); // read the data into space we opened for it | ||
|
|
||
| bool test = ((written == sizeof(msg)) && (read == sizeof(msg)) && !std::memcmp(written, read, sizeof(msg))); | ||
| printResult("Basic Read Write test: ", ok); | ||
| } | ||
|
|
||
| void testBufferFlush() { | ||
| spiFlash spiFlash(256, 128); | ||
| spiFlash.startUp(); | ||
|
|
||
| const char msg[] = "BUFFERED"; | ||
| char out[sizeof(msg)] = {0}; | ||
|
|
||
| spiFlash.buffer(sizeof(msg), msg); | ||
| spiFlash.flush(); | ||
| spiFlash.read(0, sizeof(msg), out); | ||
|
|
||
| bool ok = !std::memcmp(msg, out, sizeof(msg)); | ||
| printResult("Buffer flush: ", ok); | ||
| } | ||
|
|
||
| void testQueuePriority() { | ||
| spiFlash spiFlash(256, 128); | ||
| spiFlash.startUp(); | ||
|
|
||
| char low[] = "LOW"; | ||
| char high[] = "HIGH"; | ||
|
|
||
| spiFlash.queue(sizeof(low), low, spiFlash::P_UNIMPORTANT); | ||
| spiFlash.queue(sizeof(high), high, spiFlash::P_URGENT); | ||
|
|
||
| while (spiFlash.tick() > 0) {} | ||
|
|
||
| char out1[5] = {0}; | ||
| char out2[4] = {0}; | ||
|
|
||
| spiFlash.read(0, sizeof(high), out1); | ||
| spiFlash.read(sizeof(high), sizeof(low), out2); | ||
|
|
||
| bool ok = (std::strcmp(out1, "HIGH") == 0 && std::strcmp(out2, "LOW") == 0); | ||
| printResult("Queue priority: ", ok); | ||
| } | ||
|
|
||
|
|
||
| public: | ||
| void run() { | ||
| Serial.println("SPI Flash Tester: start"); | ||
| testStartup(); | ||
| testReadWrite(); | ||
| testBufferFlush(); | ||
| testQueuePriority(); | ||
| Serial.println("SPI Flash Tester: done"); | ||
| } | ||
| ~SpiFlashTester(); | ||
|
|
||
| }; | ||
|
|
||
| SpiFlashTester:: SpiFlashTester() = default; | ||
| SpiFlashTester::~SpiFlashTester() = default; | ||
|
|
||
| void setup () { | ||
| auto tester = SpiFlashTester(); | ||
| tester.run(); | ||
| } | ||
|
|
||
| void loop () { | ||
| delay(100); //so we dont fry the arduino | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move to blaze-lite/core/test