Skip to content

Instantly share code, notes, and snippets.

Created March 28, 2017 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/be60193ced7dbe85670b75ddea4d86db to your computer and use it in GitHub Desktop.
Save anonymous/be60193ced7dbe85670b75ddea4d86db to your computer and use it in GitHub Desktop.
#include "FlashManager.hpp"
extern "C" {
#include "spi_master.h"
}
FlashManager::FlashManager(freertos_spi_if *spi, SPI_C * spi_c_in) {
freertos_spi = spi;
spi_c = spi_c_in;
device.id = 0;
spi_disable(spi_c->OurSPI);
spi_set_clock_polarity(spi_c->OurSPI, device.id, 0); //Clock Polarity 0
spi_set_clock_phase(spi_c->OurSPI, device.id, 1); // !Clock Phase 0
spi_set_bits_per_transfer(spi_c->OurSPI, device.id, SPI_CSR_BITS_8_BIT);
spi_set_baudrate_div(spi_c->OurSPI, device.id, 2);
spi_set_transfer_delay(spi_c->OurSPI, device.id, 0x400, 0x100);
spi_configure_cs_behavior(spi_c->OurSPI, device.id, SPI_CS_KEEP_LOW);
spi_set_peripheral_chip_select_value(spi_c->OurSPI, spi_get_pcs(device.id));
spi_enable(spi_c->OurSPI);
spi_enable_clock(spi_c->OurSPI);
U8 readData[2];
FlashCommand cmd;
cmd.opcode = READ_SR;
cmd.address=0;
writeOpcode(cmd);
spi_read_packet(SPI, &readData[0], 2);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1);
//testFlashComms();
}
void FlashManager::testFlashComms() {
U8 testData[256];
U8 readData[256];
for(int i=0; i < 256; i++) {
testData[i] = i;
}
eraseFlash();
FlashCommand cmd;
cmd.opcode = READ_SR;
cmd.address=0;
writeOpcode(cmd);
uint32_t data = 0;
spi_read_packet(SPI, (uint8_t*)&data, 1);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1);
clearLockBits();
clearLockBits();
writeOpcode(cmd);
spi_read_packet(SPI, &readData[0], 2);
eraseBlock(0);
writeDataToFlash(0, &(testData[0]), 256);
waitForNotBusy();
cmd.opcode = FASTER_READ_ARRAY;
cmd.address = 0;//0x8DFF;
writeFullCommand(cmd,1);
spi_read_packet(SPI, &readData[0], 256);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1);
for(int i=0; i<256; i++) {
printf("Test value[%d]: %d : %d : %d\n", i, testData[i], readData[i], (testData[i] == readData[i]));
}
}
void FlashManager::readStatusRegisters() {
U8 readData[2];
FlashCommand cmd;
cmd.opcode = READ_SR;
cmd.address=0;
writeOpcode(cmd);
spi_read_packet(SPI, &readData[0], 2);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1);
}
void FlashManager::readSecurityRegisters() {
U8 readData[2];
FlashCommand cmd;
cmd.opcode = READ_SECTOR_PROTECT;
cmd.address = 0;
for(; cmd.address < (8*1024*1024);cmd.address+=(64*1024)) {
writeFullCommand(cmd,0);
spi_read_packet(SPI, &readData[0], 1);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1);
}
cmd.opcode = READ_SECTOR_LOCKDOWN;
cmd.address = 0;
for(; cmd.address < (8*1024*1024);cmd.address+=(64*1024)) {
writeFullCommand(cmd,0);
spi_read_packet(SPI, &readData[0], 1);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1);
}
}
void FlashManager::clearLockBits() {
U8 lockCmd[3];
writeEnable();
lockCmd[0] = WRITE_SR1;
lockCmd[1] = 0x02;
spi_deselect_device(SPI, &device);
spi_select_device(SPI, &device);
spi_write_packet(SPI, &(lockCmd[0]), 2);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0);
spi_deselect_device(SPI, &device);
waitForNotBusy();
// writeEnable();
// lockCmd[0] = WRITE_SR2;
// lockCmd[1] = 0x00;
// spi_deselect_device(SPI, &device);
// spi_select_device(SPI, &device);
// spi_write_packet(SPI, &(lockCmd[0]), 2);
// while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0);
// spi_deselect_device(SPI, &device);
// waitForNotBusy();
}
void FlashManager::unlockAllSectors() {
// FlashCommand cmd;
// cmd.opcode = UNPROTECT_SECTOR;
// cmd.address = 0;
// for(; cmd.address < (8*1024*1024);cmd.address+=(64*1024)) {
// writeEnable();
// writeFullCommand(cmd,0);
// spi_deselect_device(SPI, &device);
// waitForNotBusy();
// }
}
void FlashManager::writeEnable() {
FlashCommand cmd;
cmd.opcode = WRITE_ENABLE;
writeOpcode(cmd);
}
//Seriosuly, watch out. Data must be programmed on 256 byte boundaries and must be erased first.
//len is length in bytes
void FlashManager::writeDataToFlash(U32 addr, U8*data, U32 len) {
FlashCommand cmd;
writeEnable();
cmd.opcode = PROGRAM;
cmd.address = addr;
writeFullCommand(cmd, 0);
spi_write_packet(SPI, data, len);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0);
}
void FlashManager::readDataFromFlash(U32 addr, U8 *data, U32 len) {
FlashCommand cmd;
cmd.opcode = FASTER_READ_ARRAY;
cmd.address = addr;
writeFullCommand(cmd,1);
spi_read_packet(SPI, &data[0], len);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1);
}
void FlashManager::writeOpcode(FlashCommand cmd) {
spi_deselect_device(SPI, &device);
spi_select_device(SPI, &device);
spi_write_packet(SPI, &cmd.data[0], 1);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0);
}
void FlashManager::writeFullCommand(FlashCommand cmd, U8 dummy) {
U8 t = cmd.data[3];
cmd.data[3] = cmd.data[1];
cmd.data[1] = t;
spi_deselect_device(SPI, &device);
spi_select_device(SPI, &device);
spi_write_packet(SPI, &cmd.data[0], 4);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0);
if(dummy != 0) {
spi_write_packet(SPI, &cmd.data[0], dummy);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0);
}
}
void FlashManager::waitForNotBusy() {
FlashCommand cmd;
U8 readData;
int busy = 1;
cmd.opcode = READ_SR;
cmd.address=0;
writeOpcode(cmd);
while(busy) {
spi_read_packet(SPI, &readData, 1);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1);
if(!(readData & 0x1))
busy = 0;
}
}
void FlashManager::eraseBlock(U32 addr) {
writeEnable();
FlashCommand cmd;
cmd.opcode = BLOCK_ERASE_4K;
cmd.address = 0;
spi_deselect_device(SPI, &device);
spi_select_device(SPI, &device);
spi_write_packet(SPI, &cmd.data[0], 4);
spi_deselect_device(SPI, &device);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0);
waitForNotBusy();
}
void FlashManager::eraseFlash() {
writeEnable();
FlashCommand cmd;
cmd.opcode = CHIP_ERASE;
cmd.address = 0;
spi_deselect_device(SPI, &device);
spi_select_device(SPI, &device);
spi_write_packet(SPI, &cmd.data[0], 1);
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0);
spi_deselect_device(SPI, &device);
waitForNotBusy();
}
void FlashManager::sleep(void) {
FlashCommand cmd;
cmd.opcode = DEEP_POWER_DOWN;
writeOpcode(cmd);
}
void FlashManager::wake(void) {
FlashCommand cmd;
cmd.opcode = RESUME_FROM_DEEP_POWER_DOWN;
writeOpcode(cmd);
waitForNotBusy();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment