You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
2.5 KiB
C

7 years ago
/**
* @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/>.
*/
7 years ago
#include <stm32l476xx.h>
#include <gpio.h>
#include <clock.h>
#define READ 0x03
#define WRITE 0x02
#define WREN 0x06
#define WRDS 0x04
7 years ago
#define NSS GPIO_PORT(B, 12)
#define SCK GPIO_PORT(B, 13)
#define MISO GPIO_PORT(B, 14)
#define MOSI GPIO_PORT(B, 15)
7 years ago
7 years ago
void flash_xchg(char *byte, int count);
7 years ago
void flash_init(void)
{
7 years ago
gpio_mode(NSS, ALTERNATE);
gpio_mode(SCK, ALTERNATE);
gpio_mode(MISO, ALTERNATE);
gpio_mode(MOSI, ALTERNATE);
GPIOB->AFR[1] |= 0x55550000; // alt mode SPI2
7 years ago
7 years ago
// clock enable
RCC->APB1ENR1 |= RCC_APB1ENR1_SPI2EN;
7 years ago
7 years ago
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;
7 years ago
7 years ago
char buf[4];
buf[0] = READ;
buf[1] = 0;
buf[2] = 0;
buf[3] = 0;
flash_xchg(buf, 4);
7 years ago
}
7 years ago
void flash_xchg(char *byte, int count)
7 years ago
{
7 years ago
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;
}
7 years ago
}
7 years ago
do status = SPI2->SR;
while (status & SPI_SR_BSY);
7 years ago
7 years ago
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;
}
7 years ago
}
7 years ago
SPI2->CR1 |= SPI_CR1_SSI;
(void)dummy;
7 years ago
}
void flash_read(char *buf, uint32_t addr, unsigned int count)
{
7 years ago
(void)buf;
(void)addr;
(void)count;
7 years ago
if (buf == 0)
return;
}
void flash_write(const char *buf, uint32_t addr, unsigned int count)
{
7 years ago
(void)buf;
(void)addr;
(void)count;
7 years ago
if (buf == 0)
return;
}