From 314846bee32479f8fd6aae46c508fdc7ff8e0a95 Mon Sep 17 00:00:00 2001 From: bnewbold Date: Thu, 5 Aug 2010 20:58:51 -0400 Subject: Partially working! Documented; see ./notes/fsmc.txt. Not yet integrated into .ld scripts or fully tested --- examples/test-fsmc.cpp | 80 ++++++++++++++++++-------------------------------- libmaple/exc.c | 1 - libmaple/fsmc.c | 25 +++++++++------- notes/fsmc.txt | 51 ++++++++++++++++++++++---------- 4 files changed, 79 insertions(+), 78 deletions(-) diff --git a/examples/test-fsmc.cpp b/examples/test-fsmc.cpp index a4e43d6..6449cfd 100644 --- a/examples/test-fsmc.cpp +++ b/examples/test-fsmc.cpp @@ -1,48 +1,17 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -/** - * @brief Sample main.cpp file. Sends "Hello world!" out SPI1. - * - * SPI1 is set up to be a master transmitter at 4.5MHz, little endianness, - * and SPI mode 0. - * - * Pin 10 is used as Chip Select - * - */ #include "wirish.h" #include "fsmc.h" #include "rcc.h" #include "gpio.h" -#define LED_PIN 23 -#define DISC_PIN 14 +#define LED_PIN 23 // hack for maple native +#define DISC_PIN 14 // hack for USB on native // System control block registers #define SCB_BASE (SCB_Reg*)(0xE000ED00) +// This stuff should ultimately get moved to util.h or scb.h or w/e. +// Also in interactive test program and the HardFault IRQ handler. typedef struct { volatile uint32 CPUID; volatile uint32 ICSR; @@ -65,6 +34,7 @@ SCB_Reg *scb; uint16 *ptr; int toggle = 0; +int count = 0; void setup() { uint32 id; @@ -84,26 +54,20 @@ void setup() { fsmc_native_sram_init(); Serial1.println("Done."); - + // Start of channel1 SRAM bank (through to 0x63FFFFFF, though only a chunk + // of this is valid) ptr = (uint16*)(0x60000000); - //ptr = (uint16*)(0x68000000); - //ptr = (uint16*)(0x80000000); - Serial1.print("Writing... "); - *ptr = 0xFFFF; + Serial1.print("Writing... "); + *ptr = 0x1234; Serial1.println("Done."); Serial1.print("Reading... "); id = *ptr; - Serial1.print("Done: "); - Serial1.println(id,BIN); - - /* - Serial1.print("CPUID is at: "); - id = (uint32)(&(scb->CPUID)); + Serial1.print("Done: "); // shouldn't be 0xFFFFFFFF Serial1.println(id,BIN); - */ + Serial1.println("Dumping System Control Block Registers"); Serial1.print("CPUID: "); id = scb->CPUID; Serial1.println(id,BIN); @@ -122,20 +86,32 @@ void setup() { Serial1.print("BFAR: "); id = scb->BFAR; Serial1.println(id,BIN); - + + Serial1.println("Now testing all memory addresses... (will hardfault at the end)"); + delay(3000); } void loop() { digitalWrite(LED_PIN, toggle); toggle ^= 1; - delay(100); + delay(1); - *ptr = 0xFFFF; - /* + ptr = (uint16*)(0x60000000); + count = 0; + for(int i = 0; i<1024; i++) { + count++; + ptr++; + *ptr = (0x0000FFFF & count); + //delay(10); // tweak this to test SRAM resiliance over time + if(*ptr != (0x0000FFFF & count)) { + Serial1.println("ERROR: mismatch, halting"); + while(1) { } + } + } + Serial1.print((uint32)(ptr),HEX); Serial1.print(": "); Serial1.println(*ptr,BIN); - */ } int main(void) { diff --git a/libmaple/exc.c b/libmaple/exc.c index 3d01492..dd02476 100644 --- a/libmaple/exc.c +++ b/libmaple/exc.c @@ -38,7 +38,6 @@ void NMIException(void) { } void HardFaultException(void) { - return; ASSERT(0); while(1) ; diff --git a/libmaple/fsmc.c b/libmaple/fsmc.c index 17431f5..4e25ef6 100644 --- a/libmaple/fsmc.c +++ b/libmaple/fsmc.c @@ -28,12 +28,14 @@ #include "gpio.h" #include "fsmc.h" -#define FSMC_ADDSET 0x5 -#define FSMC_DATAST 0x5 - -// Setup the FSMC peripheral to use the SRAM chip on the maple native -// as an external segment of memory space. -// This is for the IS62WV51216BLL 8meg 55ns chip +// These values determined for a particular SRAM chip by following the +// calculations in the ST FSMC application note. +#define FSMC_ADDSET 0x0 +#define FSMC_DATAST 0x3 + +// Sets up the FSMC peripheral to use the SRAM chip on the maple native as an +// external segment of system memory space. +// This implementation is for the IS62WV51216BLL 8mbit chip (55ns timing) void fsmc_native_sram_init(void) { FSMC_Bank *bank; @@ -87,8 +89,8 @@ void fsmc_native_sram_init(void) { gpio_set_mode(GPIOE_BASE, 0, MODE_AF_OUTPUT_PP); // NBL0 gpio_set_mode(GPIOE_BASE, 1, MODE_AF_OUTPUT_PP); // NBL1 - // Then we configure the FSMC SRAM channel 1 peripheral - // (the SRAM part of the FSMC is "bank 1") + // Then we configure channel 1 the FSMC SRAM peripheral + // (all SRAM channels are in "Bank 1" of the FSMC) bank = (FSMC_Bank*)(FSMC1_BASE); // Everything else is cleared (BCR1) @@ -104,6 +106,9 @@ void fsmc_native_sram_init(void) { // Memory is nonmultiplexed bank->BCR &= ~(FSMC_BCR_MUXEN); // '0' + // Need write enable to write to the chip + bank->BCR |= FSMC_BCR_WREN; + // Set ADDSET bank->BTR &= ~(FSMC_BTR_ADDSET); bank->BTR |= (FSMC_BTR_ADDSET | FSMC_ADDSET); @@ -112,9 +117,9 @@ void fsmc_native_sram_init(void) { bank->BTR &= ~(FSMC_BTR_DATAST); bank->BTR |= (FSMC_BTR_DATAST | (FSMC_DATAST << 8)); - // Enable bank1 + // Enable channel 1 bank->BCR |= FSMC_BCR_MBKEN; // '1' - // FSMC_BWTR3 not used + // FSMC_BWTR3 not used for this simple configuration. } diff --git a/notes/fsmc.txt b/notes/fsmc.txt index 583dba2..b41de60 100644 --- a/notes/fsmc.txt +++ b/notes/fsmc.txt @@ -1,18 +1,32 @@ -FSMC notes (for maple native) +FSMC notes (for maple native and other "high density" STM32 devices) ------------------------------------------------------------------------------- There is an application note for all this which is helpful; see the ST website. -Chip details +SRAM chip details IS62WV51216BLL 512k x 16 19 address input 16 data inputs + t_wc (write cycle) = 55ns + t_rc (write cycle) = 55ns + t_pwe1 (write enable low pulse) = 40ns + t_aa (address access) = 55ns -For simple debugging, i'm going to set all the access parameters to maximum -time values (aka, slowest). I'm going to use not-extended mode 1 for -read/write. + +The FSMC nomenclature is very confusing. There are three seperate "banks" +(which I will call "peripheral banks") each of specialized for different types +of external memory (NOR flash, NAND flash, SRAM, etc). We use the one for +"PSRAM" with our SRAM chip; it's bank #1. The SRAM peripheral bank is further +split into 4 "banks" (which I will call "channels") to support multiple +external devices with chip select pins. I think what's going on is that there +are 4 hardware peripherals and many sections of RAM; the docs are confusing +about what's a "block of memeory" and what's an "FSMC block". + +Anyways, this all takes place on the AHB memory bus. + +I'm going to use not-extended mode 1 for read/write. Steps from application note: @@ -22,21 +36,28 @@ Steps from application note: - memory is nonmultiplexed: BCR3_MEXEN is reset (= '0') - everything else is cleared -Parameters: - - t_wc (write cycle) = 55ns - t_rc (write cycle) = 55ns - t_pwe1 (write enable low pulse) = 40ns - t_aa (address access) = 55ns +But not true! Actually write enable needs to be set. -So address setup (ADDSET) = 0x0, data setup (DATAST) = 0x3 +Using the application note, which is based around a very similar chip (with +faster timing), I calculated an ADDSET (address setup) value of 0x0 and a +DATAST (data setup) value of 0x3. -Using bank1, NOR/PSRAM1 memory starts at 0x60000000. +Using channel1, NOR/PSRAM1 memory starts at 0x60000000. -Oops, obviously have to turn on the clock for all those GPIO pins... +Have to turn on the RCC clock for all those GPIO pins, but don't need to use +any interrupts. Not-super-helpful-link: http://www.keil.com/support/man/docs/mcbstm32e/mcbstm32e_to_xmemory.htm -PG9 (which is NE2) is twiddling on reset? +Note the possible confusion with address spaces, bitwidths, rollovers, etc. + + +TODO +------------------------------------------------------------------------------- +- more rigorous testing: throughput, latency, bounds checking, bitwidth, data + resiliance, etc. +- update .ld scripts to transparently make use of this external memory +- test/demo using a seperate external SRAM chip or screen +- write up documentation -- cgit v1.2.3