From d54c4d3e05cf88cf2a862e678553cd00756d9b01 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 20 Feb 2018 12:03:11 +0100 Subject: [PATCH] chg: SPI tests for flashmem on PA10. (aka pm3 evo) Peripheral B, fixed. --- armsrc/flashmem.c | 365 ++++++++++++++++++++---------------------- armsrc/flashmem.h | 45 ++---- include/config_gpio.h | 5 +- include/proxmark3.h | 7 +- 4 files changed, 195 insertions(+), 227 deletions(-) diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index d77cdc22e..2de71b82e 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -1,77 +1,129 @@ #include "flashmem.h" -#include "proxmark3.h" -#include "apps.h" #define address_length 3 -extern void Dbprintf(const char *fmt, ...); +/* here: use NCPS2 @ PA10: */ +#define NCPS_PDR_BIT AT91C_PA10_NPCS2 +#define NCPS_ASR_BIT 0 +#define NPCS_BSR_BIT AT91C_PA10_NPCS2 +#define SPI_CSR_NUM 0 -static void FlashSetup() { +/* PCS_0 for NPCS0, PCS_1 for NPCS1 ... */ +#define PCS_0 ((0<<0)|(1<<1)|(1<<2)|(1<<3)) // 0xE - 1110 +#define PCS_1 ((1<<0)|(0<<1)|(1<<2)|(1<<3)) // 0xD - 1101 +#define PCS_2 ((1<<0)|(1<<1)|(0<<2)|(1<<3)) // 0xB - 1011 +#define PCS_3 ((1<<0)|(1<<1)|(1<<2)|(0<<3)) // 0x7 - 0111 + +/* TODO: ## */ +#if (SPI_CSR_NUM == 0) +#define SPI_MR_PCS PCS_0 +#elif (SPI_CSR_NUM == 1) +#define SPI_MR_PCS PCS_1 +#elif (SPI_CSR_NUM == 2) +#define SPI_MR_PCS PCS_2 +#elif (SPI_CSR_NUM == 3) +#define SPI_MR_PCS PCS_3 +#else +#error "SPI_CSR_NUM invalid" +// not realy - when using an external address decoder... +// but this code takes over the complete SPI-interace anyway +#endif +/* +1. variable chip select (PS=1) ChipSelect number is written to TDR in EVERY transfer +2. fixed chip select (PS=0), + +FIXED = you manage the CS lines +VARIABLE = SPI module manages the CS lines +*/ + +void FlashSetup(void) { // PA1 -> SPI_NCS3 chip select (MEM) // PA12 -> SPI_MISO Master-In Slave-Out // PA13 -> SPI_MOSI Master-Out Slave-In // PA14 -> SPI_SPCK Serial Clock - // Disable PIO control of the following pins, allows use by the SPI peripheral - AT91C_BASE_PIOA->PIO_PDR = - GPIO_NCS2 | - GPIO_MISO | - GPIO_MOSI | - GPIO_SPCK; + // Kill all the pullups, + //AT91C_BASE_PIOA->PIO_PPUDR = GPIO_NCS1 | GPIO_MOSI | GPIO_SPCK | GPIO_MISO; + // These pins are outputs + //AT91C_BASE_PIOA->PIO_OER = GPIO_NCS1 | GPIO_MOSI | GPIO_SPCK; + + // PIO controls the following pins + //AT91C_BASE_PIOA->PIO_PER = GPIO_NCS1 | GPIO_MOSI | GPIO_SPCK | GPIO_MISO; + + // Disable PIO control of the following pins, hand over to SPI control + AT91C_BASE_PIOA->PIO_PDR = GPIO_MISO | GPIO_MOSI | GPIO_SPCK; + // Peripheral A - AT91C_BASE_PIOA->PIO_ASR = - GPIO_NCS2 | - GPIO_MISO | - GPIO_MOSI | - GPIO_SPCK; + AT91C_BASE_PIOA->PIO_ASR = GPIO_MISO | GPIO_MOSI | GPIO_SPCK; + // Peripheral B + AT91C_BASE_PIOA->PIO_BSR = GPIO_MISO | GPIO_MOSI | GPIO_SPCK; + // set chip-select as output high (unselect card) + AT91C_BASE_PIOA->PIO_PER = NCPS_PDR_BIT; // enable GPIO of CS-pin + AT91C_BASE_PIOA->PIO_SODR = NCPS_PDR_BIT; // set high + AT91C_BASE_PIOA->PIO_OER = NCPS_PDR_BIT; // output enable + //enable the SPI Peripheral clock AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI); + // SPI Mode register + /* + AT91C_BASE_SPI->SPI_MR = + (0 << 24) | // DLYBCS, Delay between chip selects (take default: 6 MCK periods) + (0 << 7) | // LLB, Local Loopback Disabled + AT91C_SPI_MODFDIS | // Mode Fault Detection disabled + (0 << 2) | // PCSDEC, Chip selects connected directly to peripheral + AT91C_SPI_PS_FIXED | // PS, Fixed Peripheral Select + AT91C_SPI_MSTR; // MSTR, Master Mode + */ + AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS; + + // PCS, Peripheral Chip Select + AT91C_BASE_SPI->SPI_MR |= ( (SPI_MR_PCS << 16) & AT91C_SPI_PCS ); + + // SPI Chip select register +/* + AT91C_BASE_SPI->SPI_CSR[SPI_CSR_NUM] = + (1 << 24) | // Delay between Consecutive Transfers (32 MCK periods) + (1 << 16) | // Delay Before SPCK (1 MCK period) + (6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud + AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits) + (0 << 3) | // CSAAT, Chip Select inactive after transfer + AT91C_SPI_NCPHA | // NCPHA, Clock Phase data captured on leading edge, changes on following edge + (0 << 0); // CPOL, Clock Polarity inactive state is logic 0 +*/ + AT91C_BASE_SPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | (6 << 8); + // Enable SPI AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; - - // SPI Mode register - AT91C_BASE_SPI->SPI_MR = - ((0 << 24)& AT91C_SPI_DLYBCS) | // DLYBCS, Delay between chip selects (take default: 6 MCK periods) - ((1 << 16)& AT91C_SPI_PCS) | // PCS, Peripheral Chip Select (selects PA1) - ((0 << 7) & AT91C_SPI_LLB) | // Local Loopback Disabled - ((1 << 4) & AT91C_SPI_MODFDIS) | // Mode Fault Detection disabled - ((0 << 2) & AT91C_SPI_PCSDEC) | // Chip selects connected directly to peripheral - ((0 << 1) & AT91C_SPI_PS_FIXED) | // PS, Fixed Peripheral Select - ((1 << 0) & AT91C_SPI_MSTR); // MSTR, Master Mode - // SPI Chip select register - AT91C_BASE_SPI->SPI_CSR[0] = - ((1 << 24)& AT91C_SPI_DLYBCT) | // Delay between Consecutive Transfers (32 MCK periods) - ((1 << 16)& AT91C_SPI_DLYBS) | // Delay Before SPCK (1 MCK period) - ((6 << 8) & AT91C_SPI_SCBR) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud - (AT91C_SPI_BITS_8 & AT91C_SPI_BITS) | // Bits per Transfer (8 bits) - ((0 << 3) & AT91C_SPI_CSAAT) | // CSAAT, Chip Select inactive after transfer - ((1 << 1) & AT91C_SPI_NCPHA) | // NCPHA, Clock Phase data captured on leading edge, changes on following edge - ((0 << 0) & AT91C_SPI_CPOL); // CPOL, Clock Polarity inactive state is logic 0 + /* Send 20 spi commands with card not selected */ + for (int i=0; i<21; i++) + FlashSend(0xFF); + + /* enable automatic chip-select */ + // reset PIO-registers of CS-pin to default + AT91C_BASE_PIOA->PIO_ODR = NCPS_PDR_BIT; // input + AT91C_BASE_PIOA->PIO_CODR = NCPS_PDR_BIT; // clear + // disable PIO from controlling the CS pin (=hand over to SPI) + AT91C_BASE_PIOA->PIO_PDR = NCPS_PDR_BIT; + // set pin-functions in PIO Controller (function NCPS for CS-pin) + AT91C_BASE_PIOA->PIO_ASR = NCPS_ASR_BIT; + AT91C_BASE_PIOA->PIO_BSR = NPCS_BSR_BIT; } -static void FlashInit() { - StartTicks(); - LED_A_ON(); - FlashSetup(); - NCS_2_LOW; - WaitUS(100); - Dbprintf("FlashInit"); -} -static void FlashStop(){ - NCS_2_HIGH; +void FlashStop(void) { + //NCS_1_HIGH; StopTicks(); Dbprintf("FlashStop"); LED_A_OFF(); //* Reset all the Chip Select register AT91C_BASE_SPI->SPI_CSR[0] = 0; -// AT91C_BASE_SPI->SPI_CSR[1] = 0; -// AT91C_BASE_SPI->SPI_CSR[2] = 0; -// AT91C_BASE_SPI->SPI_CSR[3] = 0; + AT91C_BASE_SPI->SPI_CSR[1] = 0; + AT91C_BASE_SPI->SPI_CSR[2] = 0; + AT91C_BASE_SPI->SPI_CSR[3] = 0; // Reset the SPI mode AT91C_BASE_SPI->SPI_MR = 0; @@ -83,78 +135,58 @@ static void FlashStop(){ AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS; } -// The chip select lines used when sending data. -// These values are loaded into the SPI Transmit Data Register (TDR) when sending data. -/* -static const U32 SPI_TXRX_CS0 = BIT19 | BIT18 | BIT17 ; -static const U32 SPI_TXRX_CS1 = BIT19 | BIT18 | BIT16; -static const U32 SPI_TXRX_CS2 = BIT19 | BIT17 | BIT16; -static const U32 SPI_TXRX_CS3 = BIT18 | BIT17 | BIT16; -*/ -/* -Fixed = you manage the CS lines -Variable = SPI module manages the CS lines -const UINT32 PCS_CS2 = 0x00030000; -const UINT32 PCS_LASTTXFER = 0x01000000; -UINT32 temp; -temp = dataToSend; -temp |= PCS_CS2; -if(lastByte == true) -{ - temp |= PCS_LASTTXFER; +uint16_t FlashSend(uint16_t data) { + + uint16_t incoming = 0; + + while ( !(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY)) {}; // wait for the transfer to complete + AT91C_BASE_SPI->SPI_TDR = data; // send the data + while ( !(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF)) {}; // wait till transfer is complete + + incoming = ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF); + return incoming; +} +uint8_t Flash_ReadStat1(void) { + uint8_t stat2 = FlashSend(READSTAT1); + uint8_t stat1 = FlashSend(0xFF); + Dbprintf("stat1 [%02x] %02x ", stat1, stat2); +// NCS_1_HIGH; + return stat1; +} +/* +static uint8_t Flash_ReadStat2(void) { + FlashSend(READSTAT2); + uint8_t stat2 = FlashSend(0xff); + NCS_1_HIGH; + return stat2; } -SPI_TDR = temp; */ -// 1. variable chip select (PS=1) ChipSelect number is written to TDR in EVERY transfer -// 2. fixed chip select (PS=0), -static uint8_t FlashSend(uint16_t data) { - - // wait for the transfer to complete - while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {}; - - // send data - AT91C_BASE_SPI->SPI_TDR = data; - - // wait for the recieving data - while (!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF)) {}; - - //return MISO_VALUE; - return AT91C_BASE_SPI->SPI_RDR & 0xFF; - -/* - - SCK_LOW; - NCS_2_LOW; - - for (uint8_t i = 0; i < 8; i++) { - SCK_LOW; - WaitUS(2); - - if (data & 0x80) { - MOSI_HIGH; - } else { - MOSI_LOW; - WaitUS(2); +bool Flash_NOTBUSY(void) { + WDT_HIT(); + uint8_t state, count = 0; + do { + state = Flash_ReadStat1(); + if (count > 100) { + return false; } - data <<= 1; - SCK_HIGH; - tmp = tmp << 1 | MISO_VALUE; - } - SCK_LOW; - return tmp; - */ + count++; + } while (state & BUSY); + return true; } +/* static uint8_t FlashWriteRead(uint8_t data){ FlashSend(READDATA); FlashSend(data); uint8_t ret = MISO_VALUE; return ret; } + static void FlashWrite_Enable(){ FlashWriteRead(WRITEENABLE); Dbprintf("Flash WriteEnabled"); } +*/ /* static uint8_t FlashRead(uint8_t *address, uint16_t len) { FlashSend(READDATA); @@ -168,39 +200,49 @@ static uint8_t FlashRead(uint8_t *address, uint16_t len) { uint8_t Flash_ReadID(void) { +// if (!Flash_NOTBUSY()) +// return true; + // Manufacture ID / device ID uint8_t t0 = FlashSend(ID); - uint8_t t1 = FlashSend(0x00); - uint8_t t2 = FlashSend(0x00); - uint8_t t3 = FlashSend(0x00); + uint8_t t1 = FlashSend(0x00); + uint8_t t2 = FlashSend(0x00); + uint8_t t3 = FlashSend(0x00); - uint8_t man_id = MISO_VALUE; - uint8_t dev_id = MISO_VALUE; + uint8_t man_id = FlashSend(0xFF); + uint8_t dev_id = 0; // FlashSend(0xff); Dbprintf(" [%02x] %02x %02x %02x | %02x %02x", t0,t1,t2,t3, man_id, dev_id); - //WINBOND_MANID if ( man_id == WINBOND_MANID ) { Dbprintf("Correct read of Manucaturer ID [%02x] == %02x", man_id, WINBOND_MANID); } - if ( dev_id > 0) { - Dbprintf("Got a device ID [%02x] == %02x ( 0x11 0x30 0x12", dev_id, WINBOND_DEVID); - } + // if ( dev_id > 0) { + // Dbprintf("Got a device ID [%02x] == %02x ( 0x11 0x30 0x12", dev_id, WINBOND_DEVID); + // } - uint8_t foo[8]; - // Read unique ID number UNIQUE_ID (0x4B) - FlashSend(UNIQUE_ID); - FlashSend(0x00); - FlashSend(0x00); - FlashSend(0x00); - FlashSend(0x00); - for (int i = 0; i< sizeof(foo); i++) { - foo[i] = MISO_VALUE; - } +// NCS_1_HIGH; + return man_id; +} +bool FlashInit(void) { - NCS_2_HIGH; - return 0; + StartTicks(); + + LED_A_ON(); + FlashSetup(); + + if (!Flash_NOTBUSY()) + return false; + +// FlashSend(ENABLE_RESET); +// NCS_1_HIGH; +// FlashSend(RESET); +// NCS_1_HIGH; +// WaitUS(10); + + Dbprintf("FlashInit"); + return true; } void EXFLASH_TEST(void) { @@ -208,9 +250,9 @@ void EXFLASH_TEST(void) { //uint8_t b[3] = {0x00,0x01,0x02}; //uint8_t d = 0; - FlashInit(); + if (!FlashInit()) return; - FlashWrite_Enable(); + //FlashWrite_Enable(); Flash_ReadID(); @@ -223,12 +265,12 @@ void EXFLASH_TEST(void) { FlashStop(); cmd_send(CMD_ACK, 1, 0, 0, 0,0); } - +/* // IO spi write or read uint8_t EXFLASH_spi_write_read(uint8_t wData) { uint8_t tmp = 0; SCK_LOW; - NCS_2_LOW; + LOW(GPIO_NCS2); for (uint8_t i = 0; i < 8; i++) { SCK_LOW; @@ -249,40 +291,14 @@ uint8_t EXFLASH_spi_write_read(uint8_t wData) { return tmp; } -uint8_t EXFLASH_readStat1(void) { - uint8_t stat1 = 3; - EXFLASH_spi_write_read(READSTAT1); - stat1 = EXFLASH_spi_write_read(0xFF); - NCS_2_HIGH; - return stat1; -} - -uint8_t EXFLASH_readStat2(void) { - uint8_t stat2; - EXFLASH_spi_write_read(READSTAT2); - stat2 = EXFLASH_spi_write_read(0xFF); - NCS_2_HIGH; - return stat2; -} - -bool EXFLASH_NOTBUSY(void) { - uint8_t state, count = 0; - do { - state = EXFLASH_readStat1(); - if (count > 100) { - return false; - } - count++; - } while (state & BUSY); - return true; -} void EXFLASH_Write_Enable(void) { EXFLASH_spi_write_read(WRITEENABLE); - NCS_2_HIGH; + HIGH(GPIO_NCS2); } uint8_t EXFLASH_Read(uint8_t *address, uint16_t len) { + if (!EXFLASH_NOTBUSY()) return false; @@ -293,7 +309,7 @@ uint8_t EXFLASH_Read(uint8_t *address, uint16_t len) { EXFLASH_spi_write_read(address[i]); } tmp = EXFLASH_spi_write_read(0XFF); - NCS_2_HIGH; + HIGH(GPIO_NCS2); return tmp; } @@ -319,7 +335,7 @@ uint8_t EXFLASH_Program(uint8_t address[], uint8_t *array, uint8_t len) { EXFLASH_spi_write_read(array[i]); } - NCS_2_HIGH; + HIGH(GPIO_NCS2); return true; } @@ -336,7 +352,7 @@ uint8_t EXFLASH_ReadID(void) { ManID = EXFLASH_spi_write_read(0xff); // DevID = EXFLASH_spi_write_read(0xff); - NCS_2_HIGH; + HIGH(GPIO_NCS2); return ManID; } @@ -354,35 +370,10 @@ bool EXFLASH_Erase(void) { } while ((state1 & WRTEN) != WRTEN); EXFLASH_spi_write_read(CHIPERASE); - NCS_2_HIGH; + HIGH(GPIO_NCS2); return true; } - -bool EXFLASH_Reset(void) { - LED_A_ON(); - SetupSpi(SPI_MEM_MODE); - - NCS_2_LOW; - - if (!EXFLASH_NOTBUSY()) { - LED_A_OFF(); - Dbprintf("[!] init reset failed"); - return false; - } - - EXFLASH_spi_write_read(ENABLE_RESET); - NCS_2_HIGH; - EXFLASH_spi_write_read(RESET); - NCS_2_HIGH; - SpinDelayUs(10); - LED_A_OFF(); - return true; -} - -void EXFLASH_Init(void) { - EXFLASH_Reset(); -} - +*/ /* void EXFLASH_TEST(void) { uint8_t a[3] = {0x00,0x00,0x00}; diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h index 07e7b0760..8b0ed0b4e 100644 --- a/armsrc/flashmem.h +++ b/armsrc/flashmem.h @@ -83,27 +83,6 @@ #define lengthOf(x) (sizeof(x))/sizeof(byte) #define maxAddress capacity -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Arduino Due DMA definitions // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Use SAM3X DMAC if nonzero -#define USE_SAM3X_DMAC 1 -// Use extra Bus Matrix arbitration fix if nonzero -#define USE_SAM3X_BUS_MATRIX_FIX 0 -// Time in ms for DMA receive timeout -#define SAM3X_DMA_TIMEOUT 100 -// chip select register number -#define SPI_CHIP_SEL 3 -// DMAC receive channel -#define SPI_DMAC_RX_CH 1 -// DMAC transmit channel -#define SPI_DMAC_TX_CH 0 -// DMAC Channel HW Interface Number for SPI TX. -#define SPI_TX_IDX 1 -// DMAC Channel HW Interface Number for SPI RX. -#define SPI_RX_IDX 2 -// Set DUE SPI clock div (any integer from 2 - 255) -#define DUE_SPI_CLK 2 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// // List of Error codes // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// @@ -119,20 +98,16 @@ #define NOSUSPEND 0x09 #define UNKNOWNERROR 0xFF - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +extern void Dbprintf(const char *fmt, ...); - uint8_t EXFLASH_spi_write_read(uint8_t wData); - uint8_t EXFLASH_readStat1(void) ; - uint8_t EXFLASH_readStat2(void) ; - bool EXFLASH_NOTBUSY(void); - void EXFLASH_Write_Enable(void) ; - uint8_t EXFLASH_Read(uint8_t *address, uint16_t len); - uint8_t EXFLASH_Program(uint8_t address[], uint8_t *array, uint8_t len) ; - - uint8_t EXFLASH_ReadID(void) ; - bool EXFLASH_Erase(void) ; - bool EXFLASH_Reset(void); - void EXFLASH_Init(void); - void EXFLASH_TEST(void); +void FlashSetup(void); +void FlashStop(void); +bool Flash_NOTBUSY(void); +uint8_t Flash_ReadStat1(void); +uint8_t Flash_ReadStat2(void); +uint16_t FlashSend(uint16_t data); +bool FlashInit(); +void EXFLASH_TEST(void); #endif \ No newline at end of file diff --git a/include/config_gpio.h b/include/config_gpio.h index aa4f36601..a30ef0635 100644 --- a/include/config_gpio.h +++ b/include/config_gpio.h @@ -20,8 +20,9 @@ #define GPIO_LED_B AT91C_PIO_PA8 #define GPIO_LED_C AT91C_PIO_PA9 -//#define GPIO_NCS2 AT91C_PA10_NPCS2 -#define GPIO_NCS2 AT91C_PIO_PA1 +// flashmem hooked on PA10 +//#define GPIO_NCS2 AT91C_PIO_PA1 +#define GPIO_NCS2 AT91C_PA10_NPCS2 #define GPIO_NCS0 AT91C_PA11_NPCS0 #define GPIO_MISO AT91C_PA12_MISO diff --git a/include/proxmark3.h b/include/proxmark3.h index a748c64f5..9029ca865 100644 --- a/include/proxmark3.h +++ b/include/proxmark3.h @@ -93,9 +93,10 @@ // fpga #define NCS_0_LOW LOW(GPIO_NCS0) #define NCS_0_HIGH HIGH(GPIO_NCS0) -// lcd - flash mem -#define NCS_2_LOW LOW(GPIO_NCS2) -#define NCS_2_HIGH HIGH(GPIO_NCS2) + +// flash mem PA1 +#define NCS_1_LOW LOW(GPIO_NCS2) +#define NCS_1_HIGH HIGH(GPIO_NCS2) #define RELAY_ON() HIGH(GPIO_RELAY)