diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2018-04-24 14:11:01 -0400 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2018-04-24 14:11:01 -0400 |
commit | c47485371ac69797b487f9549368fab62859de78 (patch) | |
tree | f10077a503379ada25c9f57622d9edd319c9c63d /old/flash.c | |
parent | 5df5c67397e2800182e5016ab89bbd17e4e67a5b (diff) |
file cleanup, better text, documentation
Diffstat (limited to 'old/flash.c')
-rw-r--r-- | old/flash.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/old/flash.c b/old/flash.c new file mode 100644 index 0000000..e3de420 --- /dev/null +++ b/old/flash.c @@ -0,0 +1,115 @@ +/** + * @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> + +#define READ 0x03 +#define WRITE 0x02 +#define WREN 0x06 +#define WRDS 0x04 + +#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_xchg(char *byte, int count); + +void flash_init(void) +{ + gpio_mode(NSS, ALTERNATE); + gpio_mode(SCK, ALTERNATE); + gpio_mode(MISO, ALTERNATE); + gpio_mode(MOSI, ALTERNATE); + GPIOB->AFR[1] |= 0x55550000; // alt mode SPI2 + + // clock enable + RCC->APB1ENR1 |= RCC_APB1ENR1_SPI2EN; + + 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; + + char buf[4]; + buf[0] = READ; + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + flash_xchg(buf, 4); +} + +void flash_xchg(char *byte, int count) +{ + 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); + + 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; + } + } + + 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; +} + +void flash_write(const char *buf, uint32_t addr, unsigned int count) +{ + (void)buf; + (void)addr; + (void)count; + if (buf == 0) + return; +} |