aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2010-08-05 20:58:51 -0400
committerbnewbold <bnewbold@robocracy.org>2010-08-05 21:47:47 -0400
commit314846bee32479f8fd6aae46c508fdc7ff8e0a95 (patch)
treed3271e5239fb972bcc73803de9c10cf9f4d318e6
parent0f55cc0d89dc018aa1a2e7ad1c926889f98ec26d (diff)
downloadlibrambutan-314846bee32479f8fd6aae46c508fdc7ff8e0a95.tar.gz
librambutan-314846bee32479f8fd6aae46c508fdc7ff8e0a95.zip
Partially working!
Documented; see ./notes/fsmc.txt. Not yet integrated into .ld scripts or fully tested
-rw-r--r--examples/test-fsmc.cpp80
-rw-r--r--libmaple/exc.c1
-rw-r--r--libmaple/fsmc.c25
-rw-r--r--notes/fsmc.txt51
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