diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index be7f07628..d77cdc22e 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -6,24 +6,144 @@ extern void Dbprintf(const char *fmt, ...); +static void FlashSetup() { + // 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; + + // Peripheral A + AT91C_BASE_PIOA->PIO_ASR = + GPIO_NCS2 | + GPIO_MISO | + GPIO_MOSI | + GPIO_SPCK; + + //enable the SPI Peripheral clock + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI); + + // 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 +} + static void FlashInit() { - SetupSpi(SPI_MEM_MODE); - NCS_3_LOW; + StartTicks(); + LED_A_ON(); + FlashSetup(); + NCS_2_LOW; + WaitUS(100); Dbprintf("FlashInit"); } static void FlashStop(){ - NCS_3_HIGH; + NCS_2_HIGH; + StopTicks(); Dbprintf("FlashStop"); -} -static void FlashSend(uint16_t data) { - - Dbprintf("FlashSend"); + LED_A_OFF(); - // 9th bit set for data, clear for command - while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete - // For clarity's sake we pass data with 9th bit clear and commands with 9th - // bit set since they're implemented as defines, se we need to invert bit - AT91C_BASE_SPI->SPI_TDR = data ^ 0x100; // Send the data/command + //* 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; + + // Reset the SPI mode + AT91C_BASE_SPI->SPI_MR = 0; + + // Disable all interrupts + AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF; + + // SPI disable + 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; +} +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); + } + data <<= 1; + SCK_HIGH; + tmp = tmp << 1 | MISO_VALUE; + } + SCK_LOW; + return tmp; + */ } static uint8_t FlashWriteRead(uint8_t data){ FlashSend(READDATA); @@ -35,6 +155,7 @@ static void FlashWrite_Enable(){ FlashWriteRead(WRITEENABLE); Dbprintf("Flash WriteEnabled"); } +/* static uint8_t FlashRead(uint8_t *address, uint16_t len) { FlashSend(READDATA); for (uint16_t i = 0; i < len; i++) { @@ -43,20 +164,61 @@ static uint8_t FlashRead(uint8_t *address, uint16_t len) { uint8_t tmp = FlashWriteRead(0XFF); return tmp; } +*/ + +uint8_t Flash_ReadID(void) { + + // 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 man_id = MISO_VALUE; + uint8_t dev_id = MISO_VALUE; + + 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); + } + + 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_2_HIGH; + return 0; +} + void EXFLASH_TEST(void) { - uint8_t a[3] = {0x00,0x00,0x00}; - //uint8_t b[3] = {0x00,0x01,0x02}; - uint8_t d = 0; + //uint8_t a[3] = {0x00,0x00,0x00}; + //uint8_t b[3] = {0x00,0x01,0x02}; + //uint8_t d = 0; FlashInit(); FlashWrite_Enable(); - //Dbprintf("write 012 to 0x00 0x01 0x02"); + Flash_ReadID(); + + //Dbprintf("Flash test write: 012 to 0x00 0x01 0x02"); //EXFLASH_Program(a, b, sizeof(b)); - d = FlashRead(a, sizeof(a)); - Dbprintf("%02x | %02x %02x %02x", d, a[0], a[1], a[2]); + //d = FlashRead(a, sizeof(a)); + //Dbprintf("%02x | %02x %02x %02x", d, a[0], a[1], a[2]); FlashStop(); cmd_send(CMD_ACK, 1, 0, 0, 0,0); @@ -66,7 +228,7 @@ void EXFLASH_TEST(void) { uint8_t EXFLASH_spi_write_read(uint8_t wData) { uint8_t tmp = 0; SCK_LOW; - NCS_3_LOW; + NCS_2_LOW; for (uint8_t i = 0; i < 8; i++) { SCK_LOW; @@ -91,7 +253,7 @@ uint8_t EXFLASH_readStat1(void) { uint8_t stat1 = 3; EXFLASH_spi_write_read(READSTAT1); stat1 = EXFLASH_spi_write_read(0xFF); - NCS_3_HIGH; + NCS_2_HIGH; return stat1; } @@ -99,7 +261,7 @@ uint8_t EXFLASH_readStat2(void) { uint8_t stat2; EXFLASH_spi_write_read(READSTAT2); stat2 = EXFLASH_spi_write_read(0xFF); - NCS_3_HIGH; + NCS_2_HIGH; return stat2; } @@ -117,7 +279,7 @@ bool EXFLASH_NOTBUSY(void) { void EXFLASH_Write_Enable(void) { EXFLASH_spi_write_read(WRITEENABLE); - NCS_3_HIGH; + NCS_2_HIGH; } uint8_t EXFLASH_Read(uint8_t *address, uint16_t len) { @@ -131,7 +293,7 @@ uint8_t EXFLASH_Read(uint8_t *address, uint16_t len) { EXFLASH_spi_write_read(address[i]); } tmp = EXFLASH_spi_write_read(0XFF); - NCS_3_HIGH; + NCS_2_HIGH; return tmp; } @@ -157,7 +319,7 @@ uint8_t EXFLASH_Program(uint8_t address[], uint8_t *array, uint8_t len) { EXFLASH_spi_write_read(array[i]); } - NCS_3_HIGH; + NCS_2_HIGH; return true; } @@ -174,7 +336,7 @@ uint8_t EXFLASH_ReadID(void) { ManID = EXFLASH_spi_write_read(0xff); // DevID = EXFLASH_spi_write_read(0xff); - NCS_3_HIGH; + NCS_2_HIGH; return ManID; } @@ -192,7 +354,7 @@ bool EXFLASH_Erase(void) { } while ((state1 & WRTEN) != WRTEN); EXFLASH_spi_write_read(CHIPERASE); - NCS_3_HIGH; + NCS_2_HIGH; return true; } @@ -200,7 +362,7 @@ bool EXFLASH_Reset(void) { LED_A_ON(); SetupSpi(SPI_MEM_MODE); - NCS_3_LOW; + NCS_2_LOW; if (!EXFLASH_NOTBUSY()) { LED_A_OFF(); @@ -209,9 +371,9 @@ bool EXFLASH_Reset(void) { } EXFLASH_spi_write_read(ENABLE_RESET); - NCS_3_HIGH; + NCS_2_HIGH; EXFLASH_spi_write_read(RESET); - NCS_3_HIGH; + NCS_2_HIGH; SpinDelayUs(10); LED_A_OFF(); return true; diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h index 7bc0399fe..07e7b0760 100644 --- a/armsrc/flashmem.h +++ b/armsrc/flashmem.h @@ -22,7 +22,6 @@ * along with the Arduino SPIFlash Library. If not, see * . */ - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// // Common Instructions // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// @@ -32,34 +31,36 @@ #include "proxmark3.h" #include "apps.h" -#define MANID 0x90 -#define PAGEPROG 0x02 -#define READDATA 0x03 -#define FASTREAD 0x0B -#define WRITEDISABLE 0x04 -#define READSTAT1 0x05 -#define READSTAT2 0x35 -#define WRITESTAT 0x01 -#define WRITEENABLE 0x06 -#define SECTORERASE 0x20 -#define BLOCK32ERASE 0x52 -#define CHIPERASE 0xC7 -#define SUSPEND 0x75 -#define ID 0x90 -#define RESUME 0x7A -#define JEDECID 0x9F -#define RELEASE 0xAB -#define POWERDOWN 0xB9 -#define BLOCK64ERASE 0xD8 -#define ENABLE_RESET 0x66 -#define RESET 0x99 +#define MANID 0x90 +#define PAGEPROG 0x02 +#define READDATA 0x03 +#define FASTREAD 0x0B +#define WRITEDISABLE 0x04 +#define READSTAT1 0x05 +#define READSTAT2 0x35 +#define WRITESTAT 0x01 +#define WRITEENABLE 0x06 +#define SECTORERASE 0x20 +#define BLOCK32ERASE 0x52 +#define CHIPERASE 0xC7 +#define SUSPEND 0x75 +#define ID 0x90 +#define RESUME 0x7A +#define JEDECID 0x9F +#define RELEASE 0xAB +#define POWERDOWN 0xB9 +#define BLOCK64ERASE 0xD8 +#define ENABLE_RESET 0x66 +#define RESET 0x99 +#define UNIQUE_ID 0x4B //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// // Chip specific instructions // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// //~~~~~~~~~~~~~~~~~~~~~~~~~ Winbond ~~~~~~~~~~~~~~~~~~~~~~~~~// -#define WINBOND_MANID 0xEF +#define WINBOND_MANID 0xEF +#define WINBOND_DEVID 0x11 #define PAGESIZE 0x100 //~~~~~~~~~~~~~~~~~~~~~~~~ Microchip ~~~~~~~~~~~~~~~~~~~~~~~~// diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 93669b983..933ff0fb3 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -44,21 +44,19 @@ void SetupSpi(int mode) { // Disable PIO control of the following pins, allows use by the SPI peripheral AT91C_BASE_PIOA->PIO_PDR = GPIO_NCS0 | - GPIO_NCS2 | - GPIO_NCS3 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK; + // Peripheral A AT91C_BASE_PIOA->PIO_ASR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK; - AT91C_BASE_PIOA->PIO_BSR = - GPIO_NCS2 | - GPIO_NCS3; + // Peripheral B + AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2; //enable the SPI Peripheral clock AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI); @@ -75,6 +73,7 @@ void SetupSpi(int mode) { ( 0 << 2) | // Chip selects connected directly to peripheral ( 0 << 1) | // Fixed Peripheral Select ( 1 << 0); // Master Mode + AT91C_BASE_SPI->SPI_CSR[0] = ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods) ( 1 << 16) | // Delay Before SPCK (1 MCK period) @@ -94,6 +93,7 @@ void SetupSpi(int mode) { ( 0 << 2) | // Chip selects connected directly to peripheral ( 0 << 1) | // Fixed Peripheral Select ( 1 << 0); // Master Mode + AT91C_BASE_SPI->SPI_CSR[2] = ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods) ( 1 << 16) | // Delay Before SPCK (1 MCK period) @@ -104,25 +104,6 @@ void SetupSpi(int mode) { ( 0 << 0); // Clock Polarity inactive state is logic 0 break; */ - case SPI_MEM_MODE: - AT91C_BASE_SPI->SPI_MR = - ( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods) - ( 1 << 16) | // Peripheral Chip Select (selects MEM SPI_NCS3 or PA1) ---> IS THIS CORRECT Chipset pin PA1? - ( 0 << 7) | // Local Loopback Disabled - ( 1 << 4) | // Mode Fault Detection disabled - ( 0 << 2) | // Chip selects connected directly to peripheral - ( 0 << 1) | // Fixed Peripheral Select - ( 1 << 0); // Master Mode - AT91C_BASE_SPI->SPI_CSR[2] = - ( 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) ---> 8bits? - ( 0 << 3) | // Chip Select inactive after transfer - ( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge - ( 0 << 0); // Clock Polarity inactive state is logic 0 - - break; default: // Disable SPI AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS; break; @@ -149,7 +130,7 @@ void FpgaSetupSscExt(uint8_t clearPCER) { // Now set up the SSC proper, starting from a known state. AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - + // RX clock comes from TX clock, RX starts when TX starts, data changes // on RX clock rising edge, sampled on falling edge AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1); @@ -516,6 +497,7 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v) { SetupSpi(SPI_FPGA_MODE); while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data + while (!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF)) {}; // wait till transfer is complete } //----------------------------------------------------------------------------- // Write the FPGA setup word (that determines what mode the logic is in, read @@ -569,7 +551,6 @@ int FpgaGetCurrent(void) { // log message // if HF, Disable SSC DMA // turn off trace and leds off. - void switch_off(void) { if (MF_DBGLEVEL > 3) Dbprintf("switch_off"); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); diff --git a/include/at91sam7s512.h b/include/at91sam7s512.h index 67f308eaa..47c79ee41 100644 --- a/include/at91sam7s512.h +++ b/include/at91sam7s512.h @@ -2111,7 +2111,6 @@ typedef struct _AT91S_UDP { #define AT91C_PIO_PA1 (1 << 1) // Pin Controlled by PA1 #define AT91C_PA1_PWM1 (AT91C_PIO_PA1) // PWM Channel 1 #define AT91C_PA1_TIOB0 (AT91C_PIO_PA1) // Timer Counter 0 Multipurpose Timer I/O Pin B -#define AT91C_PA1_NPCS3 (AT91C_PIO_PA1) // SPI Peripheral Chip Select 3 #define AT91C_PIO_PA2 (1 << 2) // Pin Controlled by PA2 #define AT91C_PA2_PWM2 (AT91C_PIO_PA2) // PWM Channel 2 #define AT91C_PA2_SCK0 (AT91C_PIO_PA2) // USART 0 Serial Clock diff --git a/include/config_gpio.h b/include/config_gpio.h index b61a27561..aa4f36601 100644 --- a/include/config_gpio.h +++ b/include/config_gpio.h @@ -19,9 +19,11 @@ #define GPIO_LRST AT91C_PIO_PA7 #define GPIO_LED_B AT91C_PIO_PA8 #define GPIO_LED_C AT91C_PIO_PA9 -#define GPIO_NCS3 AT91C_PA1_NPCS3 -#define GPIO_NCS2 AT91C_PA10_NPCS2 + +//#define GPIO_NCS2 AT91C_PA10_NPCS2 +#define GPIO_NCS2 AT91C_PIO_PA1 #define GPIO_NCS0 AT91C_PA11_NPCS0 + #define GPIO_MISO AT91C_PA12_MISO #define GPIO_MOSI AT91C_PA13_MOSI #define GPIO_SPCK AT91C_PA14_SPCK diff --git a/include/proxmark3.h b/include/proxmark3.h index 7b27ae010..a748c64f5 100644 --- a/include/proxmark3.h +++ b/include/proxmark3.h @@ -82,22 +82,22 @@ #define LED_D_ON() HIGH(GPIO_LED_D) #define LED_D_OFF() LOW(GPIO_LED_D) #define LED_D_INV() INVBIT(GPIO_LED_D) + +// SPI #define SCK_LOW LOW(GPIO_SPCK) #define SCK_HIGH HIGH(GPIO_SPCK) #define MOSI_HIGH HIGH(GPIO_MOSI) #define MOSI_LOW LOW(GPIO_MOSI) +#define MISO_VALUE (AT91C_BASE_PIOA->PIO_PDSR & GPIO_MISO) + // fpga #define NCS_0_LOW LOW(GPIO_NCS0) #define NCS_0_HIGH HIGH(GPIO_NCS0) -// lcd +// lcd - flash mem #define NCS_2_LOW LOW(GPIO_NCS2) #define NCS_2_HIGH HIGH(GPIO_NCS2) -// flash mem -#define NCS_3_LOW LOW(GPIO_NCS3) -#define NCS_3_HIGH HIGH(GPIO_NCS3) -#define MISO_VALUE (AT91C_BASE_PIOA->PIO_PDSR & GPIO_MISO) #define RELAY_ON() HIGH(GPIO_RELAY) #define RELAY_OFF() LOW(GPIO_RELAY) #define BUTTON_PRESS() !((AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON) == GPIO_BUTTON)