/firmware/ssd1963/spiflash.c
C | 251 lines | 198 code | 29 blank | 24 comment | 11 complexity | 97c7f8b74536002a6e753f03599747e9 MD5 | raw file
- /*
- * SST25VF016B SPI Flash access
- * (CC) 2011 Ivan A-R <ivan@tuxotronic.org>
- */
- #include "spiflash.h"
- #include "stm32f10x.h"
- #define USE_HW_SPI 1
- #define nCS (1<<4)
- #define grabCS() GPIOA->BRR = nCS
- #define releaseCS() GPIOA->BSRR = nCS
- void sfSpiCsGrab(void)
- {
- grabCS();
- }
- void sfSpiCsRelease(void)
- {
- releaseCS();
- }
- uint16_t sfSpiExchange(uint16_t data)
- {
- #if (USE_HW_SPI == 1)
- while((SPI1->SR & SPI_SR_TXE) == 0) ;
- SPI1->DR = data;
- while((SPI1->SR & SPI_SR_RXNE) == 0) ;
- return SPI1->DR;
- #else
- uint16_t d = 0;
- uint16_t mask = (1<<(BIT_SIZE-1));
- int i;
- for(i=0; i<BIT_SIZE; i++)
- {
- if(data & mask)
- GPIOA->BSRR = (1<<7);
- else
- GPIOA->BRR = (1<<7);
- data <<= 1;
- GPIOA->BSRR = (1<<5);
- d <<= 1;
- if(GPIOA->IDR & (1<<6))
- d |= 1;
- GPIOA->BRR = (1<<5);
- }
- return d;
- #endif
- }
- void sfInit(void)
- {
- #if (USE_HW_SPI == 1)
- GPIOA->CRL = (GPIOA->CRL & 0x0000FFFF) | 0xbbb30000;
- // GPIOD->CRH = (GPIOD->CRH & 0xFF0FFFFF) | 0x00300000;
- releaseCS();
- /*
- SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SPE;
- SPI1->CR1 = 0;
- */
- RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
- SPI1->CR1 = 0;
- SPI1->CR1 = SPI_CR1_MSTR |
- // SPI_CR1_DFF |
- // SPI_CR1_CPHA |
- // SPI_CR1_CPOL |
- // SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_BR_2 | /* BR[2-0] = 000 - Fpclk/2 */
- 0;
- SPI1->CR2 = 0; // SPI_CR2_SSOE;
- SPI1->CR1 |= SPI_CR1_SPE; // Enable SPI
- //(void)(SPI1->DR);
- grabCS();
- sfSpiExchange(0);
- sfSpiExchange(0);
- sfSpiExchange(0);
- sfSpiExchange(0);
- releaseCS();
- #else
- GPIOA->BSRR = 0xE0;
- GPIOA->CRL = (GPIOA->CRL & 0x000FFFFF) | 0x38300000;
- GPIOD->CRH = (GPIOD->CRH & 0xFF0FFFFF) | 0x00300000;
- releaseCS();
- grabCS();
- int i;
- GPIOA->BRR = (1<<5);
- GPIOA->BSRR = (1<<7);
- for(i=0; i<32; i++)
- {
- GPIOA->BSRR = (1<<5);
- GPIOA->BRR = (1<<5);
- }
- releaseCS();
- #endif
- sfWriteDisable();
- grabCS();
- sfSpiExchange(0x80);
- releaseCS();
- }
- void sfSetDataWidth(uint8_t width)
- {
- if(width == 16)
- {
- SPI1->CR1 |= SPI_CR1_DFF;
- }
- else
- {
- SPI1->CR1 &= ~SPI_CR1_DFF;
- }
- }
- void sfWriteEnable(void)
- {
- grabCS();
- sfSpiExchange(0x06);
- releaseCS();
- }
- void sfWriteDisable(void)
- {
- grabCS();
- sfSpiExchange(0x04);
- releaseCS();
- }
- void sfWaitFlash(void)
- {
- uint8_t stat;
- grabCS();
- sfSpiExchange(0x05);
- do {
- stat = sfSpiExchange(0xFF);
- } while(stat & 1);
- releaseCS();
- }
- uint32_t sfReadJedecId(void)
- {
- uint32_t id;
- grabCS();
- sfSpiExchange(0x9F);
- id = sfSpiExchange(0xFF)<<16;
- id |= sfSpiExchange(0xFF)<<8;
- id |= sfSpiExchange(0xFF);
- releaseCS();
- return id;
- }
- void sfWriteStatus(uint8_t stat)
- {
- sfWaitFlash();
- sfWriteEnable();
- /*
- grabCS();
- sfSpiExchange(0x50);
- releaseCS();
- */
- grabCS();
- sfSpiExchange(0x01);
- sfSpiExchange(stat);
- releaseCS();
- }
- void sfEraseChip(void)
- {
- sfWaitFlash();
- sfWriteEnable();
- grabCS();
- sfSpiExchange(0x60);
- releaseCS();
- }
- void sfErase4k(uint32_t addr)
- {
- sfWaitFlash();
- sfWriteEnable();
- grabCS();
- sfSpiExchange(0x20);
- sfSpiExchange((addr >> 16) & 0xFF);
- sfSpiExchange((addr >> 8) & 0xFF);
- sfSpiExchange(addr & 0xFF);
- releaseCS();
- }
- void sfReadBlock(uint8_t* buf, int addr, int len)
- {
- sfWaitFlash();
- grabCS();
- sfSpiExchange(0x0B);
- sfSpiExchange((addr>>16) & 0xFF);
- sfSpiExchange((addr>>8) & 0xFF);
- sfSpiExchange((addr>>0) & 0xFF);
- sfSpiExchange(0xFF); // Dummy
- while(len--)
- {
- *buf++ = sfSpiExchange(0xFF);
- }
- releaseCS();
- }
- // char szBuf[32];
- void sfWriteBlock(uint8_t* buf, int addr, int len)
- {
- sfWaitFlash();
- len = (len+1)>>1;
- grabCS();
- sfSpiExchange(0x70); // Enable SO to output RY/BY# status during AAI programming
- releaseCS();
- sfWriteEnable();
- grabCS();
- sfSpiExchange(0xAD);
- sfSpiExchange((addr>>16) & 0xFF);
- sfSpiExchange((addr>>8) & 0xFF);
- sfSpiExchange((addr>>0) & 0xFF);
- sfSpiExchange(*buf++);
- sfSpiExchange(*buf++);
- releaseCS();
- while(--len)
- {
- /*
- uitox(len, szBuf, 8);
- fontString(fontList[0], 16, 80, szBuf, lcdNightBlue, lcdYellow);
- */
- grabCS();
- sfSpiExchange(0xAD);
- sfSpiExchange(*buf++);
- sfSpiExchange(*buf++);
- releaseCS();
- while((GPIOA->IDR & (1<<6)) == 0)
- ;
- }
- sfWriteDisable();
- sfWaitFlash();
- grabCS();
- sfSpiExchange(0x80); // Disable SO to output RY/BY# status during AAI programming
- releaseCS();
- }