diff --git a/armsrc/Makefile b/armsrc/Makefile index b2de878c8..ef62af013 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -52,7 +52,7 @@ SRC_CRAPTO1 = crypto1.c des.c aes.c desfire_key.c desfire_crypto.c mifaredesfire SRC_CRC = crc.c crc16.c crc32.c SRC_ICLASS = iclass.c optimized_cipher.c SRC_LEGIC = legicrf.c legic_prng.c -SRC_FLASH = flash.c +SRC_FLASH = flashmem.c SRC_BEE = bee.c #the FPGA bitstream files. Note: order matters! @@ -77,6 +77,7 @@ THUMBSRC = start.c \ $(SRC_LF) \ $(SRC_ZLIB) \ $(SRC_LEGIC) \ + $(SRC_FLASH) \ appmain.c \ printf.c \ util.c \ diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c new file mode 100644 index 000000000..cebaae19f --- /dev/null +++ b/armsrc/flashmem.c @@ -0,0 +1,193 @@ +#include "flashmem.h" +#include "proxmark3.h" +#include "apps.h" + +#define address_length 3 +#define data_len 3 + +extern void Dbprintf(const char *fmt, ...); + +// IO spi write or read +uint8_t EXFLASH_spi_write_read(uint8_t wData) { + uint8_t i, tmp = 0; + SCK_LOW; + NCS_3_LOW; + + for (i = 0; i < 8; i++) { + SCK_LOW; + SpinDelayUs(2); + + if (wData&0x80) { + MOSI_HIGH; + } else { + MOSI_LOW; + SpinDelayUs(2); + } + wData <<= 1; + SCK_HIGH; + tmp <<= 1; + tmp |= MISO_VALUE; + } + SCK_LOW; + return tmp; +} + +uint8_t EXFLASH_readStat1(void) { + uint8_t stat1 = 3; + EXFLASH_spi_write_read(READSTAT1); + stat1 = EXFLASH_spi_write_read(0xff); + NCS_3_HIGH; + return stat1; +} + +uint8_t EXFLASH_readStat2(void) { + uint8_t stat2; + EXFLASH_spi_write_read(READSTAT2); + stat2 = EXFLASH_spi_write_read(0xff); + NCS_3_HIGH; + return stat2; +} + +bool ESFLASH_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_3_HIGH; +} + +uint8_t EXFLASH_Read(uint8_t address[]) { + uint8_t i, tmp; + if (!ESFLASH_NOTBUSY()) + return false; + + EXFLASH_spi_write_read(READDATA); + + for (i=0; i < address_length; i++) { + EXFLASH_spi_write_read(address[i]); + } + tmp = EXFLASH_spi_write_read(0XFF); + NCS_3_HIGH; + return tmp; +} + +uint8_t EXFLASH_Program(uint8_t address[],uint8_t array[], uint8_t len) { + uint8_t state1, count = 0, i; + EXFLASH_Write_Enable(); + + do { + state1 = EXFLASH_readStat1(); + if (count > 100) { + return false; + } + count++; + } while ((state1 & WRTEN) != WRTEN); + + EXFLASH_spi_write_read(PAGEPROG); + + for (i=0; i 100) { + return false; + } + count++; + } while ((state1 & WRTEN) != WRTEN); + + EXFLASH_spi_write_read(CHIPERASE); + NCS_3_HIGH; + return true; +} + +bool EXFLASH_Reset(void) { + LED_A_ON(); //blue + SetupSpi(SPI_MEM_MODE); + + if (!ESFLASH_NOTBUSY()) + return false; + + EXFLASH_spi_write_read(Enable_Reset); + NCS_3_HIGH; + EXFLASH_spi_write_read(Reset); + NCS_3_HIGH; + SpinDelayUs(10); + LED_A_ON(); + return true; +} + +void EXFLASH_Init(void) { + EXFLASH_Reset(); +} + +void EXFLASH_TEST(void) { + uint8_t a[3] = {0x00,0x00,0x00}; + uint8_t b[data_len] = {0x00,0x01,0x02}; + uint8_t f[3] = {0x00,0x00,0x01}; + uint8_t e[3] = {0x00,0x00,0x02}; + uint8_t d = 0; + + EXFLASH_Init(); + // c = EXFLASH_ReadID(); + + //EXFLASH_Write_Enable(); + //EXFLASH_readStat1(); + Dbprintf("%s \r\n", "write 012 to 0x00 0x01 0x02"); + + Dbprintf("%s \r\n"," wait... "); + + EXFLASH_Program(a, b, data_len); + + d = EXFLASH_Read(a); + Dbprintf(" %d ", d); + + d = EXFLASH_Read(f); + Dbprintf(" %d ", d); + + d = EXFLASH_Read(e); + + Dbprintf(" %d ", d); + Dbprintf("%s \r\n","TEST done!"); + + EXFLASH_Erase(); +} \ No newline at end of file diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h new file mode 100644 index 000000000..badd3d4c2 --- /dev/null +++ b/armsrc/flashmem.h @@ -0,0 +1,137 @@ +/* Arduino SPIFlash Library v.2.5.0 + * Copyright (C) 2015 by Prajwal Bhattaram + * Modified by Prajwal Bhattaram - 13/11/2016 + * + * This file is part of the Arduino SPIFlash Library. This library is for + * Winbond NOR flash memory modules. In its current form it enables reading + * and writing individual data variables, structs and arrays from and to various locations; + * reading and writing pages; continuous read functions; sector, block and chip erase; + * suspending and resuming programming/erase and powering down for low power operation. + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License v3.0 + * along with the Arduino SPIFlash Library. If not, see + * . + */ + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Common Instructions // +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +#ifndef __FLASHMEM_H +#define __FLASHMEM_H + +#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 + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Chip specific instructions // +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +//~~~~~~~~~~~~~~~~~~~~~~~~~ Winbond ~~~~~~~~~~~~~~~~~~~~~~~~~// +#define WINBOND_MANID 0xEF +#define PAGESIZE 0x100 + +//~~~~~~~~~~~~~~~~~~~~~~~~ Microchip ~~~~~~~~~~~~~~~~~~~~~~~~// +#define MICROCHIP_MANID 0xBF +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Definitions // +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +#define BUSY 0x01 +#define SPI_CLK 104000000 //Hex equivalent of 104MHz +#define WRTEN 0x02 +#define SUS 0x40 +#define DUMMYBYTE 0xEE +#define NULLBYTE 0x00 +#define NULLINT 0x0000 +#define NO_CONTINUE 0x00 +#define PASS 0x01 +#define FAIL 0x00 +#define arrayLen(x) (sizeof(x) / sizeof(*x)) +#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 // +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +#define SUCCESS 0x00 +#define CALLBEGIN 0x01 +#define UNKNOWNCHIP 0x02 +#define UNKNOWNCAP 0x03 +#define CHIPBUSY 0x04 +#define OUTOFBOUNDS 0x05 +#define CANTENWRITE 0x06 +#define PREVWRITTEN 0x07 +#define LOWRAM 0x08 +#define NOSUSPEND 0x09 +#define UNKNOWNERROR 0xFF + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + + uint8_t EXFLASH_spi_write_read(uint8_t wData); + uint8_t EXFLASH_readStat1(void) ; + uint8_t EXFLASH_readStat2(void) ; + bool ESFLASH_NOTBUSY(void); + void EXFLASH_Write_Enable(void) ; + uint8_t EXFLASH_Read(uint8_t address[]); + 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); + + #endif \ No newline at end of file diff --git a/include/proxmark3.h b/include/proxmark3.h index fc0001c86..7b27ae010 100644 --- a/include/proxmark3.h +++ b/include/proxmark3.h @@ -82,6 +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) +#define SCK_LOW LOW(GPIO_SPCK) +#define SCK_HIGH HIGH(GPIO_SPCK) +#define MOSI_HIGH HIGH(GPIO_MOSI) +#define MOSI_LOW LOW(GPIO_MOSI) +// fpga +#define NCS_0_LOW LOW(GPIO_NCS0) +#define NCS_0_HIGH HIGH(GPIO_NCS0) +// lcd +#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)