mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-02-27 01:25:41 +08:00
Second Pass rewrite of flashmem. added command 'mem spibaud' to switch between 24/48Mhz operation. All is more consistant, less messy. All logic rewrittent avoiding multiple flashinit/flashstop. busywait is now at it's lowest possible. Beware : 48Mhz is VERY buggy cause of sillicon bug (see source for more info), and doesn't give much more than 24Mhz for now since we doubled nearly every operation speed here.
This commit is contained in:
parent
76e2d7502a
commit
368fe11df0
5 changed files with 201 additions and 189 deletions
|
@ -153,10 +153,11 @@ void SpinUp(uint32_t speed)
|
|||
LED_D_OFF();
|
||||
}
|
||||
|
||||
void TestFlashmemSpeed(size_t buffersize, bool fastmode)
|
||||
void TestFlashmemSpeed(size_t buffersize, uint32_t spibaudrate)
|
||||
{
|
||||
|
||||
DbprintfEx(FLAG_NOLOG, "%s---+----[ %s %s[%dKB] %s]", _GREEN_, _WHITE_, _YELLOW_, buffersize / 1024, _WHITE_);
|
||||
FLASHMEM_SPIBAUDRATE = spibaudrate*1000000;
|
||||
DbprintfEx(FLAG_NOLOG, "%s---+----[ %s %s[%dKB] %s] (%d)", _GREEN_, _WHITE_, _YELLOW_, buffersize / 1024, _WHITE_, FLASHMEM_SPIBAUDRATE);
|
||||
uint16_t t = 0;
|
||||
|
||||
LED_B_ON();
|
||||
|
@ -166,10 +167,10 @@ void TestFlashmemSpeed(size_t buffersize, bool fastmode)
|
|||
uint32_t startidx = 0;
|
||||
uint32_t numofbytes = 0x3FFFF;
|
||||
|
||||
if (!FlashInit(fastmode)) {
|
||||
if (!FlashInit()) {
|
||||
return;
|
||||
}
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
//Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
|
||||
//Flash_ReadStat1();
|
||||
|
||||
|
@ -183,14 +184,7 @@ void TestFlashmemSpeed(size_t buffersize, bool fastmode)
|
|||
//isok = Flash_ReadData(startidx + i, mem, len);
|
||||
//uint32_t iend_time;
|
||||
//uint32_t istart_time = iend_time = GetTickCount();
|
||||
if (fastmode)
|
||||
{
|
||||
isok = Flash_FastReadDataCont(startidx + i, mem, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
isok = Flash_ReadDataCont(startidx + i, mem, len);
|
||||
}
|
||||
isok = Flash_ReadDataCont(startidx + i, mem, len);
|
||||
//iend_time = GetTickCount();
|
||||
//DbprintfEx(FLAG_RAWPRINT, "%s%dms%s>", _YELLOW_, iend_time - istart_time, _WHITE_);
|
||||
//cjSetCursLeft();
|
||||
|
@ -199,7 +193,7 @@ void TestFlashmemSpeed(size_t buffersize, bool fastmode)
|
|||
Dbprintf("[FAIL] reading flash memory failed :: | bytes between %d - %d", i, len);
|
||||
return;
|
||||
}
|
||||
//isok = cmd_send(CMD_DOWNLOADED_FLASHMEM, i, len, 0, mem, len);
|
||||
//isok = cmd_send(CMD_FLASHMEM_DOWNLOADED, i, len, 0, mem, len);
|
||||
//if (!isok)
|
||||
// Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
|
||||
t++;
|
||||
|
@ -213,6 +207,29 @@ void TestFlashmemSpeed(size_t buffersize, bool fastmode)
|
|||
FlashStop();
|
||||
}
|
||||
|
||||
void TestFlashmemRoutine()
|
||||
{
|
||||
DbprintfEx(FLAG_NOLOG, "%s>>%s Will Now Test dumping Full flash [256Kb] (2Mbits)through Bigbuf buffers\n", _GREEN_, _WHITE_);
|
||||
MF_DBGLEVEL = MF_DBG_NONE;
|
||||
//DbprintfEx(FLAG_NOLOG, "---------\n%s[A]%s Using NORMAL Reads @Max (24Mhz=MCK/2)\n--------", _GREEN_, _WHITE_);
|
||||
TestFlashmemSpeed(32768,24);
|
||||
TestFlashmemSpeed(16384 + 4096 + 4096,24);
|
||||
TestFlashmemSpeed(16384,24);
|
||||
TestFlashmemSpeed(4096,24);
|
||||
TestFlashmemSpeed(1024,24);
|
||||
//SpinDelay(1000);
|
||||
//WDT_HIT();
|
||||
//DbprintfEx(FLAG_NOLOG, "--------\n%s[B]%s Using FAST Reads @Max (48Mhz=MCK=CPUClock/2=MAXSPI)\n--------", _GREEN_, _WHITE_);
|
||||
TestFlashmemSpeed(32768,48);
|
||||
TestFlashmemSpeed(16384 + 4096 + 4096,48);
|
||||
TestFlashmemSpeed(16384,48);
|
||||
TestFlashmemSpeed(4096,48);
|
||||
TestFlashmemSpeed(1024,48);
|
||||
//SpinDelay(1000);
|
||||
//WDT_HIT();
|
||||
return;
|
||||
}
|
||||
|
||||
void ReadLastTagFromFlash()
|
||||
{
|
||||
|
||||
|
@ -231,11 +248,12 @@ void ReadLastTagFromFlash()
|
|||
size_t size = len;
|
||||
uint8_t *mem = BigBuf_malloc(size);
|
||||
|
||||
//if (!FlashFastReadInit()){
|
||||
if (!FlashInit(0))
|
||||
if (!FlashInit())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
|
||||
//Flash_ReadStat1();
|
||||
|
||||
uint32_t end_time;
|
||||
|
@ -256,8 +274,8 @@ void ReadLastTagFromFlash()
|
|||
{
|
||||
DbprintfEx(FLAG_NOLOG, "FlashMem reading failed | %d | %d", len, isok);
|
||||
cjSetCursLeft();
|
||||
SpinOff(100);
|
||||
FlashStop();
|
||||
SpinOff(100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -292,11 +310,12 @@ void WriteTagToFlash(uint8_t index, size_t size)
|
|||
emlGetMem(data, 0, (size * 64)/1024);
|
||||
|
||||
//if (!FlashFastReadInit()){
|
||||
if (!FlashInit(0))
|
||||
if (!FlashInit())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable();
|
||||
Flash_Erase4k(0,0);
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
|
@ -492,25 +511,8 @@ ACCBITS : 796788[00]+VALUE
|
|||
SpinDown(50);
|
||||
|
||||
#if 0
|
||||
DbprintfEx(FLAG_NOLOG, "%s>>%s Will Now Test dumping Full flash [256Kb] (2Mbits)through Bigbuf buffers\n", _GREEN_, _WHITE_);
|
||||
MF_DBGLEVEL = MF_DBG_NONE;
|
||||
DbprintfEx(FLAG_NOLOG, "---------\n%s[A]%s Using NORMAL Reads @Max (24Mhz=MCK/2)\n--------", _GREEN_, _WHITE_);
|
||||
TestFlashmemSpeed(32768,0);
|
||||
TestFlashmemSpeed(16384 + 4096 + 4096,0);
|
||||
TestFlashmemSpeed(16384,0);
|
||||
TestFlashmemSpeed(4096,0);
|
||||
TestFlashmemSpeed(1024,0);
|
||||
SpinDelay(1000);
|
||||
WDT_HIT();
|
||||
DbprintfEx(FLAG_NOLOG, "--------\n%s[B]%s Using FAST Reads @Max (48Mhz=MCK=CPUClock/2=MAXSPI)\n--------", _GREEN_, _WHITE_);
|
||||
TestFlashmemSpeed(32768,1);
|
||||
TestFlashmemSpeed(16384 + 4096 + 4096,1);
|
||||
TestFlashmemSpeed(16384,1);
|
||||
TestFlashmemSpeed(4096,1);
|
||||
TestFlashmemSpeed(1024,1);
|
||||
SpinDelay(1000);
|
||||
WDT_HIT();
|
||||
return;
|
||||
TestFlashmemRoutine();
|
||||
return;
|
||||
#endif
|
||||
|
||||
failtag:
|
||||
|
|
|
@ -52,6 +52,7 @@ void WriteTagToFlash(uint8_t index, size_t size);
|
|||
|
||||
const char clearTerm[8] = {0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x32, 0x4a, '\0'};
|
||||
|
||||
void TestFlashmemSpeed(size_t buffersize, uint32_t spibaudrate);
|
||||
|
||||
|
||||
#define LOGO logo_kigiv
|
||||
|
|
130
armsrc/appmain.c
130
armsrc/appmain.c
|
@ -33,6 +33,10 @@
|
|||
#include "i2c.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_FPC
|
||||
#include "usart.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// A buffer where we can queue things up to be sent through the FPGA, for
|
||||
// any purpose (fake tag, as reader, whatever). We go MSB first, since that
|
||||
|
@ -74,24 +78,26 @@ void PrintToSendBuffer(void) {
|
|||
}
|
||||
|
||||
void print_result(char *name, uint8_t *buf, size_t len) {
|
||||
uint8_t *p = buf;
|
||||
|
||||
if ( len % 16 == 0 ) {
|
||||
for(; p-buf < len; p += 16)
|
||||
Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
uint8_t *p = buf;
|
||||
uint16_t tmp = len & 0xFFF0;
|
||||
|
||||
for(; p-buf < tmp; p += 16) {
|
||||
Dbprintf("[%s: %02d/%02d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
name,
|
||||
p-buf,
|
||||
len,
|
||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
|
||||
);
|
||||
}
|
||||
else {
|
||||
for(; p-buf < len; p += 8)
|
||||
Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
name,
|
||||
p-buf,
|
||||
len,
|
||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||
if (len % 16 != 0) {
|
||||
char s[46] = {0};
|
||||
char *sp = s;
|
||||
for (; p-buf < len; p++ ) {
|
||||
sprintf(sp, "%02x ", p[0] );
|
||||
sp += 3;
|
||||
}
|
||||
Dbprintf("[%s: %02d/%02d] %s", name, p-buf, len, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +107,7 @@ void print_result(char *name, uint8_t *buf, size_t len) {
|
|||
|
||||
void DbpStringEx(char *str, uint32_t cmd) {
|
||||
#if DEBUG
|
||||
byte_t len = strlen(str);
|
||||
uint8_t len = strlen(str);
|
||||
cmd_send(CMD_DEBUG_PRINT_STRING, len, cmd, 0, (byte_t*)str, len);
|
||||
#endif
|
||||
}
|
||||
|
@ -113,7 +119,7 @@ void DbpString(char *str) {
|
|||
}
|
||||
|
||||
#if 0
|
||||
void DbpIntegers(inst x1, int x2, int x3) {
|
||||
void DbpIntegers(int x1, int x2, int x3) {
|
||||
cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0);
|
||||
}
|
||||
#endif
|
||||
|
@ -442,6 +448,7 @@ void printStandAloneModes(void) {
|
|||
|
||||
//DbpString("Running ");
|
||||
//Dbprintf(" Is Device attached to USB| %s", USB_ATTACHED() ? "Yes" : "No");
|
||||
//Dbprintf(" Is Device attached to FPC| %s", 0 ? "Yes" : "No");
|
||||
//Dbprintf(" Is USB_reconnect value | %d", GetUSBreconnect() );
|
||||
//Dbprintf(" Is USB_configured value | %d", GetUSBconfigured() );
|
||||
|
||||
|
@ -1070,6 +1077,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
#endif
|
||||
case CMD_BUFF_CLEAR:
|
||||
BigBuf_Clear();
|
||||
BigBuf_free();
|
||||
break;
|
||||
|
||||
case CMD_MEASURE_ANTENNA_TUNING:
|
||||
|
@ -1106,7 +1114,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
len = MIN( (numofbytes - i), USB_CMD_DATA_SIZE);
|
||||
isok = cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, i, len, BigBuf_get_traceLen(), mem + startidx + i, len);
|
||||
if (!isok)
|
||||
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
|
||||
Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len);
|
||||
}
|
||||
// Trigger a finish downloading signal with an ACK frame
|
||||
// iceman, when did sending samplingconfig array got attached here?!?
|
||||
|
@ -1163,37 +1171,30 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
ReadMem(c->arg[0]);
|
||||
break;
|
||||
#ifdef WITH_FLASH
|
||||
case CMD_READ_FLASH_MEM: {
|
||||
|
||||
case CMD_FLASHMEM_SET_SPIBAUDRATE:
|
||||
FlashmemSetSpiBaudrate(c->arg[0]);
|
||||
break;
|
||||
case CMD_FLASHMEM_READ: {
|
||||
LED_B_ON();
|
||||
uint16_t isok = 0;
|
||||
uint32_t startidx = c->arg[0];
|
||||
uint16_t len = c->arg[1];
|
||||
uint8_t fast = c->arg[2];
|
||||
//uint8_t fast = c->arg[2];
|
||||
|
||||
Dbprintf("FlashMem read | %d - %d", startidx, len);
|
||||
Dbprintf("FlashMem read | %d - %d | ", startidx, len);
|
||||
|
||||
size_t size = MIN(USB_CMD_DATA_SIZE, len);
|
||||
|
||||
uint8_t *mem = BigBuf_malloc(size);
|
||||
|
||||
|
||||
if (fast) {
|
||||
FlashInit(1);
|
||||
//FlashInit();
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
}
|
||||
FlashInit();
|
||||
//Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
|
||||
for(size_t i = 0; i < len; i += size) {
|
||||
len = MIN((len - i), size);
|
||||
|
||||
Dbprintf("FlashMem reading | %d | %d | %d", startidx + i, i, len);
|
||||
|
||||
if (!fast){
|
||||
isok = Flash_ReadData(startidx + i, mem, len);
|
||||
}
|
||||
if (fast){
|
||||
isok = Flash_FastReadDataCont(startidx + i, mem, len);
|
||||
}
|
||||
Dbprintf("FlashMem reading | %d | %d | %d |", startidx + i, i, len);
|
||||
isok = Flash_ReadDataCont(startidx + i, mem, len);
|
||||
if ( isok == len ) {
|
||||
print_result("Chunk: ", mem, len);
|
||||
} else {
|
||||
|
@ -1201,13 +1202,11 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (fast){
|
||||
FlashStop();
|
||||
}
|
||||
FlashStop();
|
||||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
case CMD_WRITE_FLASH_MEM: {
|
||||
case CMD_FLASHMEM_WRITE: {
|
||||
LED_B_ON();
|
||||
uint8_t isok = 0;
|
||||
uint16_t res = 0;
|
||||
|
@ -1217,6 +1216,14 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
|
||||
uint32_t tmp = startidx + len;
|
||||
|
||||
if (!FlashInit())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable();
|
||||
|
||||
// inside 256b page?
|
||||
if ( (tmp & 0xFF) != 0) {
|
||||
|
||||
|
@ -1230,27 +1237,28 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
uint8_t first_len = (~startidx & 0xFF)+1;
|
||||
|
||||
// first mem page
|
||||
res = Flash_WriteData(startidx, data, first_len);
|
||||
res = Flash_WriteDataCont(startidx, data, first_len);
|
||||
|
||||
// second mem page
|
||||
res = Flash_WriteData(startidx + first_len, data + first_len, len - first_len);
|
||||
res = Flash_WriteDataCont(startidx + first_len, data + first_len, len - first_len);
|
||||
|
||||
isok = (res == (len - first_len)) ? 1 : 0;
|
||||
|
||||
} else {
|
||||
res = Flash_WriteData(startidx, data, len);
|
||||
res = Flash_WriteDataCont(startidx, data, len);
|
||||
isok = (res == len) ? 1 : 0;
|
||||
}
|
||||
} else {
|
||||
res = Flash_WriteData(startidx, data, len);
|
||||
res = Flash_WriteDataCont(startidx, data, len);
|
||||
isok = (res == len) ? 1 : 0;
|
||||
}
|
||||
FlashStop();
|
||||
|
||||
cmd_send(CMD_ACK, isok, 0, 0, 0, 0);
|
||||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
case CMD_WIPE_FLASH_MEM: {
|
||||
case CMD_FLASHMEM_WIPE: {
|
||||
LED_B_ON();
|
||||
uint8_t page = c->arg[0];
|
||||
uint8_t initalwipe = c->arg[1];
|
||||
|
@ -1268,7 +1276,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
case CMD_DOWNLOAND_FLASH_MEM: {
|
||||
case CMD_FLASHMEM_DOWNLOAD: {
|
||||
|
||||
LED_B_ON();
|
||||
uint8_t *mem = BigBuf_malloc(USB_CMD_DATA_SIZE);
|
||||
|
@ -1276,48 +1284,39 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
size_t len = 0;
|
||||
uint32_t startidx = c->arg[0];
|
||||
uint32_t numofbytes = c->arg[1];
|
||||
uint8_t fast = c->arg[2];
|
||||
//uint8_t fast = c->arg[2];
|
||||
|
||||
// arg0 = startindex
|
||||
// arg1 = length bytes to transfer
|
||||
// arg2 = RFU
|
||||
|
||||
FlashInit();
|
||||
|
||||
if (fast) {
|
||||
FlashInit(1);
|
||||
//FlashInit();
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
}
|
||||
for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
|
||||
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
|
||||
if (!fast){
|
||||
isok = Flash_ReadData(startidx + i, mem, len);
|
||||
}
|
||||
if (fast){
|
||||
isok = Flash_FastReadDataCont(startidx + i, mem, len);
|
||||
}
|
||||
|
||||
isok = Flash_ReadDataCont(startidx + i, mem, len);
|
||||
if (!isok )
|
||||
Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len);
|
||||
|
||||
isok = cmd_send(CMD_DOWNLOADED_FLASHMEM, i, len, 0, mem, len);
|
||||
|
||||
isok = cmd_send(CMD_FLASHMEM_DOWNLOADED, i, len, 0, mem, len);
|
||||
if (!isok)
|
||||
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
|
||||
}
|
||||
if (fast){
|
||||
FlashStop();
|
||||
}
|
||||
|
||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
case CMD_INFO_FLASH_MEM: {
|
||||
case CMD_FLASHMEM_INFO: {
|
||||
|
||||
LED_B_ON();
|
||||
rdv40_validation_t *info = (rdv40_validation_t*)BigBuf_malloc( sizeof(rdv40_validation_t) );
|
||||
|
||||
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET, info->signature, FLASH_MEM_SIGNATURE_LEN);
|
||||
|
||||
if (FlashInit(0)) {
|
||||
if (FlashInit()) {
|
||||
Flash_UniqueID( info->flashid);
|
||||
FlashStop();
|
||||
}
|
||||
|
@ -1437,15 +1436,15 @@ void __attribute__((noreturn)) AppMain(void) {
|
|||
StartTickCount();
|
||||
|
||||
#ifdef WITH_LCD
|
||||
// LCDInit();
|
||||
LCDInit();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SMARTCARD
|
||||
// I2C_init();
|
||||
I2C_init();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_FPC
|
||||
// usart_init();
|
||||
usart_init();
|
||||
#endif
|
||||
|
||||
// This is made as late as possible to ensure enumeration without timeout
|
||||
|
@ -1487,11 +1486,6 @@ void __attribute__((noreturn)) AppMain(void) {
|
|||
#if defined (WITH_ISO14443a) && ( defined (WITH_HF_YOUNG) || defined(WITH_HF_COLIN) || defined(WITH_HF_MATTYRUN) )
|
||||
RunMod();
|
||||
#endif
|
||||
|
||||
// when here, we are no longer in standalone mode.
|
||||
// reseting the variables which keeps track of usb re-attached/configured
|
||||
//SetUSBreconnect(0);
|
||||
//SetUSBconfigured(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
#include "flashmem.h"
|
||||
|
||||
|
||||
#define MCK 48000000
|
||||
//#define FLASH_BAUD 24000000
|
||||
//define FLASH_BAUD 33000000
|
||||
#define FLASH_BAUD MCK/2
|
||||
#define FLASH_FASTBAUD MCK
|
||||
|
||||
/* here: use NCPS2 @ PA10: */
|
||||
#define SPI_CSR_NUM 2
|
||||
|
@ -18,10 +13,17 @@
|
|||
#define SPI_DLYBCT(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 32000) << 24)
|
||||
|
||||
|
||||
uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
|
||||
|
||||
|
||||
void FlashmemSetSpiBaudrate(uint32_t baudrate){
|
||||
FLASHMEM_SPIBAUDRATE = baudrate;
|
||||
Dbprintf("Spi Baudrate : %dMhz", FLASHMEM_SPIBAUDRATE/1000000);
|
||||
}
|
||||
|
||||
// initialize
|
||||
bool FlashInit(bool fast) {
|
||||
FlashSetup(fast);
|
||||
bool FlashInit() {
|
||||
FlashSetup(FLASHMEM_SPIBAUDRATE);
|
||||
|
||||
StartTicks();
|
||||
|
||||
|
@ -33,7 +35,7 @@ bool FlashInit(bool fast) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void FlashSetup(bool fast){
|
||||
void FlashSetup(uint32_t baudrate){
|
||||
//WDT_DISABLE
|
||||
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
|
||||
|
||||
|
@ -79,13 +81,12 @@ void FlashSetup(bool fast){
|
|||
AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
|
||||
AT91C_SPI_MSTR; // Master Mode
|
||||
|
||||
int baudrate = FLASH_BAUD;
|
||||
uint8_t csaat = 1;
|
||||
int dlybct = 0;
|
||||
if (fast) {
|
||||
uint32_t dlybct = 0;
|
||||
if (baudrate > FLASH_MINFAST) {
|
||||
baudrate = FLASH_FASTBAUD;
|
||||
//csaat = 0;
|
||||
dlybct = MCK/32;
|
||||
dlybct = 1500;
|
||||
}
|
||||
|
||||
AT91C_BASE_SPI->SPI_CSR[2] =
|
||||
|
@ -100,28 +101,28 @@ void FlashSetup(bool fast){
|
|||
// transferred in the shifter. This can imply for example, that the second data is sent twice.
|
||||
// COLIN :: For now we STILL use CSAAT=1 to avoid having to (de)assert NPCS manually via PIO lines and we deal with delay
|
||||
( csaat << 3) |
|
||||
/* Spi modes:
|
||||
Mode CPOL CPHA NCPHA
|
||||
0 0 0 1 clock normally low read on rising edge
|
||||
1 0 1 0 clock normally low read on falling edge
|
||||
2 1 0 1 clock normally high read on falling edge
|
||||
3 1 1 0 clock normally high read on rising edge
|
||||
However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI
|
||||
master mode the ATSAM7S512/256/128/64/321/32 does not sample the data
|
||||
(MISO) on the opposite edge where data clocks out (MOSI) but the same
|
||||
edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3
|
||||
shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and
|
||||
that the data changes sometime after the rising edge (about 2 ns). To
|
||||
be consistent with normal SPI operation, it is probably safe to say
|
||||
that the data changes on the falling edge and should be sampled on the
|
||||
rising edge. Therefore, it appears that NCPHA should be treated the
|
||||
same as CPHA. Thus:
|
||||
Mode CPOL CPHA NCPHA
|
||||
0 0 0 0 clock normally low read on rising edge
|
||||
1 0 1 1 clock normally low read on falling edge
|
||||
2 1 0 0 clock normally high read on falling edge
|
||||
3 1 1 1 clock normally high read on rising edge
|
||||
*/
|
||||
/* Spi modes:
|
||||
Mode CPOL CPHA NCPHA
|
||||
0 0 0 1 clock normally low read on rising edge
|
||||
1 0 1 0 clock normally low read on falling edge
|
||||
2 1 0 1 clock normally high read on falling edge
|
||||
3 1 1 0 clock normally high read on rising edge
|
||||
However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI
|
||||
master mode the ATSAM7S512/256/128/64/321/32 does not sample the data
|
||||
(MISO) on the opposite edge where data clocks out (MOSI) but the same
|
||||
edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3
|
||||
shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and
|
||||
that the data changes sometime after the rising edge (about 2 ns). To
|
||||
be consistent with normal SPI operation, it is probably safe to say
|
||||
that the data changes on the falling edge and should be sampled on the
|
||||
rising edge. Therefore, it appears that NCPHA should be treated the
|
||||
same as CPHA. Thus:
|
||||
Mode CPOL CPHA NCPHA
|
||||
0 0 0 0 clock normally low read on rising edge
|
||||
1 0 1 1 clock normally low read on falling edge
|
||||
2 1 0 0 clock normally high read on falling edge
|
||||
3 1 1 1 clock normally high read on rising edge
|
||||
*/
|
||||
( 0 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||
|
||||
|
@ -161,10 +162,10 @@ uint16_t FlashSendByte(uint32_t data) {
|
|||
// send the data
|
||||
AT91C_BASE_SPI->SPI_TDR = data;
|
||||
|
||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){};
|
||||
//while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){};
|
||||
|
||||
// wait recive transfer is complete
|
||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0);
|
||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0){};
|
||||
|
||||
// reading incoming data
|
||||
return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF);
|
||||
|
@ -187,6 +188,8 @@ bool Flash_CheckBusy(uint32_t timeout)
|
|||
StartCountUS();
|
||||
uint32_t _time = GetCountUS();
|
||||
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Checkbusy in...");
|
||||
|
||||
do
|
||||
{
|
||||
if (!(Flash_ReadStat1() & BUSY))
|
||||
|
@ -249,37 +252,61 @@ void Flash_UniqueID(uint8_t *uid) {
|
|||
|
||||
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
||||
|
||||
if (!FlashInit(0)) return 0;
|
||||
if (!FlashInit()) return 0;
|
||||
|
||||
// length should never be zero
|
||||
if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
||||
|
||||
FlashSendByte(READDATA);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendByte((address >> 0) & 0xFF);
|
||||
|
||||
uint8_t cmd = READDATA;
|
||||
|
||||
if(FASTFLASH) {
|
||||
cmd = FASTREAD;
|
||||
}
|
||||
|
||||
FlashSendByte(cmd);
|
||||
Flash_TransferAdresse(address);
|
||||
|
||||
if (FASTFLASH){
|
||||
FlashSendByte(DUMMYBYTE);
|
||||
}
|
||||
|
||||
uint16_t i = 0;
|
||||
for (; i < (len - 1); i++)
|
||||
out[i] = FlashSendByte(0xFF);
|
||||
|
||||
out[i] = FlashSendLastByte(0xFF);
|
||||
|
||||
|
||||
|
||||
FlashStop();
|
||||
return len;
|
||||
}
|
||||
|
||||
void Flash_TransferAdresse(uint32_t address){
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendByte((address >> 0) & 0xFF);
|
||||
}
|
||||
|
||||
/* This ensure we can ReadData without having to cycle through initialization everytime */
|
||||
uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
||||
|
||||
// length should never be zero
|
||||
if (!len) return 0;
|
||||
|
||||
uint8_t cmd = READDATA;
|
||||
|
||||
FlashSendByte(READDATA);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendByte((address >> 0) & 0xFF);
|
||||
if(FASTFLASH) {
|
||||
cmd = FASTREAD;
|
||||
}
|
||||
|
||||
FlashSendByte(cmd);
|
||||
Flash_TransferAdresse(address);
|
||||
|
||||
if (FASTFLASH){
|
||||
FlashSendByte(DUMMYBYTE);
|
||||
}
|
||||
|
||||
uint16_t i = 0;
|
||||
for (; i < (len - 1); i++)
|
||||
out[i] = FlashSendByte(0xFF);
|
||||
|
@ -289,32 +316,6 @@ uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
|||
return len;
|
||||
}
|
||||
|
||||
uint16_t Flash_FastReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
||||
|
||||
// length should never be zero
|
||||
if (!len) return 0;
|
||||
|
||||
//if (Flash_CheckBusy(BUSY_TIMEOUT))
|
||||
//{return 0;}
|
||||
|
||||
FlashSendByte(FASTREAD);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendByte((address >> 0) & 0xFF);
|
||||
FlashSendByte(0xFF);
|
||||
//Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
|
||||
|
||||
uint16_t i = 0;
|
||||
for (; i < (len - 1); i++)
|
||||
out[i] = FlashSendByte(0xFF);
|
||||
|
||||
out[i] = FlashSendLastByte(0xFF);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
|
@ -338,13 +339,12 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!FlashInit(0)) {
|
||||
if (!FlashInit()) {
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
//Flash_ReadStat1();
|
||||
|
||||
Flash_WriteEnable();
|
||||
|
||||
|
@ -382,10 +382,8 @@ uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
|
|||
}
|
||||
|
||||
|
||||
//Flash_CheckBusy(100);
|
||||
//SpinDelay(1);
|
||||
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
//Flash_ReadStat1();
|
||||
Flash_WriteEnable();
|
||||
|
||||
FlashSendByte(PAGEPROG);
|
||||
|
@ -403,7 +401,7 @@ uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
|
|||
}
|
||||
|
||||
bool Flash_WipeMemoryPage(uint8_t page) {
|
||||
if (!FlashInit(0)) {
|
||||
if (!FlashInit()) {
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||
return false;
|
||||
}
|
||||
|
@ -417,7 +415,7 @@ bool Flash_WipeMemoryPage(uint8_t page) {
|
|||
}
|
||||
// Wipes flash memory completely, fills with 0xFF
|
||||
bool Flash_WipeMemory() {
|
||||
if (!FlashInit(0)) {
|
||||
if (!FlashInit()) {
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||
return false;
|
||||
}
|
||||
|
@ -498,12 +496,13 @@ void Flash_EraseChip(void) {
|
|||
|
||||
void Flashmem_print_status(void) {
|
||||
DbpString("Flash memory");
|
||||
Dbprintf(" Baudrate................%dMHz",FLASHMEM_SPIBAUDRATE/1000000);
|
||||
|
||||
if (!FlashInit(0)) {
|
||||
DbpString(" init....................FAIL");
|
||||
if (!FlashInit()) {
|
||||
DbpString(" Init....................FAIL");
|
||||
return;
|
||||
}
|
||||
DbpString(" init....................OK");
|
||||
DbpString(" Init....................OK");
|
||||
|
||||
uint8_t dev_id = Flash_ReadID();
|
||||
switch (dev_id) {
|
||||
|
|
|
@ -102,15 +102,30 @@
|
|||
#define MAX_SECTORS 16
|
||||
|
||||
|
||||
|
||||
|
||||
#define MCK 48000000
|
||||
//#define FLASH_BAUD 24000000
|
||||
#define FLASH_MINFAST 24000000 //33000000
|
||||
#define FLASH_BAUD MCK/2
|
||||
#define FLASH_FASTBAUD MCK
|
||||
#define FLASH_MINBAUD FLASH_FASTBAUD
|
||||
|
||||
#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST)
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||
extern void Dbprintf(const char *fmt, ...);
|
||||
bool FlashInit(bool fast);
|
||||
void FlashSetup(bool fast);
|
||||
|
||||
void FlashmemSetSpiBaudrate(uint32_t baudrate);
|
||||
bool FlashInit();
|
||||
void FlashSetup(uint32_t baudrate);
|
||||
void FlashStop(void);
|
||||
bool Flash_WaitIdle(void);
|
||||
uint8_t Flash_ReadStat1(void);
|
||||
uint8_t Flash_ReadStat2(void);
|
||||
uint16_t FlashSendByte(uint32_t data);
|
||||
void Flash_TransferAdresse(uint32_t address);
|
||||
|
||||
bool Flash_CheckBusy(uint32_t timeout);
|
||||
|
||||
|
@ -128,10 +143,11 @@ uint8_t Flash_ReadID(void);
|
|||
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len);
|
||||
|
||||
uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len);
|
||||
uint16_t Flash_FastReadDataCont(uint32_t address, uint8_t *out, uint16_t len);
|
||||
|
||||
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len);
|
||||
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len);
|
||||
void Flashmem_print_status(void);
|
||||
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue