spiFlash: add flash_model, method to convert len to block protect and block protect to len
This commit is contained in:
parent
22c095547e
commit
ddcf8fd1b1
|
|
@ -7,12 +7,13 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "ftdipp_mpsse.hpp"
|
|
||||||
#include "progressBar.hpp"
|
#include "progressBar.hpp"
|
||||||
#include "display.hpp"
|
#include "display.hpp"
|
||||||
#include "spiFlash.hpp"
|
#include "spiFlash.hpp"
|
||||||
|
#include "spiFlashdb.hpp"
|
||||||
#include "spiInterface.hpp"
|
#include "spiInterface.hpp"
|
||||||
|
|
||||||
/* read/write status register : 0B addr + 0 dummy */
|
/* read/write status register : 0B addr + 0 dummy */
|
||||||
|
|
@ -55,8 +56,10 @@
|
||||||
/* Global Block Protection unlock */
|
/* Global Block Protection unlock */
|
||||||
#define FLASH_ULBPR 0x98
|
#define FLASH_ULBPR 0x98
|
||||||
|
|
||||||
SPIFlash::SPIFlash(SPIInterface *spi, int8_t verbose):_spi(spi), _verbose(verbose)
|
SPIFlash::SPIFlash(SPIInterface *spi, int8_t verbose):_spi(spi),
|
||||||
|
_verbose(verbose), _jedec_id(0), _flash_model(NULL)
|
||||||
{
|
{
|
||||||
|
read_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SPIFlash::bulk_erase()
|
int SPIFlash::bulk_erase()
|
||||||
|
|
@ -281,30 +284,39 @@ void SPIFlash::read_id()
|
||||||
|
|
||||||
if (_verbose > 0)
|
if (_verbose > 0)
|
||||||
printf("read %x\n", _jedec_id);
|
printf("read %x\n", _jedec_id);
|
||||||
|
auto t = flash_list.find(_jedec_id >> 8);
|
||||||
|
if (t != flash_list.end()) {
|
||||||
|
_flash_model = &(*t).second;
|
||||||
|
char content[256];
|
||||||
|
snprintf(content, 256, "Detected: %s %s %u sectors size: %uMb",
|
||||||
|
_flash_model->manufacturer.c_str(), _flash_model->model.c_str(),
|
||||||
|
_flash_model->nr_sector, _flash_model->nr_sector * 0x80000 / 1048576);
|
||||||
|
printInfo(content);
|
||||||
|
} else {
|
||||||
|
/* read extented */
|
||||||
|
if ((_jedec_id & 0xff) != 0) {
|
||||||
|
has_edid = true;
|
||||||
|
len += (_jedec_id & 0x0ff);
|
||||||
|
_spi->spi_put(0x9F, NULL, rx, len);
|
||||||
|
}
|
||||||
|
|
||||||
/* read extented */
|
/* must be 0x20BA1810 ... */
|
||||||
if ((_jedec_id & 0xff) != 0) {
|
|
||||||
has_edid = true;
|
|
||||||
len += (_jedec_id & 0x0ff);
|
|
||||||
_spi->spi_put(0x9F, NULL, rx, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* must be 0x20BA1810 ... */
|
printf("Detail: \n");
|
||||||
|
printf("Jedec ID : %02x\n", rx[0]);
|
||||||
printf("Detail: \n");
|
printf("memory type : %02x\n", rx[1]);
|
||||||
printf("Jedec ID : %02x\n", rx[0]);
|
printf("memory capacity : %02x\n", rx[2]);
|
||||||
printf("memory type : %02x\n", rx[1]);
|
if (has_edid) {
|
||||||
printf("memory capacity : %02x\n", rx[2]);
|
printf("EDID + CFD length : %02x\n", rx[3]);
|
||||||
if (has_edid) {
|
printf("EDID : %02x%02x\n", rx[5], rx[4]);
|
||||||
printf("EDID + CFD length : %02x\n", rx[3]);
|
printf("CFD : ");
|
||||||
printf("EDID : %02x%02x\n", rx[5], rx[4]);
|
if (_verbose > 0) {
|
||||||
printf("CFD : ");
|
for (int i = 6; i < len; i++)
|
||||||
if (_verbose > 0) {
|
printf("%02x ", rx[i]);
|
||||||
for (int i = 6; i < len; i++)
|
printf("\n");
|
||||||
printf("%02x ", rx[i]);
|
} else {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
} else {
|
}
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -391,6 +403,45 @@ int SPIFlash::disable_protection()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* convert bp area (status register) to len in byte */
|
||||||
|
uint32_t SPIFlash::bp_to_len(uint8_t bp)
|
||||||
|
{
|
||||||
|
/* 0 -> no sectors protected */
|
||||||
|
if (bp == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* reconstruct code based on each BPx bit */
|
||||||
|
uint8_t tmp = 0;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
if ((bp & _flash_model->bp_offset[i]))
|
||||||
|
tmp |= (1 << i);
|
||||||
|
/* bp code is 2^(bp-1) sectors */
|
||||||
|
uint16_t nr_sectors = (1 << (tmp-1));
|
||||||
|
|
||||||
|
return nr_sectors * 0x10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert len (in byte) to bp (sector protection) */
|
||||||
|
uint8_t SPIFlash::len_to_bp(uint32_t len)
|
||||||
|
{
|
||||||
|
/* 0 -> no sector to protect */
|
||||||
|
if (len == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* round and divide by sector size */
|
||||||
|
len = ((len + 0xffff) & ~0xffff) / 0x10000;
|
||||||
|
|
||||||
|
/* convert size to basic BP code */
|
||||||
|
uint8_t bp = 1 + static_cast<int>(ceil(log2(len)));
|
||||||
|
/* reconstruct code based on each BPx bit */
|
||||||
|
uint8_t tmp = 0;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
if (bp >> i)
|
||||||
|
tmp |= _flash_model->bp_offset[i];
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
/* microchip SST26VF032B has a dedicated register
|
/* microchip SST26VF032B has a dedicated register
|
||||||
* to read sectors (un)lock status and another one to unlock
|
* to read sectors (un)lock status and another one to unlock
|
||||||
* sectors
|
* sectors
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,13 @@
|
||||||
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SPIFLASH_HPP
|
#ifndef SRC_SPIFLASH_HPP_
|
||||||
#define SPIFLASH_HPP
|
#define SRC_SPIFLASH_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "spiInterface.hpp"
|
#include "spiInterface.hpp"
|
||||||
|
#include "spiFlashdb.hpp"
|
||||||
|
|
||||||
class SPIFlash {
|
class SPIFlash {
|
||||||
public:
|
public:
|
||||||
|
|
@ -18,6 +21,10 @@ class SPIFlash {
|
||||||
/* protection */
|
/* protection */
|
||||||
int write_enable();
|
int write_enable();
|
||||||
int write_disable();
|
int write_disable();
|
||||||
|
/*!
|
||||||
|
* \brief disable protection for all sectors
|
||||||
|
* \return -1 if write enable or disabling failed
|
||||||
|
*/
|
||||||
int disable_protection();
|
int disable_protection();
|
||||||
/*!
|
/*!
|
||||||
* \brief unlock all sectors: specific to
|
* \brief unlock all sectors: specific to
|
||||||
|
|
@ -27,7 +34,13 @@ class SPIFlash {
|
||||||
bool global_unlock();
|
bool global_unlock();
|
||||||
/* erase */
|
/* erase */
|
||||||
int bulk_erase();
|
int bulk_erase();
|
||||||
|
/*!
|
||||||
|
* \brief erase one sector (64Kb)
|
||||||
|
*/
|
||||||
int sector_erase(int addr);
|
int sector_erase(int addr);
|
||||||
|
/*!
|
||||||
|
* \brief erase n sectors starting at base_addr
|
||||||
|
*/
|
||||||
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);
|
||||||
|
|
@ -62,10 +75,25 @@ class SPIFlash {
|
||||||
virtual void read_id();
|
virtual void read_id();
|
||||||
uint16_t readNonVolatileCfgReg();
|
uint16_t readNonVolatileCfgReg();
|
||||||
uint16_t readVolatileCfgReg();
|
uint16_t readVolatileCfgReg();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/*!
|
||||||
|
* \brief convert bit protect to len in byte
|
||||||
|
* \param[in] bp: byte protection
|
||||||
|
* \return protect area in byte
|
||||||
|
*/
|
||||||
|
uint32_t bp_to_len(uint8_t bp);
|
||||||
|
/*!
|
||||||
|
* \brief convert len (in byte) to corresponding bit protect
|
||||||
|
* \param[in] len: len in byte
|
||||||
|
* \return bp code (based on chip bp[x] position
|
||||||
|
*/
|
||||||
|
uint8_t len_to_bp(uint32_t len);
|
||||||
|
|
||||||
SPIInterface *_spi;
|
SPIInterface *_spi;
|
||||||
int8_t _verbose;
|
int8_t _verbose;
|
||||||
uint32_t _jedec_id; /**< CHIP ID */
|
uint32_t _jedec_id; /**< CHIP ID */
|
||||||
|
flash_t *_flash_model; /**< detect flash model */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // SRC_SPIFLASH_HPP_
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue