|
|
@ -1,19 +1,36 @@
|
|
|
|
#include <stm32l476xx.h>
|
|
|
|
|
|
|
|
#include <gpio.h>
|
|
|
|
|
|
|
|
#include <clock.h>
|
|
|
|
#include <clock.h>
|
|
|
|
|
|
|
|
#include <gpio.h>
|
|
|
|
|
|
|
|
#include <heap.h>
|
|
|
|
|
|
|
|
#include <stm32l476xx.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
|
|
#define READ 0x03
|
|
|
|
#define READ 0x03
|
|
|
|
#define WRITE 0x02
|
|
|
|
#define WRITE 0x02
|
|
|
|
#define WREN 0x06
|
|
|
|
#define WREN 0x06
|
|
|
|
#define WRDS 0x04
|
|
|
|
#define WRDS 0x04
|
|
|
|
|
|
|
|
|
|
|
|
#define SCK GPIO_PORT(C, 14)
|
|
|
|
#define SCK GPIO_PORT(D, 2)
|
|
|
|
#define SI GPIO_PORT(C, 3)
|
|
|
|
#define SI GPIO_PORT(C, 3)
|
|
|
|
#define SO GPIO_PORT(C, 2)
|
|
|
|
#define SO GPIO_PORT(C, 2)
|
|
|
|
#define CS GPIO_PORT(C, 15)
|
|
|
|
#define CS GPIO_PORT(B, 7)
|
|
|
|
|
|
|
|
|
|
|
|
void flash_out(uint8_t);
|
|
|
|
void flash_spi_xchg(char *buf, unsigned int count)
|
|
|
|
uint8_t flash_in(void);
|
|
|
|
{
|
|
|
|
|
|
|
|
gpio_dout(CS, 0);
|
|
|
|
|
|
|
|
// for each byte
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < count; i++) {
|
|
|
|
|
|
|
|
for (int b = 7; b >= 0; b--) {
|
|
|
|
|
|
|
|
gpio_dout(SI, buf[i] & (1 << b));
|
|
|
|
|
|
|
|
gpio_dout(SCK, 1);
|
|
|
|
|
|
|
|
if (gpio_din(SO))
|
|
|
|
|
|
|
|
buf[i] |= 1 << b;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
buf[i] &= ~(1 << b);
|
|
|
|
|
|
|
|
gpio_dout(SCK, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
gpio_dout(CS, 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void flash_init(void)
|
|
|
|
void flash_init(void)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -26,92 +43,64 @@ void flash_init(void)
|
|
|
|
gpio_dout(CS, 1);
|
|
|
|
gpio_dout(CS, 1);
|
|
|
|
gpio_dout(SCK, 0);
|
|
|
|
gpio_dout(SCK, 0);
|
|
|
|
gpio_dout(SI, 0);
|
|
|
|
gpio_dout(SI, 0);
|
|
|
|
|
|
|
|
|
|
|
|
//RCC->AHB3ENR |= RCC_AHB3ENR_QSPIEN;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//// 10MHz operation, per datasheet
|
|
|
|
|
|
|
|
//QUADSPI->CR &= ~(0xFF << QUADSPI_CR_PRESCALER_Pos);
|
|
|
|
|
|
|
|
//QUADSPI->CR |= 7 << QUADSPI_CR_PRESCALER_Pos;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//// pick FSEL! 0=1, 1=2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//// FSIZE = 16, 2^17 bits = 1Mb
|
|
|
|
|
|
|
|
//QUADSPI->DCR = (16 << QUADSPI_DCR_FSIZE_Pos);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//// Memmap mode, single-spi
|
|
|
|
|
|
|
|
//QUADSPI->CCR = (3 << QUADSPI_CCR_FMODE_Pos) | (1 << QUADSPI_CCR_DMODE_Pos)
|
|
|
|
|
|
|
|
// | (2 << QUADSPI_CCR_ADSIZE_Pos) | (1 << QUADSPI_CCR_ADMODE_Pos)
|
|
|
|
|
|
|
|
// | (1 << QUADSPI_CCR_IMODE_Pos);
|
|
|
|
|
|
|
|
//// TODO CCR also takes instruction byte
|
|
|
|
|
|
|
|
//QUADSPI->CCR |= (READ << QUADSPI_CCR_INSTRUCTION_Pos);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//QUADSPI->CR |= QUADSPI_CR_EN;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void flash_out(uint8_t byte)
|
|
|
|
void flash_read(char *buf, uint32_t addr, unsigned int count)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
if (buf == 0)
|
|
|
|
gpio_dout(SI, (byte & (1 << (7 - i))));
|
|
|
|
return;
|
|
|
|
gpio_dout(SCK, 1);
|
|
|
|
|
|
|
|
delay(1);
|
|
|
|
|
|
|
|
gpio_dout(SCK, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void flash_addr(uint32_t addr)
|
|
|
|
char *spibuf = malloc(count + 4);
|
|
|
|
{
|
|
|
|
spibuf[0] = READ;
|
|
|
|
for (uint8_t i = 0; i < 24; i++) {
|
|
|
|
spibuf[1] = (addr >> 16) & 0xFF;
|
|
|
|
gpio_dout(SI, (addr & (1 << (23 - i))));
|
|
|
|
spibuf[2] = (addr >> 8) & 0xFF;
|
|
|
|
gpio_dout(SCK, 1);
|
|
|
|
spibuf[3] = addr & 0xFF;
|
|
|
|
delay(1);
|
|
|
|
memcpy(spibuf + 4, buf, count);
|
|
|
|
gpio_dout(SCK, 0);
|
|
|
|
flash_spi_xchg(spibuf, count + 4);
|
|
|
|
}
|
|
|
|
memcpy(buf, spibuf + 4, count);
|
|
|
|
|
|
|
|
free(spibuf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t flash_in(void)
|
|
|
|
void flash_small_write(char *buf, uint32_t addr, unsigned int count)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint8_t byte = 0;
|
|
|
|
char wren = WREN;
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
flash_spi_xchg(&wren, 1);
|
|
|
|
gpio_dout(SCK, 1);
|
|
|
|
delay(10);
|
|
|
|
delay(1);
|
|
|
|
|
|
|
|
gpio_dout(SCK, 0);
|
|
|
|
|
|
|
|
if (gpio_din(SO))
|
|
|
|
|
|
|
|
byte |= (1 << (7 - i));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return byte;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void flash_read(char *buf, uint32_t addr, unsigned int count)
|
|
|
|
buf[0] = WRITE;
|
|
|
|
{
|
|
|
|
buf[1] = (addr >> 16) & 0xFF;
|
|
|
|
if (buf == 0)
|
|
|
|
buf[2] = (addr >> 8) & 0xFF;
|
|
|
|
return;
|
|
|
|
buf[3] = addr & 0xFF;
|
|
|
|
gpio_dout(CS, 0);
|
|
|
|
flash_spi_xchg(buf, count);
|
|
|
|
delay(1);
|
|
|
|
delay(10);
|
|
|
|
flash_out(READ);
|
|
|
|
|
|
|
|
flash_addr(addr);
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < count; i++)
|
|
|
|
|
|
|
|
buf[i] = flash_in();
|
|
|
|
|
|
|
|
gpio_dout(CS, 1);
|
|
|
|
|
|
|
|
delay(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void flash_write(const char *buf, uint32_t addr, unsigned int count)
|
|
|
|
void flash_write(const char *buf, uint32_t addr, unsigned int count)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (buf == 0)
|
|
|
|
if (buf == 0)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
gpio_dout(CS, 0);
|
|
|
|
|
|
|
|
delay(1);
|
|
|
|
char *spibuf = malloc(260); // 4 header + 256 page size
|
|
|
|
flash_out(WREN);
|
|
|
|
|
|
|
|
gpio_dout(CS, 1);
|
|
|
|
uint32_t startaddr = addr;
|
|
|
|
delay(100);
|
|
|
|
uint16_t counter = 0;
|
|
|
|
gpio_dout(CS, 0);
|
|
|
|
unsigned int offset = 0;
|
|
|
|
flash_out(WRITE);
|
|
|
|
for (uint32_t i = 0; i < count; i++) {
|
|
|
|
flash_addr(addr);
|
|
|
|
if (i > 0 && ((addr + i) & 0xFF) == 0) {
|
|
|
|
for (unsigned int i = 0; i < count; i++)
|
|
|
|
memcpy(spibuf + 4, buf + offset, counter);
|
|
|
|
flash_out(buf[i]);
|
|
|
|
flash_small_write(spibuf, startaddr, 4 + counter);
|
|
|
|
gpio_dout(CS, 1);
|
|
|
|
|
|
|
|
delay(100);
|
|
|
|
offset += counter;
|
|
|
|
//gpio_dout(CS, 0);
|
|
|
|
startaddr += counter;
|
|
|
|
//flash_out(WRDS);
|
|
|
|
counter = 0;
|
|
|
|
//gpio_dout(CS, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
counter++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (offset < count) {
|
|
|
|
|
|
|
|
memcpy(spibuf + 4, buf + offset, count - offset);
|
|
|
|
|
|
|
|
flash_small_write(spibuf, startaddr, 4 + count - offset);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
free(spibuf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|