diff --git a/libinterp.a b/libinterp.a index 46f2a26..bec4e48 100644 Binary files a/libinterp.a and b/libinterp.a differ diff --git a/src/flash.c b/src/flash.c index e3de420..e194f85 100644 --- a/src/flash.c +++ b/src/flash.c @@ -1,23 +1,3 @@ -/** - * @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 . - */ - #include #include #include @@ -27,89 +7,111 @@ #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) +#define SCK GPIO_PORT(C, 14) +#define SI GPIO_PORT(C, 3) +#define SO GPIO_PORT(C, 2) +#define CS GPIO_PORT(C, 15) -void flash_xchg(char *byte, int count); +void flash_out(uint8_t); +uint8_t flash_in(void); 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 + 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; - // clock enable - RCC->APB1ENR1 |= RCC_APB1ENR1_SPI2EN; + //// pick FSEL! 0=1, 1=2 - 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; + //// FSIZE = 16, 2^17 bits = 1Mb + //QUADSPI->DCR = (16 << QUADSPI_DCR_FSIZE_Pos); - char buf[4]; - buf[0] = READ; - buf[1] = 0; - buf[2] = 0; - buf[3] = 0; - flash_xchg(buf, 4); + //// 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_xchg(char *byte, int count) +void flash_out(uint8_t byte) { - 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; - } + for (uint8_t i = 0; i < 8; i++) { + gpio_dout(SI, (byte & (1 << (7 - i)))); + gpio_dout(SCK, 1); + delay(1); + gpio_dout(SCK, 0); } - 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; - } +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); + delay(1); + gpio_dout(SCK, 0); } +} - SPI2->CR1 |= SPI_CR1_SSI; - (void)dummy; +uint8_t flash_in(void) +{ + uint8_t byte = 0; + for (uint8_t i = 0; i < 8; i++) { + gpio_dout(SCK, 1); + 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) { - (void)buf; - (void)addr; - (void)count; if (buf == 0) return; + gpio_dout(CS, 0); + delay(1); + 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)buf; - (void)addr; - (void)count; if (buf == 0) return; + gpio_dout(CS, 0); + delay(1); + flash_out(WREN); + gpio_dout(CS, 1); + delay(100); + 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); } 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 . + */ + #include #include #include @@ -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); } diff --git a/src/main.c b/src/main.c index 79f3e92..3696c18 100644 --- a/src/main.c +++ b/src/main.c @@ -57,6 +57,7 @@ int main(void) serial_init(); random_init(); keypad_init(); + flash_init(); gpio_mode(GPIOA, 5, OUTPUT); @@ -74,8 +75,16 @@ void kmain(void) dsp_init(); dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, dsp_color(0, 0, 0)); dsp_cursoron(); - keypad_start(); - task_start(task_interpreter, 4096); + + char buf[2] = {0, 0}; + buf[0] = 'A'; + flash_write(buf, 42, 1); + buf[0] = 0; + flash_read(buf, 42, 1); + dsp_puts(buf); + + //keypad_start(); + //task_start(task_interpreter, 4096); while (1) { gpio_dout(GPIOA, 5, 1);