diff options
Diffstat (limited to 'src/flash.c.bak')
-rw-r--r-- | src/flash.c.bak | 153 |
1 files changed, 79 insertions, 74 deletions
diff --git a/src/flash.c.bak b/src/flash.c.bak index 037eeae..e3de420 100644 --- a/src/flash.c.bak +++ b/src/flash.c.bak @@ -1,3 +1,23 @@ +/** + * @file flash.c + * Provides functionality for using an external SPI flash + * + * Copyright (C) 2018 Clyne Sullivan + * + * This program 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 program 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 + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + #include <stm32l476xx.h> #include <gpio.h> #include <clock.h> @@ -7,104 +27,89 @@ #define WREN 0x06 #define WRDS 0x04 -#define SCK GPIO_PORT(C, 9) -#define SI GPIO_PORT(B, 8) -#define SO GPIO_PORT(B, 9) -#define CS GPIO_PORT(C, 4) +#define NSS GPIO_PORT(B, 12) +#define SCK GPIO_PORT(B, 13) +#define MISO GPIO_PORT(B, 14) +#define MOSI GPIO_PORT(B, 15) -void flash_out(uint8_t); -uint8_t flash_in(void); +void flash_xchg(char *byte, int count); void flash_init(void) { - gpio_mode(SCK, OUTPUT); - gpio_mode(SI, OUTPUT); - gpio_mode(CS, OUTPUT); - gpio_mode(SO, OUTPUT); - gpio_dout(SO, 0); - gpio_mode(SO, INPUT); - gpio_dout(CS, 1); - gpio_dout(SCK, 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; + gpio_mode(NSS, ALTERNATE); + gpio_mode(SCK, ALTERNATE); + gpio_mode(MISO, ALTERNATE); + gpio_mode(MOSI, ALTERNATE); + GPIOB->AFR[1] |= 0x55550000; // alt mode SPI2 - //// pick FSEL! 0=1, 1=2 + // clock enable + RCC->APB1ENR1 |= RCC_APB1ENR1_SPI2EN; - //// FSIZE = 16, 2^17 bits = 1Mb - //QUADSPI->DCR = (16 << QUADSPI_DCR_FSIZE_Pos); + SPI2->CR1 &= ~(SPI_CR1_BR_Msk); + SPI2->CR1 |= (3 << SPI_CR1_BR_Pos); + SPI2->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI; + SPI2->CR1 |= SPI_CR1_MSTR; + SPI2->CR2 &= ~(SPI_CR2_DS_Msk); + SPI2->CR2 |= (7 << SPI_CR2_DS_Pos); + SPI2->CR2 |= SPI_CR2_SSOE; + SPI2->CR2 |= SPI_CR2_FRXTH; + SPI2->CR1 |= SPI_CR1_SPE; - //// 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; + char buf[4]; + buf[0] = READ; + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + flash_xchg(buf, 4); } -void flash_out(uint8_t byte) +void flash_xchg(char *byte, int count) { - for (uint8_t i = 0; i < 8; i++) { - gpio_dout(SI, (byte & (1 << (7 - i)))); - gpio_dout(SCK, 1); - gpio_dout(SCK, 0); + uint32_t status = 0, dummy; + SPI2->CR1 &= ~(SPI_CR1_SSI); + while (SPI2->SR & SPI_SR_BSY); + for (int i = 0; i < count; i++) { + SPI2->DR = byte[i]; + do status = SPI2->SR; + while (status & SPI_SR_BSY); + // discard rx + while (status & SPI_SR_RXNE) { + dummy = SPI2->DR; + status = SPI2->SR; + } } -} + do status = SPI2->SR; + while (status & SPI_SR_BSY); -void flash_addr(uint32_t addr) -{ - for (uint8_t i = 0; i < 24; i++) { - gpio_dout(SI, (addr & (1 << (23 - i)))); - gpio_dout(SCK, 1); - gpio_dout(SCK, 0); + while (1) { + SPI2->DR = 0; + do status = SPI2->SR; + while (status & SPI_SR_BSY); + // discard rx + while (status & SPI_SR_RXNE) { + dummy = SPI2->DR; + status = SPI2->SR; + } } -} -uint8_t flash_in(void) -{ - uint8_t byte = 0; - for (uint8_t i = 0; i < 8; i++) { - gpio_dout(SCK, 1); - gpio_dout(SCK, 0); - if (gpio_din(SO)) - byte |= (1 << (7 - i)); - } - return byte; + SPI2->CR1 |= SPI_CR1_SSI; + (void)dummy; } void flash_read(char *buf, uint32_t addr, unsigned int count) { + (void)buf; + (void)addr; + (void)count; if (buf == 0) return; - gpio_dout(CS, 0); - flash_out(READ); - flash_addr(addr); - for (unsigned int i = 0; i < count; i++) - buf[i] = flash_in(); - gpio_dout(CS, 1); } void flash_write(const char *buf, uint32_t addr, unsigned int count) { + (void)buf; + (void)addr; + (void)count; if (buf == 0) return; - gpio_dout(CS, 0); - flash_out(WREN); - gpio_dout(CS, 1); - gpio_dout(CS, 0); - flash_out(WRITE); - flash_addr(addr); - for (unsigned int i = 0; i < count; i++) - flash_out(buf[i]); - gpio_dout(CS, 1); - delay(100); - //gpio_dout(CS, 0); - //flash_out(WRDS); - //gpio_dout(CS, 1); } |