aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--examples/test-dac.cpp53
-rw-r--r--examples/test-fsmc.cpp119
-rw-r--r--libmaple/dac.c67
-rw-r--r--libmaple/dac.h108
-rw-r--r--libmaple/fsmc.c128
-rw-r--r--libmaple/fsmc.h86
-rw-r--r--libmaple/libmaple.h18
-rw-r--r--libmaple/rcc.c4
-rw-r--r--libmaple/rcc.h2
-rw-r--r--libmaple/rules.mk2
-rw-r--r--libmaple/usb/usb.c3
-rw-r--r--libmaple/usb/usb_config.h4
-rw-r--r--libmaple/util.c3
-rw-r--r--notes/dac.txt32
-rw-r--r--notes/fsmc.txt63
-rw-r--r--support/ld/flash.ld4
-rw-r--r--support/ld/jtag.ld4
-rw-r--r--support/ld/ram.ld4
-rw-r--r--support/openocd/flash.cfg6
-rw-r--r--wirish/wirish.c10
21 files changed, 701 insertions, 20 deletions
diff --git a/.gitignore b/.gitignore
index c764a06..5d7d6ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ main.cpp
libmaple.layout
tags
TAGS
+*.swp \ No newline at end of file
diff --git a/examples/test-dac.cpp b/examples/test-dac.cpp
new file mode 100644
index 0000000..65496f4
--- /dev/null
+++ b/examples/test-dac.cpp
@@ -0,0 +1,53 @@
+
+#include "wirish.h"
+#include "fsmc.h"
+#include "rcc.h"
+#include "gpio.h"
+#include "dac.h"
+
+#define LED_PIN 23 // hack for maple native
+#define DISC_PIN 14 // hack for USB on native
+
+int toggle = 0;
+uint16 count = 0;
+
+void setup() {
+
+ pinMode(LED_PIN, OUTPUT);
+ pinMode(DISC_PIN, OUTPUT);
+ digitalWrite(DISC_PIN,1);
+ digitalWrite(LED_PIN,1);
+
+ Serial1.begin(9600);
+ Serial1.println("Hello World!");
+
+ Serial1.print("Init... ");
+ dac_init();
+ Serial1.println("Done.");
+}
+
+void loop() {
+ digitalWrite(LED_PIN, toggle);
+ toggle ^= 1;
+ delay(100);
+
+ count += 100;
+
+ if(count > 4095) {
+ count = 0;
+ }
+
+ dac_write(1, 2048);
+ dac_write(2, count);
+}
+
+int main(void) {
+ init();
+ setup();
+
+ while (1) {
+ loop();
+ }
+ return 0;
+}
+
diff --git a/examples/test-fsmc.cpp b/examples/test-fsmc.cpp
new file mode 100644
index 0000000..f4fd068
--- /dev/null
+++ b/examples/test-fsmc.cpp
@@ -0,0 +1,119 @@
+
+#include "wirish.h"
+#include "fsmc.h"
+
+#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;
+ volatile uint32 VTOR;
+ volatile uint32 AIRCR;
+ volatile uint32 SCR;
+ volatile uint32 CCR;
+ volatile uint32 SHPR1;
+ volatile uint32 SHPR2;
+ volatile uint32 SHPR3;
+ volatile uint32 SHCRS;
+ volatile uint32 CFSR;
+ volatile uint32 HFSR;
+ uint32 pad1;
+ volatile uint32 MMAR;
+ volatile uint32 BFAR;
+} SCB_Reg;
+
+SCB_Reg *scb;
+
+uint16 *ptr;
+int toggle = 0;
+int count = 0;
+
+void setup() {
+ uint32 id;
+ scb = (SCB_Reg*)SCB_BASE;
+
+ pinMode(LED_PIN, OUTPUT);
+ pinMode(DISC_PIN, OUTPUT);
+ digitalWrite(DISC_PIN,1);
+ digitalWrite(LED_PIN,1);
+
+ Serial1.begin(9600);
+ Serial1.println("Hello World!");
+
+ Serial1.print("Init... ");
+ 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);
+
+ Serial1.print("Writing... ");
+ *ptr = 0x1234;
+ Serial1.println("Done.");
+
+ Serial1.print("Reading... ");
+ id = *ptr;
+ 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);
+ Serial1.print("ICSR: ");
+ id = scb->ICSR;
+ Serial1.println(id,BIN);
+ Serial1.print("CFSR: ");
+ id = scb->CFSR;
+ Serial1.println(id,BIN);
+ Serial1.print("HFSR: ");
+ id = scb->HFSR;
+ Serial1.println(id,BIN);
+ Serial1.print("MMAR: ");
+ id = scb->MMAR;
+ Serial1.println(id,BIN);
+ 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(1);
+
+ for(int i = 0; i<100; i++) { // modify this to speed things up
+ count++;
+ ptr++;
+ //delay(10); // tweak this to test SRAM resiliance over time
+ *ptr = (0x0000FFFF & count);
+ 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) {
+ init();
+ setup();
+
+ while (1) {
+ loop();
+ }
+ return 0;
+}
diff --git a/libmaple/dac.c b/libmaple/dac.c
new file mode 100644
index 0000000..ffc34f8
--- /dev/null
+++ b/libmaple/dac.c
@@ -0,0 +1,67 @@
+
+/* *****************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2010 Bryan Newbold.
+ *
+ * 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.
+ * ****************************************************************************/
+
+#include "libmaple.h"
+#include "rcc.h"
+#include "gpio.h"
+#include "dac.h"
+
+// Only one, so global to this file
+DAC_Map *dac = (DAC_Map*)(DAC_BASE);
+
+// This numbering follows the registers (1-indexed)
+#define DAC_CHA 1
+#define DAC_CHB 2
+
+// Sets up the DAC peripheral
+void dac_init(void) {
+
+ // First turn on the clock
+ rcc_clk_enable(RCC_DAC);
+
+ // Then setup ANALOG mode on PA4 and PA5
+ gpio_set_mode(GPIOA_BASE, 4, CNF_INPUT_ANALOG);
+ gpio_set_mode(GPIOA_BASE, 5, CNF_INPUT_ANALOG);
+
+ // Then do register stuff.
+ // Default does no triggering, and buffered output, so all good.
+ dac->CR |= DAC_CR_EN1;
+ dac->CR |= DAC_CR_EN2;
+
+}
+
+void dac_write(uint8 chan, uint16 val) {
+
+ switch(chan) {
+ case DAC_CHA:
+ dac->DHR12R1 = 0x0FFF & val;
+ break;
+ case DAC_CHB:
+ dac->DHR12R2 = 0x0FFF & val;
+ break;
+ default:
+ ASSERT(0); // Shouldn't get here
+ }
+}
diff --git a/libmaple/dac.h b/libmaple/dac.h
new file mode 100644
index 0000000..de1fd3f
--- /dev/null
+++ b/libmaple/dac.h
@@ -0,0 +1,108 @@
+/* *****************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2010 Bryan Newbold.
+ *
+ * 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.
+ * ****************************************************************************/
+
+/*
+ * See ../notes/dac.txt for more info
+ */
+
+#ifndef _DAC_H_
+#define _DAC_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#define DAC_BASE 0x40007400
+
+typedef struct {
+ volatile uint32 CR;
+ volatile uint32 SWTRIGR;
+ volatile uint32 DHR12R1;
+ volatile uint32 DHR12L1;
+ volatile uint32 DHR8R1;
+ volatile uint32 DHR12R2;
+ volatile uint32 DHR12L2;
+ volatile uint32 DHR8R2;
+ volatile uint32 DHR12RD;
+ volatile uint32 DHR12LD;
+ volatile uint32 DHR8RD;
+ volatile uint32 DOR1;
+ volatile uint32 DOR2;
+} DAC_Map;
+
+
+// And here are the register bit ranges
+#define DAC_CR_EN1 BIT(0)
+#define DAC_CR_BOFF1 BIT(1)
+#define DAC_CR_TEN1 BIT(2)
+#define DAC_CR_TSEL1 (BIT(3) | BIT(4) | BIT(5))
+#define DAC_CR_WAVE1 (BIT(6) | BIT(7))
+#define DAC_CR_MAMP1 (BIT(8) | BIT(9) | BIT(10) | BIT(11))
+#define DAC_CR_DMAEN1 BIT(12)
+#define DAC_CR_EN2 BIT(16)
+#define DAC_CR_BOFF2 BIT(17)
+#define DAC_CR_TEN2 BIT(18)
+#define DAC_CR_TSEL2 (BIT(19) | BIT(20) | BIT(21))
+#define DAC_CR_WAVE2 (BIT(22) | BIT(23))
+#define DAC_CR_MAMP2 (BIT(24) | BIT(25) | BIT(26) | BIT(27))
+#define DAC_CR_DMAEN2 BIT(28)
+
+#define DAC_SWTRIGR_SWTRIG1 BIT(0)
+#define DAC_SWTRIGR_SWTRIG2 BIT(1)
+
+#define DAC_DHR12R1_DACC1DHR 0x00000FFF
+
+#define DAC_DHR12L1_DACC1DHR 0x0000FFF0
+
+#define DAC_DHR8R1_DACC1DHR 0x000000FF
+
+#define DAC_DHR12R2_DACC2DHR 0x00000FFF
+
+#define DAC_DHR12L2_DACC2DHR 0x0000FFF0
+
+#define DAC_DHR8R2_DACC2DHR 0x000000FF
+
+#define DAC_DHR12RD_DACC1DHR 0x00000FFF
+#define DAC_DHR12RD_DACC2DHR 0x0FFF0000
+
+#define DAC_DHR12LD_DACC1DHR 0x0000FFF0
+#define DAC_DHR12LD_DACC2DHR 0xFFF00000
+
+#define DAC_DHR8RD_DACC1DHR 0x000000FF
+#define DAC_DHR8RD_DACC2DHR 0x0000FF00
+
+#define DAC_DOR1 0x00000FFF
+
+#define DAC_DOR2 0x00000FFF
+
+
+void dac_init(void);
+void dac_write(uint8 chan, uint16 val);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif
diff --git a/libmaple/fsmc.c b/libmaple/fsmc.c
new file mode 100644
index 0000000..502b7b4
--- /dev/null
+++ b/libmaple/fsmc.c
@@ -0,0 +1,128 @@
+
+/* *****************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2010 Bryan Newbold.
+ *
+ * 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.
+ * ****************************************************************************/
+
+#include "libmaple.h"
+#include "rcc.h"
+#include "gpio.h"
+#include "fsmc.h"
+
+// 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;
+
+ // First we setup all the GPIO pins.
+ // Data lines...
+ gpio_set_mode(GPIOD_BASE, 0, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOD_BASE, 1, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOD_BASE, 8, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOD_BASE, 9, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOD_BASE, 10, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOD_BASE, 14, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOD_BASE, 15, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOE_BASE, 7, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOE_BASE, 8, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOE_BASE, 9, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOE_BASE, 10, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOE_BASE, 11, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOE_BASE, 12, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOE_BASE, 13, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOE_BASE, 14, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOE_BASE, 15, MODE_AF_OUTPUT_PP);
+ // Address lines...
+ gpio_set_mode(GPIOD_BASE, 11, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOD_BASE, 12, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOD_BASE, 13, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOF_BASE, 0, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOF_BASE, 1, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOF_BASE, 2, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOF_BASE, 3, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOF_BASE, 4, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOF_BASE, 5, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOF_BASE, 12, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOF_BASE, 13, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOF_BASE, 14, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOF_BASE, 15, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOG_BASE, 0, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOG_BASE, 1, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOG_BASE, 2, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOG_BASE, 3, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOG_BASE, 4, MODE_AF_OUTPUT_PP);
+ gpio_set_mode(GPIOG_BASE, 5, MODE_AF_OUTPUT_PP);
+ // And control lines...
+ gpio_set_mode(GPIOD_BASE, 4, MODE_AF_OUTPUT_PP); // NOE
+ gpio_set_mode(GPIOD_BASE, 5, MODE_AF_OUTPUT_PP); // NWE
+
+ gpio_set_mode(GPIOD_BASE, 7, MODE_AF_OUTPUT_PP); // NE1
+ gpio_set_mode(GPIOG_BASE, 9, MODE_AF_OUTPUT_PP); // NE2
+ gpio_set_mode(GPIOG_BASE, 10, MODE_AF_OUTPUT_PP); // NE3
+ gpio_set_mode(GPIOG_BASE, 12, MODE_AF_OUTPUT_PP); // NE4
+
+ gpio_set_mode(GPIOE_BASE, 0, MODE_AF_OUTPUT_PP); // NBL0
+ gpio_set_mode(GPIOE_BASE, 1, MODE_AF_OUTPUT_PP); // NBL1
+
+ // Next enable the clock
+ rcc_clk_enable(RCC_FSMC);
+
+ // 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)
+ bank->BCR = 0x0000;
+
+ // Memory type is SRAM
+ bank->BCR &= ~(FSMC_BCR_MTYP); // '00'
+
+ // Databus width is 16bits
+ bank->BCR &= ~(FSMC_BCR_MWID);
+ bank->BCR |= 0x1 << 4; // '01'
+
+ // 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);
+
+ // Set DATAST
+ bank->BTR &= ~(FSMC_BTR_DATAST);
+ bank->BTR |= (FSMC_BTR_DATAST | (FSMC_DATAST << 8));
+
+ // Enable channel 1
+ bank->BCR |= FSMC_BCR_MBKEN; // '1'
+
+ // FSMC_BWTR3 not used for this simple configuration.
+}
+
diff --git a/libmaple/fsmc.h b/libmaple/fsmc.h
new file mode 100644
index 0000000..0ac4084
--- /dev/null
+++ b/libmaple/fsmc.h
@@ -0,0 +1,86 @@
+/* *****************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2010 Bryan Newbold.
+ *
+ * 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.
+ * ****************************************************************************/
+
+/*
+ * See ../notes/fsmc.txt for more info
+ */
+
+#ifndef _FSMC_H_
+#define _FSMC_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+// There are 4 FSMC chip-select devices; here are the SRAM-specific registers
+// for each
+
+#define FSMC1_BASE 0xA0000000
+#define FSMC2_BASE 0xA0000008
+#define FSMC3_BASE 0xA0000010
+#define FSMC4_BASE 0xA0000018
+
+typedef struct {
+ volatile uint32 BCR;
+ volatile uint32 BTR;
+ //uint32 pad[62]; // double check this?
+ //__io uint32 BWTR;
+} FSMC_Bank;
+
+// And here are the register bit ranges
+#define FSMC_BCR_MBKEN 0b00000000000000000000000000000001
+#define FSMC_BCR_MUXEN 0b00000000000000000000000000000010
+#define FSMC_BCR_MTYP 0b00000000000000000000000000001100
+#define FSMC_BCR_MWID 0b00000000000000000000000000110000
+#define FSMC_BCR_FACCEN 0b00000000000000000000000001000000
+#define FSMC_BCR_BURSTEN 0b00000000000000000000000100000000
+#define FSMC_BCR_WAITPOL 0b00000000000000000000001000000000
+#define FSMC_BCR_WRAPMOD 0b00000000000000000000010000000000
+#define FSMC_BCR_WAITCFG 0b00000000000000000000100000000000
+#define FSMC_BCR_WREN 0b00000000000000000001000000000000
+#define FSMC_BCR_WAITEN 0b00000000000000000010000000000000
+#define FSMC_BCR_EXTMOD 0b00000000000000000100000000000000
+#define FSMC_BCR_CBURSTRW 0b00000000000010000000000000000000
+#define FSMC_BTR_ADDSET 0b00000000000000000000000000001111
+#define FSMC_BTR_ADDHOLD 0b00000000000000000000000011110000
+#define FSMC_BTR_DATAST 0b00000000000000001111111100000000
+#define FSMC_BTR_BUSTURN 0b00000000000011110000000000000000
+#define FSMC_BTR_CLKDIV 0b00000000111100000000000000000000
+#define FSMC_BTR_DATALAT 0b00001111000000000000000000000000
+#define FSMC_BTR_ACCMOD 0b00110000000000000000000000000000
+#define FSMC_BWTR_ADDSET 0b00000000000000000000000000001111
+#define FSMC_BWTR_ADDHLD 0b00000000000000000000000011110000
+#define FSMC_BWTR_DATAST 0b00000000000000001111111100000000
+#define FSMC_BWTR_CLKDIV 0b00000000111100000000000000000000
+#define FSMC_BWTR_DATLAT 0b00001111000000000000000000000000
+#define FSMC_BWTR_ACCMOD 0b00110000000000000000000000000000
+
+void fsmc_native_sram_init(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif
diff --git a/libmaple/libmaple.h b/libmaple/libmaple.h
index a481e63..8e072c3 100644
--- a/libmaple/libmaple.h
+++ b/libmaple/libmaple.h
@@ -49,7 +49,10 @@
#define NR_TIMERS 4
// Has an FSMC bus?
- //#define HAS_FSMC // Maple does not
+ #define NR_FSMC 1
+
+ // Has an FSMC bus?
+ #define NR_DAC_PINS 2
// USB Identifier numbers
// Descriptor strings must be modified by hand in usb/descriptors.c for now
@@ -95,7 +98,10 @@
#define NR_TIMERS 8
// Has an FSMC bus?
- #define HAS_FSMC
+ #define NR_FSMC 1
+
+ // Has an FSMC bus?
+ #define NR_DAC_PINS 2
// USB Identifier numbers
// Descriptor strings must be modified by hand in usb/descriptors.c for now
@@ -110,11 +116,11 @@
#define STACK_TOP 0x20000800
// Debug port settings (from ASSERT)
- #define ERROR_LED_PORT GPIOA_BASE
- #define ERROR_LED_PIN 5
- #define ERROR_USART_NUM 2
+ #define ERROR_LED_PORT GPIOC_BASE
+ #define ERROR_LED_PIN 15
+ #define ERROR_USART_NUM 1
#define ERROR_USART_BAUD 9600
- #define ERROR_TX_PIN 2
+ #define ERROR_TX_PIN 10
#define ERROR_TX_PORT GPIOA_BASE
// Just in case, most boards have at least some memory
diff --git a/libmaple/rcc.c b/libmaple/rcc.c
index 848f59e..9bd2663 100644
--- a/libmaple/rcc.c
+++ b/libmaple/rcc.c
@@ -66,9 +66,11 @@ static const struct rcc_dev_info rcc_dev_table[] = {
[RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, // High-density devices only
[RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, // High-density devices only
[RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, // High-density devices only
- [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 }, // High-density devices only
+ [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 }, // High-density devices only
[RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 },
[RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 },
+ [RCC_FSMC] = { .clk_domain = AHB, .line_num = 8 }, // High-density devices only
+ [RCC_DAC] = { .clk_domain = APB1, .line_num = 9 }, // High-density devices only
};
/**
diff --git a/libmaple/rcc.h b/libmaple/rcc.h
index 3f55b4f..3651945 100644
--- a/libmaple/rcc.h
+++ b/libmaple/rcc.h
@@ -166,6 +166,8 @@ enum {
RCC_TIMER8, // High-density devices only (Maple Native)
RCC_SPI1,
RCC_SPI2,
+ RCC_FSMC, // High-density devices only (Maple Native)
+ RCC_DAC, // High-density devices only (Maple Native)
};
diff --git a/libmaple/rules.mk b/libmaple/rules.mk
index 60673fe..8428277 100644
--- a/libmaple/rules.mk
+++ b/libmaple/rules.mk
@@ -25,6 +25,8 @@ cSRCS_$(d) := systick.c \
rcc.c \
flash.c \
spi.c \
+ fsmc.c \
+ dac.c \
usb/usb.c \
usb/usb_callbacks.c \
usb/usb_hardware.c \
diff --git a/libmaple/usb/usb.c b/libmaple/usb/usb.c
index 23cde00..026d7f0 100644
--- a/libmaple/usb/usb.c
+++ b/libmaple/usb/usb.c
@@ -118,7 +118,8 @@ void setupUSB (void) {
pRCC->APB1ENR |= 0x00800000;
/* initialize the usb application */
- gpio_write_bit(USB_DISC_BANK,USB_DISC_PIN,0); /* present ourselves to the host */
+ gpio_write_bit(USB_DISC_BANK, USB_DISC_PIN, 0); /* present ourselves to the host */
+
USB_Init(); /* low level init routine provided by st lib */
}
diff --git a/libmaple/usb/usb_config.h b/libmaple/usb/usb_config.h
index 3aa01d5..27294dc 100644
--- a/libmaple/usb/usb_config.h
+++ b/libmaple/usb/usb_config.h
@@ -40,8 +40,8 @@
CNTR_ESOFM | \
CNTR_RESETM )
-#define USB_DISC_BANK GPIOC_BASE
-#define USB_DISC_PIN 12
+#define USB_DISC_BANK GPIOB_BASE
+#define USB_DISC_PIN 8
#define F_SUSPEND_ENABLED 1
diff --git a/libmaple/util.c b/libmaple/util.c
index 08e29fc..61beab8 100644
--- a/libmaple/util.c
+++ b/libmaple/util.c
@@ -67,7 +67,8 @@ void _fail(const char* file, int line, const char* exp) {
usart_putstr(ERROR_USART_NUM, ": ");
usart_putudec(ERROR_USART_NUM, line);
usart_putc(ERROR_USART_NUM, '\n');
-
+ usart_putc(ERROR_USART_NUM, '\r');
+
/* Turn on the error LED */
gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT_PP);
diff --git a/notes/dac.txt b/notes/dac.txt
new file mode 100644
index 0000000..9df0782
--- /dev/null
+++ b/notes/dac.txt
@@ -0,0 +1,32 @@
+
+DAC notes (for maple native and other "high density" STM32 devices)
+-------------------------------------------------------------------------------
+There is an ST application note for the DACs; it provides a lot of context but
+doesn't help setup the peripheral very much.
+
+For the first code iteration we'll just use 12-bit right-aligned single writes,
+so use DAC_DHR12Rx
+
+Once data is loaded into the digital registers, there are a number of possible
+triggers to start conversion to analog output: external interrupts, software
+control, and timer events. We'll just use software triggering for now.
+
+There is (obviously) DMA support for DAC output.
+
+There are noise output and triangle wave output features with variable
+amplitude.
+
+There are many additional modes to tigger output to both channels at the same
+time.
+
+Buffering will be enabled by default.
+
+TODO
+-------------------------------------------------------------------------------
+- sine wave demo using Timer interrupts
+- wirish implementation
+- documentation
+- higher performance modes?
+- signal quality testing
+- DMA output
+
diff --git a/notes/fsmc.txt b/notes/fsmc.txt
new file mode 100644
index 0000000..b41de60
--- /dev/null
+++ b/notes/fsmc.txt
@@ -0,0 +1,63 @@
+
+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.
+
+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
+
+
+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:
+
+- enable bank3: BCR3_MBKEN = '1'
+- memory type is SRAM: BCR3_MTYP = '00'
+- databuse weidth is 16bits: BCR3_MWID = '01'
+- memory is nonmultiplexed: BCR3_MEXEN is reset (= '0')
+- everything else is cleared
+
+But not true! Actually write enable needs to be set.
+
+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 channel1, NOR/PSRAM1 memory starts at 0x60000000.
+
+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
+
+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
+
diff --git a/support/ld/flash.ld b/support/ld/flash.ld
index 2043649..7e1e453 100644
--- a/support/ld/flash.ld
+++ b/support/ld/flash.ld
@@ -25,8 +25,8 @@
/* Define memory spaces. */
MEMORY
{
- ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
- rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K
+ ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
+ rom (rx) : ORIGIN = 0x08005000, LENGTH = 500K
}
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
diff --git a/support/ld/jtag.ld b/support/ld/jtag.ld
index 3823f4d..890f18a 100644
--- a/support/ld/jtag.ld
+++ b/support/ld/jtag.ld
@@ -8,8 +8,8 @@
/* Define memory spaces. */
MEMORY
{
- ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
- rom (rx) : ORIGIN = 0x08000000, LENGTH = 120K
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
diff --git a/support/ld/ram.ld b/support/ld/ram.ld
index 59aaeda..168c1da 100644
--- a/support/ld/ram.ld
+++ b/support/ld/ram.ld
@@ -25,8 +25,8 @@
/* Define memory spaces. */
MEMORY
{
- ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
- rom (rx) : ORIGIN = 0x00000000, LENGTH = 0K
+ ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
+ rom (rx) : ORIGIN = 0x08005000, LENGTH = 512K
}
diff --git a/support/openocd/flash.cfg b/support/openocd/flash.cfg
index eceac32..25fe23f 100644
--- a/support/openocd/flash.cfg
+++ b/support/openocd/flash.cfg
@@ -62,15 +62,15 @@ jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME
-$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0
+$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0
flash bank stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME
proc flash_chip {} {
echo "Halting..."
halt
- echo "Erasing 128KB..."
- flash erase_address 0x08000000 0x20000
+ echo "Erasing..."
+ flash erase_address 0x08000000 0x80000
echo "Flashing image..."
flash write_bank 0 build/maple.bin 0
echo "Verifying image..."
diff --git a/wirish/wirish.c b/wirish/wirish.c
index 69bd63b..41f5db4 100644
--- a/wirish/wirish.c
+++ b/wirish/wirish.c
@@ -39,6 +39,8 @@
#include "nvic.h"
#include "usb.h"
#include "rcc.h"
+#include "fsmc.h"
+#include "dac.h"
#include "flash.h"
void init(void) {
@@ -46,6 +48,14 @@ void init(void) {
flash_enable_prefetch();
flash_set_latency(FLASH_WAIT_STATE_2);
+ #if HAS_FSMC
+ fsmc_native_sram_init();
+ #endif
+
+ #if NR_DAC_PINS > 0
+ dac_init();
+ #endif
+
/* initialize clocks */
rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9);
rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1);