spiFlash: fix base addr, add method to read flash content and (non)volatile registers + cleanup
This commit is contained in:
parent
d64f6f5055
commit
4bfb764e75
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
@ -25,17 +26,6 @@
|
||||||
#include "spiFlash.hpp"
|
#include "spiFlash.hpp"
|
||||||
#include "spiInterface.hpp"
|
#include "spiInterface.hpp"
|
||||||
|
|
||||||
static uint8_t reverseByte(uint8_t src)
|
|
||||||
{
|
|
||||||
uint8_t dst = 0;
|
|
||||||
for (int i=0; i < 8; i++) {
|
|
||||||
dst = (dst << 1) | (src & 0x01);
|
|
||||||
src >>= 1;
|
|
||||||
}
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* read/write status register : 0B addr + 0 dummy */
|
/* read/write status register : 0B addr + 0 dummy */
|
||||||
#define FLASH_WRSR 0x01
|
#define FLASH_WRSR 0x01
|
||||||
#define FLASH_RDSR 0x05
|
#define FLASH_RDSR 0x05
|
||||||
|
|
@ -52,7 +42,10 @@ static uint8_t reverseByte(uint8_t src)
|
||||||
#define FLASH_POWER_DOWN 0xB9
|
#define FLASH_POWER_DOWN 0xB9
|
||||||
/* read/write non volatile register: 0B addr + 0 dummy */
|
/* read/write non volatile register: 0B addr + 0 dummy */
|
||||||
#define FLASH_RDNVCR 0xB5
|
#define FLASH_RDNVCR 0xB5
|
||||||
#define FLASH_WRNVCR 0x81
|
#define FLASH_WRNVCR 0xB1
|
||||||
|
/* read/write volatile register */
|
||||||
|
#define FLASH_RDVCR 0x85
|
||||||
|
#define FLASH_WRVCR 0x81
|
||||||
/* bulk erase */
|
/* bulk erase */
|
||||||
#define FLASH_BE 0xC7
|
#define FLASH_BE 0xC7
|
||||||
/* sector (64kb) erase */
|
/* sector (64kb) erase */
|
||||||
|
|
@ -64,9 +57,6 @@ static uint8_t reverseByte(uint8_t src)
|
||||||
#define FLASH_CLFSR 0x50
|
#define FLASH_CLFSR 0x50
|
||||||
#define FLASH_RFSR 0x70
|
#define FLASH_RFSR 0x70
|
||||||
/* */
|
/* */
|
||||||
#define FLASH_WRVCR 0x81
|
|
||||||
#define FLASH_RDVCR 0x85
|
|
||||||
/* */
|
|
||||||
#define FLASH_WRVECR 0x61
|
#define FLASH_WRVECR 0x61
|
||||||
#define FLASH_RDVECR 0x65
|
#define FLASH_RDVECR 0x65
|
||||||
|
|
||||||
|
|
@ -84,17 +74,19 @@ int SPIFlash::bulk_erase()
|
||||||
|
|
||||||
int SPIFlash::sector_erase(int addr)
|
int SPIFlash::sector_erase(int addr)
|
||||||
{
|
{
|
||||||
uint8_t tx[3] = {(uint8_t)(0xff & (addr >> 16)),
|
uint8_t tx[4];
|
||||||
(uint8_t)(0xff & (addr >> 8)),
|
tx[0] = (uint8_t)(FLASH_SE );
|
||||||
(uint8_t)(addr & 0xff)};
|
tx[1] = (uint8_t)(0xff & (addr >> 16));
|
||||||
_spi->spi_put(FLASH_SE, tx, NULL, 3);
|
tx[2] = (uint8_t)(0xff & (addr >> 8));
|
||||||
|
tx[3] = (uint8_t)(0xff & (addr ));
|
||||||
|
_spi->spi_put(tx, NULL, 4);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SPIFlash::sectors_erase(int base_addr, int size)
|
int SPIFlash::sectors_erase(int base_addr, int size)
|
||||||
{
|
{
|
||||||
int start_addr = base_addr;
|
int start_addr = base_addr;
|
||||||
int end_addr = (size + 0xffff) & ~0xffff;
|
int end_addr = (base_addr + size + 0xffff) & ~0xffff;
|
||||||
ProgressBar progress("Erasing", end_addr, 50);
|
ProgressBar progress("Erasing", end_addr, 50);
|
||||||
for (int addr = start_addr; addr < end_addr; addr += 0x10000) {
|
for (int addr = start_addr; addr < end_addr; addr += 0x10000) {
|
||||||
if (write_enable() == -1)
|
if (write_enable() == -1)
|
||||||
|
|
@ -113,15 +105,11 @@ int SPIFlash::write_page(int addr, uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
uint8_t tx[len+3];
|
uint8_t tx[len+3];
|
||||||
tx[0] = (uint8_t)(0xff & (addr >> 16));
|
tx[0] = (uint8_t)(0xff & (addr >> 16));
|
||||||
tx[1] = (uint8_t)(0xff & (addr >> 8));
|
tx[1] = (uint8_t)(0xff & (addr >> 8));
|
||||||
tx[2] = (uint8_t)(addr & 0xff);
|
tx[2] = (uint8_t)(0xff & (addr ));
|
||||||
|
|
||||||
|
memcpy(tx+3, data, len);
|
||||||
|
|
||||||
/*uint8_t tx[len+3] = {(uint8_t)(0xff & (addr >> 16)),
|
|
||||||
(uint8_t)(0xff & (addr >> 8)),
|
|
||||||
(uint8_t)(addr & 0xff)};*/
|
|
||||||
for (int i=0; i < len; i++) {
|
|
||||||
tx[i+3] = data[i];
|
|
||||||
}
|
|
||||||
if (write_enable() == -1)
|
if (write_enable() == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
@ -129,6 +117,22 @@ int SPIFlash::write_page(int addr, uint8_t *data, int len)
|
||||||
return _spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WIP, 0x00, 1000);
|
return _spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WIP, 0x00, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SPIFlash::read(int base_addr, uint8_t *data, int len)
|
||||||
|
{
|
||||||
|
uint8_t tx[len+3];
|
||||||
|
uint8_t rx[len+3];
|
||||||
|
tx[0] = (uint8_t)(0xff & (base_addr >> 16));
|
||||||
|
tx[1] = (uint8_t)(0xff & (base_addr >> 8));
|
||||||
|
tx[2] = (uint8_t)(0xff & (base_addr ));
|
||||||
|
|
||||||
|
int ret = _spi->spi_put(0x03, tx, rx, len+3);
|
||||||
|
if (ret == 0)
|
||||||
|
memcpy(data, rx+3, len);
|
||||||
|
else
|
||||||
|
printf("error\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int SPIFlash::erase_and_prog(int base_addr, uint8_t *data, int len)
|
int SPIFlash::erase_and_prog(int base_addr, uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
/* check Block Protect Bits */
|
/* check Block Protect Bits */
|
||||||
|
|
@ -140,14 +144,14 @@ int SPIFlash::erase_and_prog(int base_addr, uint8_t *data, int len)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ProgressBar progress("Writing", len, 50);
|
ProgressBar progress("Writing", len, 50);
|
||||||
if (sectors_erase(0, len) == -1)
|
if (sectors_erase(base_addr, len) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
uint8_t *ptr = data;
|
uint8_t *ptr = data;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
for (int addr = base_addr; addr < len; addr += size, ptr+=size) {
|
for (int addr = 0; addr < len; addr += size, ptr+=size) {
|
||||||
size = (addr + 256 > len)?(len-addr) : 256;
|
size = (addr + 256 > len)?(len-addr) : 256;
|
||||||
if (write_page(addr, ptr, size) == -1)
|
if (write_page(base_addr + addr, ptr, size) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
progress.display(addr);
|
progress.display(addr);
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +161,8 @@ int SPIFlash::erase_and_prog(int base_addr, uint8_t *data, int len)
|
||||||
|
|
||||||
void SPIFlash::reset()
|
void SPIFlash::reset()
|
||||||
{
|
{
|
||||||
uint8_t data[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
uint8_t data[8];
|
||||||
|
memset(data, 0xff, 8);
|
||||||
_spi->spi_put(0xff, data, NULL, 8);
|
_spi->spi_put(0xff, data, NULL, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,6 +226,24 @@ uint8_t SPIFlash::read_status_reg()
|
||||||
return rx;
|
return rx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t SPIFlash::readNonVolatileCfgReg()
|
||||||
|
{
|
||||||
|
uint8_t rx[2];
|
||||||
|
_spi->spi_put(FLASH_RDNVCR, NULL, rx, 2);
|
||||||
|
if (_verbose)
|
||||||
|
printf("Non Volatile %x %x\n", rx[0], rx[1]);
|
||||||
|
return (rx[1] << 8) | rx[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t SPIFlash::readVolatileCfgReg()
|
||||||
|
{
|
||||||
|
uint8_t rx[2];
|
||||||
|
_spi->spi_put(FLASH_RDVCR, NULL, rx, 2);
|
||||||
|
if (_verbose)
|
||||||
|
printf("Volatile %x %x\n", rx[0], rx[1]);
|
||||||
|
return (rx[1] << 8) | rx[0];
|
||||||
|
}
|
||||||
|
|
||||||
void SPIFlash::power_up()
|
void SPIFlash::power_up()
|
||||||
{
|
{
|
||||||
_spi->spi_put(FLASH_POWER_UP, NULL, NULL, 0);
|
_spi->spi_put(FLASH_POWER_UP, NULL, NULL, 0);
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,15 @@ class SPIFlash {
|
||||||
int sectors_erase(int base_addr, int len);
|
int sectors_erase(int base_addr, int len);
|
||||||
/* write */
|
/* write */
|
||||||
int write_page(int addr, uint8_t *data, int len);
|
int write_page(int addr, uint8_t *data, int len);
|
||||||
|
/* read */
|
||||||
|
int read(int base_addr, uint8_t *data, int len);
|
||||||
/* combo flash + erase */
|
/* combo flash + erase */
|
||||||
int erase_and_prog(int base_addr, uint8_t *data, int len);
|
int erase_and_prog(int base_addr, uint8_t *data, int len);
|
||||||
/* display/info */
|
/* display/info */
|
||||||
uint8_t read_status_reg();
|
uint8_t read_status_reg();
|
||||||
void read_id();
|
void read_id();
|
||||||
|
uint16_t readNonVolatileCfgReg();
|
||||||
|
uint16_t readVolatileCfgReg();
|
||||||
private:
|
private:
|
||||||
SPIInterface *_spi;
|
SPIInterface *_spi;
|
||||||
bool _verbose;
|
bool _verbose;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue