Skip to content

Commit

Permalink
Latest changes to V3 firmware - still WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
maxritter committed Jun 30, 2021
1 parent f2881e1 commit f9db764
Show file tree
Hide file tree
Showing 37 changed files with 276 additions and 2,364 deletions.
5 changes: 3 additions & 2 deletions Firmware_V3/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ This guide should work on **all common operating systems** (**Windows, Linux & M
**Download** and **install** the following programs:

1. [VS Code](https://code.visualstudio.com/)
2. [PlatformIO for VS Code](https://platformio.org/install/ide?install=vscode)
2. [PlatformIO Core](https://docs.platformio.org/en/latest//core/installation.html)
3. [PlatformIO for VS Code](https://platformio.org/install/ide?install=vscode)

Then **clone this repo**:
`git clone https://github.com/maxritter/DIY-Thermocam/tree/master/Firmware_V3`.

The **Teensyduino** version that comes pre-installed with PlatformIO does not support Mass Storage Mode (MTP), so we **need to update it**. Extract the content of `other/platformio_teensy4.zip` to: `C:\Users\<YOUR_ACCOUNT>\.platformio\packages\framework-arduinoteensy` (filepath on Windows or Mac is different, I am using Windows) and overwrite any existing files.
The **Teensyduino** version that comes pre-installed with PlatformIO does not support Mass Storage Mode (MTP), so we **need to update it**. Extract the content of `other/platformio_teensy4.zip` to: `C:\Users\<YOUR_ACCOUNT>\.platformio` (filepath on Windows or Mac is different, I am using Windows) and overwrite any existing files.

Now **start VS Code** and open the folder that you have just cloned with **File -> Open Folder**.

Expand Down
41 changes: 40 additions & 1 deletion Firmware_V3/lib/EEPROM/EEPROM.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
// this file no longer used
#include <Arduino.h>
#include <EEPROM.h>

// put - Specialization for Arduino Strings -------------------------------
// to put an Arduino String to the EEPROM we copy its internal buffer
// including the trailing \0 to the eprom

template <>
const String &EEPROMClass::put(int idx, const String &s)
{
const uint8_t *ptr = (uint8_t *)s.c_str();

#ifdef __arm__
eeprom_write_block(ptr, (void *)idx, s.length() + 1); // length() doesn't account for the trailing \0
#else
EEPtr e = idx;
for (int count = s.length() + 1; count; --count, ++e)
(*e).update(*ptr++);
#endif
return s;
}

// get - Specialization for Arduino Strings -------------------------------
// to "get" an Arduino String from the EEPROM we append chars from the EEPROM
// into it until we find the delimiting /0.
// String.append is not very efficient, code could probably be opitimized if required...

template <>
String &EEPROMClass::get(int idx, String &s){
s = ""; // just in case...
EEPtr e = idx;

char c = *e; // read in bytes until we find the terminating \0
while (c != '\0') {
s.append(c);
c = *(++e);
}
return s;
}

13 changes: 12 additions & 1 deletion Firmware_V3/lib/EEPROM/EEPROM.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
#include <avr/eeprom.h>
#include <avr/io.h>

#if defined(__has_include) && __has_include(<type_traits>)
#include <type_traits>
#endif


/***
EERef class.
Expand Down Expand Up @@ -134,13 +138,19 @@ struct EEPROMClass{

//Functionality to 'get' and 'put' objects to and from EEPROM.
template< typename T > T &get( int idx, T &t ){
#if defined(__has_include) && __has_include(<type_traits>)
static_assert(std::is_trivially_copyable<T>::value,"You can not use this type with EEPROM.get" ); // the code below only makes sense if you can "memcpy" T
#endif
EEPtr e = idx;
uint8_t *ptr = (uint8_t*) &t;
for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = *e;
return t;
}

template< typename T > const T &put( int idx, const T &t ){
template< typename T > const T &put( int idx, const T &t ){
#if defined(__has_include) && __has_include(<type_traits>)
static_assert(std::is_trivially_copyable<T>::value, "You can not use this type with EEPROM.get"); // the code below only makes sense if you can "memcpy" T
#endif
const uint8_t *ptr = (const uint8_t*) &t;
#ifdef __arm__
eeprom_write_block(ptr, (void *)idx, sizeof(T));
Expand All @@ -152,5 +162,6 @@ struct EEPROMClass{
}
};


static EEPROMClass EEPROM __attribute__ ((unused));
#endif
6 changes: 3 additions & 3 deletions Firmware_V3/lib/LittleFS/LittleFS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ uint32_t LittleFS::formatUnused(uint32_t blockCnt, uint32_t blockStart) {
}

FLASHMEM
bool LittleFS::lowLevelFormat(char progressChar)
bool LittleFS::lowLevelFormat(char progressChar, Print* pr)
{
if (!configured) return false;
if (mounted) {
Expand All @@ -330,13 +330,13 @@ bool LittleFS::lowLevelFormat(char progressChar)
int ii=config.block_count/120;
void *buffer = malloc(config.read_size);
for (unsigned int block=0; block < config.block_count; block++) {
if (progressChar && (0 == block%ii) ) Serial.write(progressChar);
if (pr && progressChar && (0 == block%ii) ) pr->write(progressChar);
if (!blockIsBlank(&config, block, buffer)) {
(*config.erase)(&config, block);
}
}
free(buffer);
if (progressChar) Serial.println();
if (pr && progressChar) pr->println();
return quickFormat();
}

Expand Down
138 changes: 133 additions & 5 deletions Firmware_V3/lib/LittleFS/LittleFS.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <FS.h>
#include <SPI.h>
#include "littlefs/lfs.h"
//#include <algorithm>

class LittleFSFile : public File
{
Expand Down Expand Up @@ -199,7 +200,7 @@ class LittleFS : public FS
config.context = nullptr;
}
bool quickFormat();
bool lowLevelFormat(char progressChar=0);
bool lowLevelFormat(char progressChar=0, Print* pr=&Serial);
uint32_t formatUnused(uint32_t blockCnt, uint32_t blockStart);
File open(const char *filepath, uint8_t mode = FILE_READ) {
//Serial.println("LittleFS open");
Expand Down Expand Up @@ -298,7 +299,7 @@ class LittleFS_RAM : public LittleFS
//Serial.println("configure "); delay(5);
configured = false;
if (!ptr) return false;
memset(ptr, 0xFF, size); // always start with blank slate
// memset(ptr, 0xFF, size); // always start with blank slate
size = size & 0xFFFFFF00;
memset(&lfs, 0, sizeof(lfs));
memset(&config, 0, sizeof(config));
Expand Down Expand Up @@ -329,9 +330,12 @@ class LittleFS_RAM : public LittleFS
config.file_max = 0;
config.attr_max = 0;
configured = true;
if (lfs_format(&lfs, &config) < 0) return false;
//Serial.println("formatted");
if (lfs_mount(&lfs, &config) < 0) return false;
if (lfs_mount(&lfs, &config) < 0) {
memset(ptr, 0xFF, size); // always start with blank slate
if (lfs_format(&lfs, &config) < 0) return false;
//Serial.println("formatted");
if (lfs_mount(&lfs, &config) < 0) return false;
}
//Serial.println("mounted atfer format");
mounted = true;
return true;
Expand Down Expand Up @@ -361,6 +365,10 @@ class LittleFS_RAM : public LittleFS
return 0;
}
static int static_sync(const struct lfs_config *c) {
if ( c->context >= (void *)0x20200000 ) {
//Serial.printf(" arm_dcache_flush_delete: ptr=0x%x, size=%d\n", c->context, c->block_count * c->block_size);
arm_dcache_flush_delete(c->context, c->block_count * c->block_size );
}
return 0;
}
};
Expand Down Expand Up @@ -512,7 +520,127 @@ class LittleFS_Program : public LittleFS
};
#endif

class LittleFS_SPINAND : public LittleFS
{
public:
LittleFS_SPINAND() {
port = nullptr;
}
bool begin(uint8_t cspin, SPIClass &spiport=SPI);
uint8_t readECC(uint32_t address, uint8_t *data, int length);
void readBBLUT(uint16_t *LBA, uint16_t *PBA, uint8_t *linkStatus);
bool lowLevelFormat(char progressChar, Print* pr=&Serial);
uint8_t addBBLUT(uint32_t block_address); //temporary for testing

private:
int read(lfs_block_t block, lfs_off_t offset, void *buf, lfs_size_t size);
int prog(lfs_block_t block, lfs_off_t offset, const void *buf, lfs_size_t size);
int erase(lfs_block_t block);
int wait(uint32_t microseconds);
static int static_read(const struct lfs_config *c, lfs_block_t block,
lfs_off_t offset, void *buffer, lfs_size_t size) {
//Serial.printf(" flash rd: block=%d, offset=%d, size=%d\n", block, offset, size);
return ((LittleFS_SPINAND *)(c->context))->read(block, offset, buffer, size);
}
static int static_prog(const struct lfs_config *c, lfs_block_t block,
lfs_off_t offset, const void *buffer, lfs_size_t size) {
//Serial.printf(" flash wr: block=%d, offset=%d, size=%d\n", block, offset, size);
return ((LittleFS_SPINAND *)(c->context))->prog(block, offset, buffer, size);
}
static int static_erase(const struct lfs_config *c, lfs_block_t block) {
//Serial.printf(" flash er: block=%d\n", block);
return ((LittleFS_SPINAND *)(c->context))->erase(block);
}
static int static_sync(const struct lfs_config *c) {
return 0;
}
bool isReady();
bool writeEnable();
void eraseSector(uint32_t address);
void writeStatusRegister(uint8_t reg, uint8_t data);
uint8_t readStatusRegister(uint16_t reg, bool dump);
void loadPage(uint32_t address);

void deviceReset();

SPIClass *port;
uint8_t pin;
uint8_t addrbits;
uint32_t progtime;
uint32_t erasetime;
uint32_t chipsize;
uint32_t blocksize;

private:
uint8_t die = 0; //die = 0: use first 1GB die PA[16], die = 1: use second 1GB die PA[16].
uint8_t dies = 0; //used for W25M02
uint32_t capacityID ; // capacity
uint32_t deviceID;

uint16_t eccSize = 64;
uint16_t PAGE_ECCSIZE = 2112;

};


#if defined(__IMXRT1062__)
class LittleFS_QPINAND : public LittleFS
{
public:
LittleFS_QPINAND() { }
bool begin();
bool deviceErase();
uint8_t readECC(uint32_t targetPage, uint8_t *buf, int size);
void readBBLUT(uint16_t *LBA, uint16_t *PBA, uint8_t *linkStatus);
bool lowLevelFormat(char progressChar);
uint8_t addBBLUT(uint32_t block_address); //temporary for testing

private:
int read(lfs_block_t block, lfs_off_t offset, void *buf, lfs_size_t size);
int prog(lfs_block_t block, lfs_off_t offset, const void *buf, lfs_size_t size);
int erase(lfs_block_t block);
int wait(uint32_t microseconds);
static int static_read(const struct lfs_config *c, lfs_block_t block,
lfs_off_t offset, void *buffer, lfs_size_t size) {
//Serial.printf("..... flash rd: block=%d, offset=%d, size=%d\n", block, offset, size);
return ((LittleFS_QPINAND *)(c->context))->read(block, offset, buffer, size);
}
static int static_prog(const struct lfs_config *c, lfs_block_t block,
lfs_off_t offset, const void *buffer, lfs_size_t size) {
//Serial.printf("..... flash wr: block=%d, offset=%d, size=%d\n", block, offset, size);
return ((LittleFS_QPINAND *)(c->context))->prog(block, offset, buffer, size);
}
static int static_erase(const struct lfs_config *c, lfs_block_t block) {
//Serial.printf("..... flash er: block=%d\n", block);
return ((LittleFS_QPINAND *)(c->context))->erase(block);
}
static int static_sync(const struct lfs_config *c) {
return 0;
}
bool isReady();
bool writeEnable();
void deviceReset();
void eraseSector(uint32_t address);
void writeStatusRegister(uint8_t reg, uint8_t data);
uint8_t readStatusRegister(uint16_t reg, bool dump);

uint8_t addrbits;
uint32_t progtime;
uint32_t erasetime;
uint32_t chipsize;
uint32_t blocksize;

private:
uint8_t die = 0; //die = 0: use first 1GB die, die = 1: use second 1GB die.
uint8_t dies;
uint32_t capacityID ; // capacity
uint32_t deviceID;

uint16_t eccSize = 64;
uint16_t PAGE_ECCSIZE = 2112;

};
#endif



Expand Down
Loading

0 comments on commit f9db764

Please sign in to comment.