diff options
author | bnewbold <bnewbold@robocracy.org> | 2010-09-01 00:02:36 -0400 |
---|---|---|
committer | bnewbold <bnewbold@robocracy.org> | 2010-09-01 00:02:36 -0400 |
commit | d6a32991684b7bfd8b91e3358dee4ca3fc887021 (patch) | |
tree | 535ebe6501bda800363c5f4debccf532d289bc1e | |
parent | 9c9d6c153154981fdedbe3f9ed4a1fb61e2b7776 (diff) | |
parent | 0ccec95446d4c7f3ea47a46d267c791fb22bb8d4 (diff) | |
download | librambutan-d6a32991684b7bfd8b91e3358dee4ca3fc887021.tar.gz librambutan-d6a32991684b7bfd8b91e3358dee4ca3fc887021.zip |
Various fixes, working with Maple
52 files changed, 1462 insertions, 326 deletions
@@ -4,3 +4,4 @@ libmaple.layout tags TAGS *~ +*.swp
\ No newline at end of file @@ -1,7 +1,22 @@ .DEFAULT_GOAL := sketch +# Valid BOARDs: maple, maple_native, ... BOARD ?= maple -MAPLE_TARGET ?= flash +MEMORY_TARGET ?= ram + +# USB ID for DFU upload +VENDOR_ID := 1EAF +PRODUCT_ID := 0003 + +# Guess the MCU based on the BOARD (can be overridden ) +ifeq ($(BOARD), maple) + MCU := STM32F103RB + PRODUCT_ID := 0003 +endif +ifeq ($(BOARD), maple_native) + MCU := STM32F103ZE + PRODUCT_ID := 0003 +endif # Useful paths ifeq ($(LIB_MAPLE_HOME),) @@ -15,8 +30,9 @@ SUPPORT_PATH := $(SRCROOT)/support # Useful variables GLOBAL_CFLAGS := -Os -g -mcpu=cortex-m3 -mthumb -march=armv7-m -nostdlib \ - -ffunction-sections -fdata-sections -Wl,--gc-sections -GLOBAL_CXXFLAGS := -fno-rtti -fno-exceptions -Wall + -ffunction-sections -fdata-sections -Wl,--gc-sections \ + -DBOARD_$(BOARD) -DMCU_$(MCU) +GLOBAL_CXXFLAGS := -fno-rtti -fno-exceptions -Wall -DBOARD_$(BOARD) -DMCU_$(MCU) LDDIR := $(SUPPORT_PATH)/ld @@ -28,20 +44,16 @@ LDFLAGS = -T$(LDDIR)/$(LDSCRIPT) -L$(LDDIR) \ include $(SUPPORT_PATH)/make/build-rules.mk include $(SUPPORT_PATH)/make/build-templates.mk -# Maple USB id -VENDOR_ID := 1EAF -PRODUCT_ID := 0003 - # Some target specific things -ifeq ($(MAPLE_TARGET), ram) +ifeq ($(MEMORY_TARGET), ram) VECT_BASE_ADDR := VECT_TAB_RAM LDSCRIPT := ram.ld endif -ifeq ($(MAPLE_TARGET), flash) +ifeq ($(MEMORY_TARGET), flash) LDSCRIPT := flash.ld VECT_BASE_ADDR := VECT_TAB_FLASH endif -ifeq ($(MAPLE_TARGET), jtag) +ifeq ($(MEMORY_TARGET), jtag) LDSCRIPT := jtag.ld VECT_BASE_ADDR := VECT_TAB_BASE endif @@ -76,7 +88,7 @@ install: $(BUILD_PATH)/$(BOARD).bin # Force a rebuild if the maple target changed PREV_BUILD_TYPE = $(shell cat $(BUILD_PATH)/build-type 2>/dev/null) build-check: -ifneq ($(PREV_BUILD_TYPE), $(MAPLE_TARGET)) +ifneq ($(PREV_BUILD_TYPE), $(MEMORY_TARGET)) $(shell rm -rf $(BUILD_PATH)) endif @@ -89,11 +101,11 @@ help: @echo "" @echo " libmaple Makefile help" @echo " ----------------------" - @echo " Compile targets (default MAPLE_TARGET=flash):" + @echo " Compile targets (default MEMORY_TARGET=flash):" @echo " ram: Compile sketch code to ram" @echo " flash: Compile sketch code to flash" @echo " jtag: Compile sketch code to jtag" - @echo " sketch: Compile sketch code to target MAPLE_TARGET" + @echo " sketch: Compile sketch code to target MEMORY_TARGET" @echo " " @echo " Programming targets:" @echo " install: Upload code to target" @@ -120,10 +132,10 @@ ctags: @echo "Made tags file for VIM code browsing" ram: - @$(MAKE) MAPLE_TARGET=ram --no-print-directory sketch + @$(MAKE) MEMORY_TARGET=ram --no-print-directory sketch flash: - @$(MAKE) MAPLE_TARGET=flash --no-print-directory sketch + @$(MAKE) MEMORY_TARGET=flash --no-print-directory sketch jtag: - @$(MAKE) MAPLE_TARGET=jtag --no-print-directory sketch + @$(MAKE) MEMORY_TARGET=jtag --no-print-directory sketch 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/adc.h b/libmaple/adc.h index 11aa5f6..f98a5f2 100644 --- a/libmaple/adc.h +++ b/libmaple/adc.h @@ -43,29 +43,32 @@ extern "C"{ * * Need to up the sample time if otherwise... see datasheet */ -/* We'll only use ADC1 for now... */ -#define ADC_BASE 0x40012400 -#define ADC_SR *(volatile uint32*)(ADC_BASE + 0) -#define ADC_CR1 *(volatile uint32*)(ADC_BASE + 0x4) -#define ADC_CR2 *(volatile uint32*)(ADC_BASE + 0x8) -#define ADC_SMPR1 *(volatile uint32*)(ADC_BASE + 0xC) -#define ADC_SMPR2 *(volatile uint32*)(ADC_BASE + 0x10) -#define ADC_SQR1 *(volatile uint32*)(ADC_BASE + 0x2C) -#define ADC_SQR3 *(volatile uint32*)(ADC_BASE + 0x34) -#define ADC_DR *(volatile uint32*)(ADC_BASE + 0x4C) +/* TODO: We'll only use ADC1 for now... */ +#define ADC1_BASE 0x40012400 +#define ADC2_BASE 0x40012400 +#define ADC3_BASE 0x40012400 + +#define ADC_SR *(volatile uint32*)(ADC1_BASE + 0) +#define ADC_CR1 *(volatile uint32*)(ADC1_BASE + 0x4) +#define ADC_CR2 *(volatile uint32*)(ADC1_BASE + 0x8) +#define ADC_SMPR1 *(volatile uint32*)(ADC1_BASE + 0xC) +#define ADC_SMPR2 *(volatile uint32*)(ADC1_BASE + 0x10) +#define ADC_SQR1 *(volatile uint32*)(ADC1_BASE + 0x2C) +#define ADC_SQR3 *(volatile uint32*)(ADC1_BASE + 0x34) +#define ADC_DR *(volatile uint32*)(ADC1_BASE + 0x4C) #define CR2_EXTSEL_SWSTART (0xE << 16) #define CR2_RSTCAL (BIT(3)) #define CR2_EXTTRIG (BIT(20)) /* Bit banded bits */ -#define CR2_ADON_BIT *(volatile uint32*)(BITBAND_PERI(ADC_BASE+0x8, 0)) -#define CR2_CAL_BIT *(volatile uint32*)(BITBAND_PERI(ADC_BASE+0x8, 2)) -#define CR2_RSTCAL_BIT *(volatile uint32*)(BITBAND_PERI(ADC_BASE+0x8, 3)) -#define CR2_SWSTART_BIT *(volatile uint32*)(BITBAND_PERI(ADC_BASE+0x8 + 2, 6)) -#define SR_EOC_BIT *(volatile uint32*)(BITBAND_PERI(ADC_BASE+0, 1)) +#define CR2_ADON_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 0)) +#define CR2_CAL_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 2)) +#define CR2_RSTCAL_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 3)) +#define CR2_SWSTART_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8 + 2, 6)) +#define SR_EOC_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0, 1)) -#define NR_ANALOG_PINS 29 +// NR_ANALOG_PINS is board specific /* Initialize ADC1 to do one-shot conversions */ void adc_init(void); @@ -88,8 +91,6 @@ static inline int adc_read(int channel) { return ADC_DR; } - - #ifdef __cplusplus } // extern "C" #endif 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/exti.h b/libmaple/exti.h index fdba184..2832e24 100644 --- a/libmaple/exti.h +++ b/libmaple/exti.h @@ -94,12 +94,11 @@ * EXTI[5-9] -> EXT9_5 * EXTI[10-15] -> EXT15_10 * - * * */ -#define NR_EXTI_CHANNELS 16 -#define NR_EXTI_PORTS 4 #define NR_EXTI_MODES 3 +#define NR_EXTI_CHANNELS 16 +#define NR_EXTI_PORTS NR_GPIO_PORTS // board specific #define EXTI_IMR 0x40010400 // Interrupt mask register #define EXTI_EMR (EXTI_IMR + 0x04) // Event mask register @@ -139,6 +138,9 @@ #define EXTI_CONFIG_PORTB 1 #define EXTI_CONFIG_PORTC 2 #define EXTI_CONFIG_PORTD 3 +#define EXTI_CONFIG_PORTE 4 // Native only +#define EXTI_CONFIG_PORTF 5 // Native only +#define EXTI_CONFIG_PORTG 6 // Native only #ifdef __cplusplus 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/gpio.c b/libmaple/gpio.c index 3e05bd0..c5bb450 100644 --- a/libmaple/gpio.c +++ b/libmaple/gpio.c @@ -37,6 +37,11 @@ void gpio_init(void) { rcc_clk_enable(RCC_GPIOB); rcc_clk_enable(RCC_GPIOC); rcc_clk_enable(RCC_GPIOD); + #if NR_GPIO_PORTS >= 7 + rcc_clk_enable(RCC_GPIOE); + rcc_clk_enable(RCC_GPIOF); + rcc_clk_enable(RCC_GPIOG); + #endif rcc_clk_enable(RCC_AFIO); } diff --git a/libmaple/gpio.h b/libmaple/gpio.h index 74320e6..9099c9b 100644 --- a/libmaple/gpio.h +++ b/libmaple/gpio.h @@ -44,10 +44,13 @@ * - After reset, the alternate functions are not active and IO prts * are set to Input Floating mode */ -#define GPIOA_BASE (GPIO_Port*)0x40010800 -#define GPIOB_BASE (GPIO_Port*)0x40010C00 -#define GPIOC_BASE (GPIO_Port*)0x40011000 -#define GPIOD_BASE (GPIO_Port*)0x40011400 +#define GPIOA_BASE (GPIO_Port*)0x40010800 +#define GPIOB_BASE (GPIO_Port*)0x40010C00 +#define GPIOC_BASE (GPIO_Port*)0x40011000 +#define GPIOD_BASE (GPIO_Port*)0x40011400 +#define GPIOE_BASE (GPIO_Port*)0x40011800 // High-density devices only +#define GPIOF_BASE (GPIO_Port*)0x40011C00 // High-density devices only +#define GPIOG_BASE (GPIO_Port*)0x40012000 // High-density devices only #define GPIO_SPEED_50MHZ (0x3) diff --git a/libmaple/libmaple.h b/libmaple/libmaple.h index 5360b51..3a4042a 100644 --- a/libmaple/libmaple.h +++ b/libmaple/libmaple.h @@ -32,6 +32,109 @@ #define _LIBMAPLE_H_ #include "libmaple_types.h" + +// General configuration +#define MAPLE_DEBUG 1 + +// MCU-specific configuration +#ifdef MCU_STM32F103RB // eg, LeafLabs Maple + + // Number of GPIO ports (GPIOA, GPIOB, etc), definately used + #define NR_GPIO_PORTS 4 + + // Total number of GPIO pins + #define NR_GPIO_PINS 39 + + // Number of timer devices ports, definately used + #define NR_TIMERS 4 + + // Number of USART ports + #define NR_USART 3 + + // Has an FSMC bus? + #define NR_FSMC 0 + + // Has an FSMC bus? + #define NR_DAC_PINS 0 + + // USB Identifier numbers + // Descriptor strings must be modified by hand in usb/descriptors.c for now + #define VCOM_ID_VENDOR 0x1EAF + #define VCOM_ID_PRODUCT 0x0004 + #define USB_DISC_BANK GPIOC_BASE + #define USB_DISC_PIN 12 + #define USB_CONFIG_MAX_POWER (100 >> 1) + #define RESET_DELAY (100) + + // Where to put usercode (based on space reserved for bootloader) + #define USER_ADDR_ROM 0x08005000 + #define USER_ADDR_RAM 0x20000C00 + #define STACK_TOP 0x20000800 + + // Debug port settings (from ASSERT) + #define ERROR_LED_PORT GPIOA_BASE + #define ERROR_LED_PIN 5 + #define ERROR_USART_NUM USART2 + #define ERROR_USART_BAUD 9600 + #define ERROR_TX_PIN 2 + #define ERROR_TX_PORT GPIOA_BASE + + // Just in case, most boards have at least some memory + #ifndef RAMSIZE + # define RAMSIZE (caddr_t)0x50000 + #endif + + // Bitbanded Memory sections + #define BITBAND_SRAM_REF 0x20000000 + #define BITBAND_SRAM_BASE 0x22000000 + #define BITBAND_PERI_REF 0x40000000 + #define BITBAND_PERI_BASE 0x42000000 +#endif + +#ifdef MCU_STM32F103ZE + // eg, LeafLabs Maple Native + #define NR_GPIO_PORTS 7 + #define NR_GPIO_PINS 63 + #define NR_TIMERS 8 + #define NR_USART 3 + #define NR_FSMC 1 + #define NR_DAC_PINS 2 + + #define VCOM_ID_VENDOR 0x1EAF + #define VCOM_ID_PRODUCT 0x0004 + #define USB_DISC_BANK GPIOB_BASE + #define USB_DISC_PIN 8 + #define USB_CONFIG_MAX_POWER (100 >> 1) + #define RESET_DELAY (100) + + #define USER_ADDR_ROM 0x08005000 + #define USER_ADDR_RAM 0x20000C00 + #define STACK_TOP 0x20000800 + + #define ERROR_LED_PORT GPIOC_BASE + #define ERROR_LED_PIN 15 + #define ERROR_USART_NUM USART1 + #define ERROR_USART_BAUD 9600 + #define ERROR_TX_PIN 10 + #define ERROR_TX_PORT GPIOA_BASE + + #ifndef RAMSIZE + # define RAMSIZE (caddr_t)0x50000 + #endif + + #define BITBAND_SRAM_REF 0x20000000 + #define BITBAND_SRAM_BASE 0x22000000 + #define BITBAND_PERI_REF 0x40000000 + #define BITBAND_PERI_BASE 0x42000000 +#endif + +// Make sure MCU-specific settings were defined +#ifndef NR_GPIO_PORTS +#error Error: No MCU type specified. Add something like -DMCU_STM32F103RB \ + to your compiler arguments (probably in a Makefile). +#endif + +// Requires board configuration info #include "util.h" #endif diff --git a/libmaple/nvic.c b/libmaple/nvic.c index 56b9940..60e7eac 100644 --- a/libmaple/nvic.c +++ b/libmaple/nvic.c @@ -44,8 +44,10 @@ void nvic_set_vector_table(uint32 addr, uint32 offset) { void nvic_irq_enable(uint32 n) { if (n < 32) { REG_SET_BIT(NVIC_ISER0, n); - } else { + } else if(n < 64) { REG_SET_BIT(NVIC_ISER1, n - 32); + } else { + REG_SET_BIT(NVIC_ISER2, n - 64); } } @@ -56,12 +58,19 @@ void nvic_irq_enable(uint32 n) { void nvic_irq_disable(uint32 n) { if (n < 32) { REG_SET_BIT(NVIC_ICER0, n); - } else { + } else if(n < 64) { REG_SET_BIT(NVIC_ICER1, n - 32); + } else { + REG_SET_BIT(NVIC_ICER2, n - 64); } } - +void nvic_irq_disable_all(void) { + short n; + for(n=0; n<65; n++) { + nvic_irq_disable(n); + } +} /** * @brief Initialice the NVIC at address addr diff --git a/libmaple/nvic.h b/libmaple/nvic.h index d256610..4e425c5 100644 --- a/libmaple/nvic.h +++ b/libmaple/nvic.h @@ -38,13 +38,13 @@ #define NVIC_ISER0 0xE000E100 #define NVIC_ISER1 0xE000E104 #define NVIC_ISER2 0xE000E108 -#define NVIC_ISER3 0xE000E10C +#define NVIC_ISER3 0xE000E10C // Non existant? /* NVIC Interrupt Clear registers */ #define NVIC_ICER0 0xE000E180 #define NVIC_ICER1 0xE000E184 #define NVIC_ICER2 0xE000E188 -#define NVIC_ICER3 0xE000E18C +#define NVIC_ICER3 0xE000E18C // Non existant? /* System control registers */ #define SCB_VTOR 0xE000ED08 // Vector table offset register @@ -52,10 +52,6 @@ #define NVIC_VectTab_RAM ((u32)0x20000000) #define NVIC_VectTab_FLASH ((u32)0x08000000) -/* Where to put code */ -#define USER_ADDR_ROM 0x08005000 -#define USER_ADDR_RAM 0x20000C00 - #ifdef __cplusplus extern "C"{ #endif @@ -65,9 +61,14 @@ enum { NVIC_TIMER2 = 28, NVIC_TIMER3 = 29, NVIC_TIMER4 = 30, + NVIC_TIMER5 = 50, // high density only (Maple Native) + NVIC_TIMER6 = 54, // high density only (Maple Native) + NVIC_TIMER7 = 55, // high density only (Maple Native) NVIC_USART1 = 37, NVIC_USART2 = 38, NVIC_USART3 = 39, + NVIC_USART4 = 52, // high density only (Maple Native) + NVIC_USART5 = 53, // high density only (Maple Native) }; @@ -77,6 +78,7 @@ enum { void nvic_init(void); void nvic_irq_enable(uint32 device); void nvic_irq_disable(uint32 device); +void nvic_irq_disable_all(void); #ifdef __cplusplus } diff --git a/libmaple/rcc.c b/libmaple/rcc.c index ab62025..9bd2663 100644 --- a/libmaple/rcc.c +++ b/libmaple/rcc.c @@ -31,48 +31,6 @@ #include "flash.h" #include "rcc.h" -/* registers */ -#define RCC_BASE 0x40021000 -#define RCC_CR (RCC_BASE + 0x0) -#define RCC_CFGR (RCC_BASE + 0x4) -#define RCC_CIR (RCC_BASE + 0x8) -#define RCC_APB2RSTR (RCC_BASE + 0xC) -#define RCC_APB1RSTR (RCC_BASE + 0x10) -#define RCC_AHBENR (RCC_BASE + 0x14) -#define RCC_APB2ENR (RCC_BASE + 0x18) -#define RCC_APB1ENR (RCC_BASE + 0x1C) -#define RCC_BDCR (RCC_BASE + 0x20) -#define RCC_CSR (RCC_BASE + 0x24) -#define RCC_AHBSTR (RCC_BASE + 0x28) -#define RCC_CFGR2 (RCC_BASE + 0x2C) - -#define RCC_CFGR_USBPRE (0x1 << 22) -#define RCC_CFGR_ADCPRE (0x3 << 14) -#define RCC_CFGR_PPRE1 (0x7 << 8) -#define RCC_CFGR_PPRE2 (0x7 << 11) -#define RCC_CFGR_HPRE (0xF << 4) -#define RCC_CFGR_PLLSRC (0x1 << 16) - -#define RCC_CFGR_SWS (0x3 << 2) -#define RCC_CFGR_SWS_PLL (0x2 << 2) -#define RCC_CFGR_SWS_HSE (0x1 << 2) - -#define RCC_CFGR_SW (0x3 << 0) -#define RCC_CFGR_SW_PLL (0x2 << 0) -#define RCC_CFGR_SW_HSE (0x1 << 0) - -/* CR status bits */ -#define RCC_CR_HSEON (0x1 << 16) -#define RCC_CR_HSERDY (0x1 << 17) -#define RCC_CR_PLLON (0x1 << 24) -#define RCC_CR_PLLRDY (0x1 << 25) - -#define RCC_WRITE_CFGR(val) __write(RCC_CFGR, val) -#define RCC_READ_CFGR() __read(RCC_CFGR) - -#define RCC_WRITE_CR(val) __write(RCC_CR, val) -#define RCC_READ_CR() __read(RCC_CR) - enum { APB1, APB2, @@ -90,17 +48,29 @@ static const struct rcc_dev_info rcc_dev_table[] = { [RCC_GPIOB] = { .clk_domain = APB2, .line_num = 3 }, [RCC_GPIOC] = { .clk_domain = APB2, .line_num = 4 }, [RCC_GPIOD] = { .clk_domain = APB2, .line_num = 5 }, + [RCC_GPIOE] = { .clk_domain = APB2, .line_num = 6 }, // High-density devices only + [RCC_GPIOF] = { .clk_domain = APB2, .line_num = 7 }, // High-density devices only + [RCC_GPIOG] = { .clk_domain = APB2, .line_num = 8 }, // High-density devices only [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 }, [RCC_ADC1] = { .clk_domain = APB2, .line_num = 9 }, + [RCC_ADC2] = { .clk_domain = APB2, .line_num = 10 }, [RCC_USART1] = { .clk_domain = APB2, .line_num = 14 }, [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, + [RCC_USART4] = { .clk_domain = APB1, .line_num = 19 }, // High-density devices only + [RCC_USART5] = { .clk_domain = APB1, .line_num = 20 }, // High-density devices only [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 11 }, [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 }, [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 }, [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 }, + [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_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 e6a28ea..3651945 100644 --- a/libmaple/rcc.h +++ b/libmaple/rcc.h @@ -29,6 +29,48 @@ #ifndef _RCC_H_ #define _RCC_H_ +/* registers */ +#define RCC_BASE 0x40021000 +#define RCC_CR (RCC_BASE + 0x0) +#define RCC_CFGR (RCC_BASE + 0x4) +#define RCC_CIR (RCC_BASE + 0x8) +#define RCC_APB2RSTR (RCC_BASE + 0xC) +#define RCC_APB1RSTR (RCC_BASE + 0x10) +#define RCC_AHBENR (RCC_BASE + 0x14) +#define RCC_APB2ENR (RCC_BASE + 0x18) +#define RCC_APB1ENR (RCC_BASE + 0x1C) +#define RCC_BDCR (RCC_BASE + 0x20) +#define RCC_CSR (RCC_BASE + 0x24) +#define RCC_AHBSTR (RCC_BASE + 0x28) +#define RCC_CFGR2 (RCC_BASE + 0x2C) + +#define RCC_CFGR_USBPRE (0x1 << 22) +#define RCC_CFGR_ADCPRE (0x3 << 14) +#define RCC_CFGR_PPRE1 (0x7 << 8) +#define RCC_CFGR_PPRE2 (0x7 << 11) +#define RCC_CFGR_HPRE (0xF << 4) +#define RCC_CFGR_PLLSRC (0x1 << 16) + +#define RCC_CFGR_SWS (0x3 << 2) +#define RCC_CFGR_SWS_PLL (0x2 << 2) +#define RCC_CFGR_SWS_HSE (0x1 << 2) + +#define RCC_CFGR_SW (0x3 << 0) +#define RCC_CFGR_SW_PLL (0x2 << 0) +#define RCC_CFGR_SW_HSE (0x1 << 0) + +/* CR status bits */ +#define RCC_CR_HSEON (0x1 << 16) +#define RCC_CR_HSERDY (0x1 << 17) +#define RCC_CR_PLLON (0x1 << 24) +#define RCC_CR_PLLRDY (0x1 << 25) + +#define RCC_WRITE_CFGR(val) __write(RCC_CFGR, val) +#define RCC_READ_CFGR() __read(RCC_CFGR) + +#define RCC_WRITE_CR(val) __write(RCC_CR, val) +#define RCC_READ_CR() __read(RCC_CR) + /* sysclk source */ #define RCC_CLKSRC_HSI (0x0) #define RCC_CLKSRC_HSE (0x1) @@ -87,34 +129,45 @@ #define RCC_PLLMUL_15 (0xD << 18) #define RCC_PLLMUL_16 (0xE << 18) -/* device numbers */ + +/* prescalers */ +enum { + RCC_PRESCALER_AHB, + RCC_PRESCALER_APB1, + RCC_PRESCALER_APB2, + RCC_PRESCALER_USB, + RCC_PRESCALER_ADC +}; + +// RCC Devices enum { RCC_GPIOA, RCC_GPIOB, RCC_GPIOC, RCC_GPIOD, + RCC_GPIOE, // High-density devices only (Maple Native) + RCC_GPIOF, // High-density devices only (Maple Native) + RCC_GPIOG, // High-density devices only (Maple Native) RCC_AFIO, RCC_ADC1, + RCC_ADC2, RCC_USART1, RCC_USART2, RCC_USART3, - RCC_USART4, - RCC_USART5, + RCC_USART4, // High-density devices only (Maple Native) + RCC_USART5, // High-density devices only (Maple Native) RCC_TIMER1, RCC_TIMER2, RCC_TIMER3, RCC_TIMER4, + RCC_TIMER5, // High-density devices only (Maple Native) + RCC_TIMER6, // High-density devices only (Maple Native) + RCC_TIMER7, // High-density devices only (Maple Native) + RCC_TIMER8, // High-density devices only (Maple Native) RCC_SPI1, RCC_SPI2, -}; - -/* prescalers */ -enum { - RCC_PRESCALER_AHB, - RCC_PRESCALER_APB1, - RCC_PRESCALER_APB2, - RCC_PRESCALER_USB, - RCC_PRESCALER_ADC + RCC_FSMC, // High-density devices only (Maple Native) + RCC_DAC, // High-density devices only (Maple Native) }; @@ -125,4 +178,3 @@ void rcc_set_prescaler(uint32 prescaler, uint32 divider); #endif - 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/spi.h b/libmaple/spi.h index 25c2c6b..742c1d0 100644 --- a/libmaple/spi.h +++ b/libmaple/spi.h @@ -36,6 +36,7 @@ extern "C" { /* peripheral addresses */ #define SPI1_BASE 0x40013000 #define SPI2_BASE 0x40003800 +#define SPI3_BASE 0x40003C00 /* baud rate prescaler bits */ #define CR1_BR 0x00000038 diff --git a/libmaple/syscalls.c b/libmaple/syscalls.c index 63ebb1e..ec271a2 100644 --- a/libmaple/syscalls.c +++ b/libmaple/syscalls.c @@ -28,13 +28,6 @@ /* _end is set in the linker command file */ extern caddr_t _end; -/* just in case, most boards have at least some memory */ -#ifndef RAMSIZE -# define RAMSIZE (caddr_t)0x50000 -#endif - -#define STACK_TOP 0x20000800 - void uart_send(const char*str); /* diff --git a/libmaple/timers.c b/libmaple/timers.c index 6e6653c..6fa2848 100644 --- a/libmaple/timers.c +++ b/libmaple/timers.c @@ -28,6 +28,8 @@ * @brief General timer routines */ +// TODO: actually support timer5 and timer8 + #include "libmaple.h" #include "rcc.h" #include "nvic.h" @@ -82,6 +84,10 @@ volatile static voidFuncPtr timer1_handlers[4]; volatile static voidFuncPtr timer2_handlers[4]; volatile static voidFuncPtr timer3_handlers[4]; volatile static voidFuncPtr timer4_handlers[4]; +#if NR_TIMERS >= 8 +volatile static voidFuncPtr timer5_handlers[4]; // High-density devices only +volatile static voidFuncPtr timer8_handlers[4]; // High-density devices only +#endif // This function should probably be rewriten to take (timer_num, mode) and have // prescaler set elsewhere. The mode can be passed through to set_mode at the @@ -110,6 +116,20 @@ void timer_init(uint8 timer_num, uint16 prescale) { timer = (Timer*)TIMER4_BASE; rcc_clk_enable(RCC_TIMER4); break; + #if NR_TIMERS >= 8 + case 5: + timer = (Timer*)TIMER5_BASE; + rcc_clk_enable(RCC_TIMER5); + break; + case 8: + timer = (Timer*)TIMER8_BASE; + rcc_clk_enable(RCC_TIMER8); + is_advanced = 1; + break; + #endif + default: + ASSERT(0); + return; } timer->CR1 = ARPE; // No clock division @@ -172,6 +192,9 @@ void timer_pause(uint8 timer_num) { case 4: timer = (Timer*)TIMER4_BASE; break; + default: + ASSERT(0); + return; } timer->CR1 &= ~(0x0001); // CEN } @@ -194,6 +217,9 @@ void timer_resume(uint8 timer_num) { case 4: timer = (Timer*)TIMER4_BASE; break; + default: + ASSERT(0); + return; } timer->CR1 |= 0x0001; // CEN } @@ -218,6 +244,9 @@ ASSERT(timer_num > 0 && timer_num <= 4); case 4: timer = (Timer*)TIMER4_BASE; break; + default: + ASSERT(0); + return; } timer->CNT = value; } @@ -241,6 +270,9 @@ uint16 timer_get_count(uint8 timer_num) { case 4: timer = (Timer*)TIMER4_BASE; break; + default: + ASSERT(0); + return; } return timer->CNT; } @@ -263,6 +295,9 @@ void timer_set_prescaler(uint8 timer_num, uint16 prescale) { case 4: timer = (Timer*)TIMER4_BASE; break; + default: + ASSERT(0); + return; } timer->PSC = prescale; } @@ -286,6 +321,9 @@ void timer_set_reload(uint8 timer_num, uint16 max_reload) { case 4: timer = (Timer*)TIMER4_BASE; break; + default: + ASSERT(0); + return; } timer->ARR = max_reload; } diff --git a/libmaple/timers.h b/libmaple/timers.h index c48ef42..c49a00e 100644 --- a/libmaple/timers.h +++ b/libmaple/timers.h @@ -89,6 +89,10 @@ typedef volatile uint32* TimerCCR; #define TIMER2_BASE 0x40000000 #define TIMER3_BASE 0x40000400 #define TIMER4_BASE 0x40000800 +#define TIMER5_BASE 0x40000C00 // High-density devices only (Maple Native) +#define TIMER6_BASE 0x40001000 // High-density devices only (Maple Native) +#define TIMER7_BASE 0x40001400 // High-density devices only (Maple Native) +#define TIMER8_BASE 0x40013400 // High-density devices only (Maple Native) #define ARPE BIT(7) // Auto-reload preload enable #define NOT_A_TIMER 0 @@ -116,6 +120,18 @@ typedef volatile uint32* TimerCCR; #define TIMER4_CH3_CCR (TimerCCR)(TIMER4_BASE + 0x3C) #define TIMER4_CH4_CCR (TimerCCR)(TIMER4_BASE + 0x40) +// Timer5 and Timer8 are in high-density devices only (such as Maple Native). +// Timer6 and Timer7 in these devices have no output compare pins. + +#define TIMER5_CH1_CCR (TimerCCR)(TIMER5_BASE + 0x34) +#define TIMER5_CH2_CCR (TimerCCR)(TIMER5_BASE + 0x38) +#define TIMER5_CH3_CCR (TimerCCR)(TIMER5_BASE + 0x3C) +#define TIMER5_CH4_CCR (TimerCCR)(TIMER5_BASE + 0x40) + +#define TIMER8_CH1_CCR (TimerCCR)(TIMER8_BASE + 0x34) +#define TIMER8_CH2_CCR (TimerCCR)(TIMER8_BASE + 0x38) +#define TIMER8_CH3_CCR (TimerCCR)(TIMER8_BASE + 0x3C) +#define TIMER8_CH4_CCR (TimerCCR)(TIMER8_BASE + 0x40) #define TIMER_DISABLED 0 #define TIMER_PWM 1 diff --git a/libmaple/usart.c b/libmaple/usart.c index 296a1fb..ef54ad0 100644 --- a/libmaple/usart.c +++ b/libmaple/usart.c @@ -33,16 +33,18 @@ #include "nvic.h" #include "usart.h" -#define USART1_BASE 0x40013800 -#define USART2_BASE 0x40004400 -#define USART3_BASE 0x40004800 - -#define USART_UE BIT(13) -#define USART_M BIT(12) -#define USART_TE BIT(3) -#define USART_RE BIT(2) -#define USART_RXNEIE BIT(5) // read data register not empty interrupt enable -#define USART_TC BIT(6) +#define USART1_BASE 0x40013800 +#define USART2_BASE 0x40004400 +#define USART3_BASE 0x40004800 +#define UART4_BASE 0x40004C00 // High-density devices only (Maple Native) +#define UART5_BASE 0x40005000 // High-density devices only (Maple Native) + +#define USART_UE BIT(13) +#define USART_M BIT(12) +#define USART_TE BIT(3) +#define USART_RE BIT(2) +#define USART_RXNEIE BIT(5) // read data register not empty interrupt enable +#define USART_TC BIT(6) /* usart descriptor table */ struct usart_dev usart_dev_table[] = { @@ -61,6 +63,20 @@ struct usart_dev usart_dev_table[] = { .rcc_dev_num = RCC_USART3, .nvic_dev_num = NVIC_USART3 }, + /* + #if NR_USART >= 5 + [UART4] = { + .base = (usart_port*)UART4_BASE, + .rcc_dev_num = RCC_UART4, + .nvic_dev_num = NVIC_UART4 + }, + [UART5] = { + .base = (usart_port*)UART5_BASE, + .rcc_dev_num = RCC_UART5, + .nvic_dev_num = NVIC_UART5 + }, + #endif + */ }; /* usart interrupt handlers */ @@ -75,6 +91,14 @@ void USART2_IRQHandler(void) { void USART3_IRQHandler(void) { rb_insert(&usart_dev_table[USART3].rb, (uint8)(((usart_port*)(USART3_BASE))->DR)); } +#if NR_USART >= 5 +void UART4_IRQHandler(void) { + rb_insert(&usart_dev_table[UART4].rb, (uint8)(((usart_port*)(UART4_BASE))->DR)); +} +void UART5_IRQHandler(void) { + rb_insert(&usart_dev_table[UART5].rb, (uint8)(((usart_port*)(UART5_BASE))->DR)); +} +#endif /** * @brief Enable a USART in single buffer transmission mode, multibuffer @@ -83,6 +107,7 @@ void USART3_IRQHandler(void) { * @param baud Baud rate to be set at */ void usart_init(uint8 usart_num, uint32 baud) { + ASSERT(usart_num <= NR_USART); usart_port *port; ring_buffer *ring_buf; @@ -121,6 +146,18 @@ void usart_init(uint8 usart_num, uint32 baud) { port->CR1 |= USART_UE; } +/** + * @brief Turn off all USARTs. + */ +void usart_disable_all() { + usart_disable(USART1); + usart_disable(USART2); + usart_disable(USART3); + #if NR_USART >= 5 + usart_disable(UART4); + usart_disable(UART5); + #endif +} /** * @brief Turn off a USART. @@ -130,7 +167,7 @@ void usart_disable(uint8 usart_num) { usart_port *port = usart_dev_table[usart_num].base; /* TC bit must be high before disabling the usart */ - while ((port->SR & USART_TC) == 0) + while((port->CR1 & USART_UE) && !(port->SR & USART_TC)) ; /* Disable UE */ diff --git a/libmaple/usart.h b/libmaple/usart.h index beffa89..2bc472f 100644 --- a/libmaple/usart.h +++ b/libmaple/usart.h @@ -42,6 +42,8 @@ enum { USART1, USART2, USART3, + UART4, + UART5, }; /* peripheral register struct */ @@ -113,6 +115,7 @@ static inline void usart_reset_rx(uint8 usart_num) { void usart_init(uint8 usart_num, uint32 baud); void usart_disable(uint8 usart_num); +void usart_disable_all(); void usart_putstr(uint8 usart_num, const char*); void usart_putudec(uint8 usart_num, uint32 val); diff --git a/libmaple/usb/descriptors.h b/libmaple/usb/descriptors.h index 1efe8c1..6652942 100644 --- a/libmaple/usb/descriptors.h +++ b/libmaple/usb/descriptors.h @@ -16,7 +16,7 @@ #define USB_DEVICE_SUBCLASS_CDC 0x00 #define USB_CONFIG_ATTR_BUSPOWERED 0b10000000 -#define USB_CONFIG_ATTR_SELF_POWERED 0b11000000 +#define USB_CONFIG_ATTR_SELF_POWERED 0b11000000 #define EP_TYPE_INTERRUPT 0x03 #define EP_TYPE_BULK 0x02 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 06c81ff..ba05d42 100644 --- a/libmaple/usb/usb_config.h +++ b/libmaple/usb/usb_config.h @@ -5,12 +5,6 @@ #include "usb_lib.h" -#define VCOM_ID_VENDOR 0x1EAF -#define VCOM_ID_PRODUCT 0x0004 - -#define USB_CONFIG_MAX_POWER (100 >> 1) -#define RESET_DELAY (100) - /* choose addresses to give endpoints the max 64 byte buffers */ #define USB_BTABLE_ADDRESS 0x00 #define VCOM_CTRL_EPNUM 0x00 @@ -46,9 +40,6 @@ CNTR_ESOFM | \ CNTR_RESETM ) -#define USB_DISC_BANK GPIOC_BASE -#define USB_DISC_PIN 12 - #define F_SUSPEND_ENABLED 1 #endif diff --git a/libmaple/usb/usb_hardware.h b/libmaple/usb/usb_hardware.h index 208fa3a..e4a26b4 100644 --- a/libmaple/usb/usb_hardware.h +++ b/libmaple/usb/usb_hardware.h @@ -30,7 +30,6 @@ /* macro'd register and peripheral definitions */ #define EXC_RETURN 0xFFFFFFF9 #define DEFAULT_CPSR 0x61000000 -#define STACK_TOP 0x20005000 #define RCC ((u32)0x40021000) #define FLASH ((u32)0x40022000) diff --git a/libmaple/util.c b/libmaple/util.c index 36173ee..a747948 100644 --- a/libmaple/util.c +++ b/libmaple/util.c @@ -36,13 +36,6 @@ #include "adc.h" #include "timers.h" -#define ERROR_LED_PORT GPIOA_BASE -#define ERROR_LED_PIN 5 -#define ERROR_USART_NUM 2 -#define ERROR_USART_BAUD 9600 -#define ERROR_TX_PIN 2 -#define ERROR_TX_PORT GPIOA_BASE - /* Error assert + fade */ void _fail(const char* file, int line, const char* exp) { int32 slope = 1; @@ -51,7 +44,7 @@ void _fail(const char* file, int line, const char* exp) { uint32 i = 0; /* Turn off interrupts */ - nvic_disable_interrupts(); + nvic_irq_disable_all(); /* Turn off timers */ timer_disable_all(); @@ -60,9 +53,7 @@ void _fail(const char* file, int line, const char* exp) { adc_disable(); /* Turn off all usarts */ - usart_disable(1); - usart_disable(2); - usart_disable(3); + usart_disable_all(); /* Initialize the error usart */ gpio_set_mode(ERROR_TX_PORT, ERROR_TX_PIN, GPIO_MODE_AF_OUTPUT_PP); @@ -76,13 +67,14 @@ 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); /* Turn the USB interrupt back on so the bootloader keeps on functioning */ - nvic_enable_interrupt(NVIC_INT_USBHP); - nvic_enable_interrupt(NVIC_INT_USBLP); + nvic_irq_enable(NVIC_INT_USBHP); + nvic_irq_enable(NVIC_INT_USBLP); /* Error fade */ while (1) { diff --git a/libmaple/util.h b/libmaple/util.h index c336e21..053731a 100644 --- a/libmaple/util.h +++ b/libmaple/util.h @@ -32,8 +32,6 @@ #ifndef _UTIL_H_ #define _UTIL_H_ -#define MAPLE_DEBUG 0 - #define BIT(shift) (1 << (shift)) #define BIT_MASK_SHIFT(mask, shift) ((mask) << (shift)) @@ -41,11 +39,7 @@ #define GET_BITS(x, m, n) ((((uint32)x) << (31 - (n))) >> ((31 - (n)) + (m))) /* Bit-banding macros */ -#define BITBAND_SRAM_REF 0x20000000 -#define BITBAND_SRAM_BASE 0x22000000 #define BITBAND_SRAM(a,b) ((BITBAND_SRAM_BASE + (a-BITBAND_SRAM_REF)*32 + (b*4))) // Convert SRAM address -#define BITBAND_PERI_REF 0x40000000 -#define BITBAND_PERI_BASE 0x42000000 #define BITBAND_PERI(a,b) ((BITBAND_PERI_BASE + (a-BITBAND_PERI_REF)*32 + (b*4))) // Convert PERI address #define REG_SET(reg, val) (*(volatile uint32*)(reg) = (val)) 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/notes/portable.txt b/notes/portable.txt new file mode 100644 index 0000000..69952d7 --- /dev/null +++ b/notes/portable.txt @@ -0,0 +1,100 @@ + +Disclaimer text: // High-density devices only (Maple Native) + + +Board portability is implemented by adding a header file to ./libmaple with the +name of the BOARD target, and then editing libmaple.h to add this file as an +option. + +A pin maple file should be added to ./notes describing the pin numbering + +Files to check by hand: +# adc.c +# adc.h +# exc.c +# exti.c +# exti.h +# flash.c +# flash.h +# gpio.c +# gpio.h +# libmaple_types.h +# nvic.c +# nvic.h +# rcc.c +# rcc.h +# ring_buffer.h +# rules.mk +# spi.c +- spi.h +# syscalls.c +# systick.c +# systick.h +# timers.c +# timers.h +# usart.c +# usart.h +# util.c +# util.h +# libmaple.h +# usb/* + +wirish/: +# bits.h +# boards.h +# cxxabi-compat.cpp +# ext_interrupts.c +# ext_interrupts.h +# HardwareTimer.cpp +# HardwareTimer.h +# io.h +# main.cxx +# Print.cpp +# Print.h +# pwm.c +# pwm.h +# rules.mk +# time.c +# time.h +# usb_serial.cpp +# usb_serial.h +# wirish_analog.c +# wirish.c +# wirish_digital.c +# wirish.h +# wirish_math.cpp +# wirish_math.h +# wirish_shift.c +# WProgram.h +- comm/ + + + +ADC Notes: + only using ADC1? + untested + +EXTI Notes: + need to update huge table in comments? + untested + +NVIC Notes: + I don't think NVIC_ISER3 and NVIC_ICER3 actually exist? + Only CANBUS and USB OTG use interrupts above #63, but I updated the nvic code anyways + +RCC Notes: + Added some clock stuff to all boards even though they aren't usable... blah. + +SPI Notes: + SPI3 is only in XL chips so didn't really handle that + +TIMER Notes: + High-density devices add an advanced timer (TIMER8) and another normal one (TIMER5). + TIMER6 and TIMER7 are much less useful. + There is some partial progress towards adding timer5/timer8 functionality, + but not much. This should probably all be rewritten. + The wirish timer implementation should be refactored to use pin numbers. + +USART Notes: + The USART/UART nomeclature is a little mixed up. + TODO: portability of HardwareSerial, HardwareSPI diff --git a/support/ld/flash.ld b/support/ld/flash.ld index 2043649..d05aa6c 100644 --- a/support/ld/flash.ld +++ b/support/ld/flash.ld @@ -26,7 +26,11 @@ MEMORY
{
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
- rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K
+ rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K
+/* native
+ 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..2ba3ce6 100644 --- a/support/ld/jtag.ld +++ b/support/ld/jtag.ld @@ -8,8 +8,12 @@ /* Define memory spaces. */
MEMORY
{
- ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
- rom (rx) : ORIGIN = 0x08000000, LENGTH = 120K
+ ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
+ rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K
+/* native
+ 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/ram.ld b/support/ld/ram.ld index 59aaeda..b9dd4ee 100644 --- a/support/ld/ram.ld +++ b/support/ld/ram.ld @@ -26,7 +26,11 @@ MEMORY
{
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
- rom (rx) : ORIGIN = 0x00000000, LENGTH = 0K
+ rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K
+/* native
+ ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
+ rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K
+*/
}
diff --git a/support/make/build-targets.mk b/support/make/build-targets.mk index 01097a7..448b1ee 100644 --- a/support/make/build-targets.mk +++ b/support/make/build-targets.mk @@ -15,7 +15,7 @@ $(BUILD_PATH)/$(BOARD).bin: $(BUILD_PATH)/$(BOARD).elf @echo " " @echo "Final Size:" @$(SIZE) $< - @echo $(MAPLE_TARGET) > $(BUILD_PATH)/build-type + @echo $(MEMORY_TARGET) > $(BUILD_PATH)/build-type $(BUILDDIRS): @mkdir -p $@ @@ -24,8 +24,9 @@ MSG_INFO: @echo "================================================================================" @echo "" @echo " Build info:" - @echo " BOARD:" $(BOARD) - @echo " MAPLE_TARGET:" $(MAPLE_TARGET) + @echo " BOARD: " $(BOARD) + @echo " MCU: " $(MCU) + @echo " MEMORY_TARGET: " $(MEMORY_TARGET) @echo "" @echo " See 'make help' for all possible targets" @echo "" diff --git a/support/openocd/flash.cfg b/support/openocd/flash.cfg index eceac32..41c6532 100644 --- a/support/openocd/flash.cfg +++ b/support/openocd/flash.cfg @@ -63,14 +63,18 @@ 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 +# TODO: native +#$_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..." + echo "Erasing..." flash erase_address 0x08000000 0x20000 + # TODO: native + #flash erase_address 0x08000000 0x80000 echo "Flashing image..." flash write_bank 0 build/maple.bin 0 echo "Verifying image..." diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp index 3c8e9f4..64fa222 100644 --- a/wirish/HardwareTimer.cpp +++ b/wirish/HardwareTimer.cpp @@ -32,10 +32,7 @@ #include "HardwareTimer.h" HardwareTimer::HardwareTimer(uint8 timerNum) { - ASSERT(timerNum == 1 || - timerNum == 2 || - timerNum == 3 || - timerNum == 4); + ASSERT(timerNum <= NR_TIMERS); this->timerNum = timerNum; // Need to remember over flow for bounds checking this->overflow = 0xFFFF; @@ -141,9 +138,43 @@ void HardwareTimer::detachCompare3Interrupt(void) { void HardwareTimer::detachCompare4Interrupt(void) { timer_detach_interrupt(this->timerNum,4); } +#if NR_TIMERS >= 8 +void HardwareTimer::setChannel5Mode(uint8 mode) { + timer_set_mode(this->timerNum,5,mode); +} +void HardwareTimer::setChannel8Mode(uint8 mode) { + timer_set_mode(this->timerNum,8,mode); +} +void HardwareTimer::setCompare5(uint16 val) { + if(val > this->overflow) + val = this->overflow; + timer_set_compare_value(this->timerNum,5,val); +} +void HardwareTimer::setCompare8(uint16 val) { + if(val > this->overflow) + val = this->overflow; + timer_set_compare_value(this->timerNum,8,val); +} +void HardwareTimer::attachCompare5Interrupt(voidFuncPtr handler) { + timer_attach_interrupt(this->timerNum,5,handler); +} +void HardwareTimer::attachCompare8Interrupt(voidFuncPtr handler) { + timer_attach_interrupt(this->timerNum,8,handler); +} +void HardwareTimer::detachCompare5Interrupt(void) { + timer_detach_interrupt(this->timerNum,5); +} +void HardwareTimer::detachCompare8Interrupt(void) { + timer_detach_interrupt(this->timerNum,8); +} +#endif HardwareTimer Timer1(1); HardwareTimer Timer2(2); HardwareTimer Timer3(3); HardwareTimer Timer4(4); +#if NR_TIMERS >= 8 +HardwareTimer Timer5(5); // High-density devices only +HardwareTimer Timer8(8); // High-density devices only +#endif diff --git a/wirish/HardwareTimer.h b/wirish/HardwareTimer.h index c79f54f..3f986e4 100644 --- a/wirish/HardwareTimer.h +++ b/wirish/HardwareTimer.h @@ -62,12 +62,26 @@ class HardwareTimer { void detachCompare2Interrupt(void); void detachCompare3Interrupt(void); void detachCompare4Interrupt(void); + #if NR_TIMERS >= 8 + void setChannel5Mode(uint8 mode); + void setChannel8Mode(uint8 mode); + void setCompare5(uint16 val); // truncates to overflow + void setCompare8(uint16 val); // truncates to overflow + void attachCompare5Interrupt(voidFuncPtr handler); + void attachCompare8Interrupt(voidFuncPtr handler); + void detachCompare5Interrupt(void); + void detachCompare8Interrupt(void); + #endif }; extern HardwareTimer Timer1; extern HardwareTimer Timer2; extern HardwareTimer Timer3; extern HardwareTimer Timer4; +#if NR_TIMERS >= 8 +extern HardwareTimer Timer5; +extern HardwareTimer Timer8; +#endif #endif diff --git a/wirish/boards.h b/wirish/boards.h new file mode 100644 index 0000000..11d1774 --- /dev/null +++ b/wirish/boards.h @@ -0,0 +1,222 @@ +/* ***************************************************************************** + * 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. + * ****************************************************************************/ + +// This file contains BOARD-specific pin mapping tables. To add a new board +// type, copy the "BOARD_maple" section below and edit it as needed, then +// update your build toolchain with a new "BOARD" type. This must match the +// seperate MCU type (which determines the ../libmaple configuration). + +#ifndef _BOARDS_H_ +#define _BOARDS_H_ + +#include "libmaple.h" +#include "gpio.h" +#include "timers.h" +#include "exti.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +// Set of all possible digital pin names; not all boards have all these +enum { + D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, + D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31, + D32, D33, D34, D35, D36, D37, D38, D39, D40, D41, D42, D43, D44, D45, D46, + D47, D48, D49, D50, D51, D52, D53, D54, D55, D56, D57, D58, D59, D60, D61, + D62, D63, D64, D65, D66, D67, D68, D69, D70, D71, D72, D73, D74, D75, D76, + D77, D78, D79, D80, D81, D82, D83, D84, D85, D86, D87, D88, D89, D90, D91, + D92, D93, D94, D95, D96, D97, D98, D99, D100, D101, D102, D103, D104, D105, + D106, D107, D108, D109, D110, D111, }; + +// Set of all possible analog pin names; not all boards have all these +enum { + ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, ADC10, ADC11, + ADC12, ADC13, ADC14, ADC15, ADC16, ADC17, ADC18, ADC19, ADC20, }; + +#define ADC_INVALID 0xFFFFFFFF +#define TIMER_INVALID (TimerCCR)0xFFFFFFFF + +// Types used for the tables below +typedef struct PinMapping { + GPIO_Port *port; + uint32 pin; + uint32 adc; + TimerCCR timer_channel; +} PinMapping; + +typedef struct ExtiInfo { + uint8 channel; + uint8 port; +} ExtiInfo; + +// LeafLabs Maple rev3, rev4 +#ifdef BOARD_maple + + #define CYCLES_PER_MICROSECOND 72 + #define MAPLE_RELOAD_VAL 72000 + + static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = { + {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR}, // D0/PA3 + {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR}, // D1/PA2 + {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR}, // D2/PA0 + {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR}, // D3/PA1 + {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID}, // D4/PB5 + {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR}, // D5/PB6 + {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR}, // D6/PA8 + {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR}, // D7/PA9 + {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR}, // D8/PA10 + {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR}, // D9/PB7 + {GPIOA_BASE, 4, ADC4, TIMER_INVALID}, // D10/PA4 + {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR}, // D11/PA7 + {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR}, // D12/PA6 + {GPIOA_BASE, 5, ADC5, TIMER_INVALID}, // D13/PA5 + {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR}, // D14/PB8 + /* Little header */ + {GPIOC_BASE, 0, ADC10, TIMER_INVALID}, // D15/PC0 + {GPIOC_BASE, 1, ADC11, TIMER_INVALID}, // D16/PC1 + {GPIOC_BASE, 2, ADC12, TIMER_INVALID}, // D17/PC2 + {GPIOC_BASE, 3, ADC13, TIMER_INVALID}, // D18/PC3 + {GPIOC_BASE, 4, ADC14, TIMER_INVALID}, // D19/PC4 + {GPIOC_BASE, 5, ADC15, TIMER_INVALID}, // D20/PC5 + /* External header */ + {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D21/PC13 + {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D22/PC14 + {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D23/PC15 + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR}, // D24/PB9 + {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID}, // D25/PD2 + {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D26/PC10 + {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR}, // D27/PB0 + {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR}, // D28/PB1 + {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D29/PB10 + {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID}, // D30/PB11 + {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID}, // D31/PB12 + {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D32/PB13 + {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D33/PB14 + {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D34/PB15 + {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID}, // D35/PC6 + {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID}, // D36/PC7 + {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID}, // D37/PC8 + {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID} // D38/PC9 (BUT) + }; + + static __attribute__ ((unused)) ExtiInfo PIN_TO_EXTI_CHANNEL[NR_GPIO_PINS] = + { + {EXTI3, EXTI_CONFIG_PORTA}, // D0/PA3 + {EXTI2, EXTI_CONFIG_PORTA}, // D1/PA2 + {EXTI0, EXTI_CONFIG_PORTA}, // D2/PA0 + {EXTI1, EXTI_CONFIG_PORTA}, // D3/PA1 + {EXTI5, EXTI_CONFIG_PORTB}, // D4/PB5 + {EXTI6, EXTI_CONFIG_PORTB}, // D5/PB6 + {EXTI8, EXTI_CONFIG_PORTA}, // D6/PA8 + {EXTI9, EXTI_CONFIG_PORTA}, // D7/PA9 + {EXTI10, EXTI_CONFIG_PORTA}, // D8/PA10 + {EXTI7, EXTI_CONFIG_PORTB}, // D9/PB7 + {EXTI4, EXTI_CONFIG_PORTA}, // D10/PA4 + {EXTI7, EXTI_CONFIG_PORTA}, // D11/PA7 + {EXTI6, EXTI_CONFIG_PORTA}, // D12/PA6 + {EXTI5, EXTI_CONFIG_PORTA}, // D13/PA5 + }; + +#endif + +// LeafLabs Maple Native (prototype) +#ifdef BOARD_maple_native + + #define CYCLES_PER_MICROSECOND 72 + #define MAPLE_RELOAD_VAL 72000 + + // TODO: + static PinMapping PIN_MAP[NR_GPIO_PINS] = { + {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR}, // D0/PA3 + {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR}, // D1/PA2 + {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR}, // D2/PA0 + {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR}, // D3/PA1 + {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID}, // D4/PB5 + {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR}, // D5/PB6 + {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR}, // D6/PA8 + {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR}, // D7/PA9 + {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR}, // D8/PA10 + {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR}, // D9/PB7 + {GPIOA_BASE, 4, ADC4, TIMER_INVALID}, // D10/PA4 + {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR}, // D11/PA7 + {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR}, // D12/PA6 + {GPIOA_BASE, 5, ADC5, TIMER_INVALID}, // D13/PA5 + {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR}, // D14/PB8 + /* Little header */ + {GPIOC_BASE, 0, ADC10, TIMER_INVALID}, // D15/PC0 + {GPIOC_BASE, 1, ADC11, TIMER_INVALID}, // D16/PC1 + {GPIOC_BASE, 2, ADC12, TIMER_INVALID}, // D17/PC2 + {GPIOC_BASE, 3, ADC13, TIMER_INVALID}, // D18/PC3 + {GPIOC_BASE, 4, ADC14, TIMER_INVALID}, // D19/PC4 + {GPIOC_BASE, 5, ADC15, TIMER_INVALID}, // D20/PC5 + /* External header */ + {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D21/PC13 + {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D22/PC14 + {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D23/PC15 + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR}, // D24/PB9 + {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID}, // D25/PD2 + {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D26/PC10 + {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR}, // D27/PB0 + {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR}, // D28/PB1 + {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D29/PB10 + {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID}, // D30/PB11 + {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID}, // D31/PB12 + {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D32/PB13 + {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D33/PB14 + {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D34/PB15 + {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID}, // D35/PC6 + {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID}, // D36/PC7 + {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID}, // D37/PC8 + {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID} // D38/PC9 (BUT) + }; + + static ExtiInfo PIN_TO_EXTI_CHANNEL[NR_GPIO_PINS] = { + {EXTI3, EXTI_CONFIG_PORTA}, // D0/PA3 + {EXTI2, EXTI_CONFIG_PORTA}, // D1/PA2 + {EXTI0, EXTI_CONFIG_PORTA}, // D2/PA0 + {EXTI1, EXTI_CONFIG_PORTA}, // D3/PA1 + {EXTI5, EXTI_CONFIG_PORTB}, // D4/PB5 + {EXTI6, EXTI_CONFIG_PORTB}, // D5/PB6 + {EXTI8, EXTI_CONFIG_PORTA}, // D6/PA8 + {EXTI9, EXTI_CONFIG_PORTA}, // D7/PA9 + {EXTI10, EXTI_CONFIG_PORTA}, // D8/PA10 + {EXTI7, EXTI_CONFIG_PORTB}, // D9/PB7 + {EXTI4, EXTI_CONFIG_PORTA}, // D10/PA4 + {EXTI7, EXTI_CONFIG_PORTA}, // D11/PA7 + {EXTI6, EXTI_CONFIG_PORTA}, // D12/PA6 + {EXTI5, EXTI_CONFIG_PORTA}, // D13/PA5 + }; +#endif + +#ifndef CYCLES_PER_MICROSECOND +#error Board type has not been selected correctly. +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif + diff --git a/wirish/comm/HardwareSerial.cpp b/wirish/comm/HardwareSerial.cpp index c1babff..6399ad5 100644 --- a/wirish/comm/HardwareSerial.cpp +++ b/wirish/comm/HardwareSerial.cpp @@ -37,6 +37,7 @@ HardwareSerial Serial1(USART1, 4500000UL, GPIOA_BASE, 9, 10, 1, 2); HardwareSerial Serial2(USART2, 2250000UL, GPIOA_BASE, 2, 3, 2, 3); HardwareSerial Serial3(USART3, 2250000UL, GPIOB_BASE, 10, 11, 0, 0); +// TODO: High density device ports HardwareSerial::HardwareSerial(uint8 usart_num, uint32 max_baud, diff --git a/wirish/comm/HardwareSerial.h b/wirish/comm/HardwareSerial.h index c2209ce..df8d7bf 100644 --- a/wirish/comm/HardwareSerial.h +++ b/wirish/comm/HardwareSerial.h @@ -61,5 +61,6 @@ class HardwareSerial : public Print { extern HardwareSerial Serial1; extern HardwareSerial Serial2; extern HardwareSerial Serial3; +// TODO: high density device ports #endif diff --git a/wirish/ext_interrupts.c b/wirish/ext_interrupts.c index 1fa50fe..6ba1d05 100644 --- a/wirish/ext_interrupts.c +++ b/wirish/ext_interrupts.c @@ -32,29 +32,6 @@ #include "exti.h" #include "ext_interrupts.h" -typedef struct ExtiInfo { - uint8 channel; - uint8 port; -} ExtiInfo; - -static ExtiInfo PIN_TO_EXTI_CHANNEL[NR_MAPLE_PINS] = { - {EXTI3, EXTI_CONFIG_PORTA}, // D0/PA3 - {EXTI2, EXTI_CONFIG_PORTA}, // D1/PA2 - {EXTI0, EXTI_CONFIG_PORTA}, // D2/PA0 - {EXTI1, EXTI_CONFIG_PORTA}, // D3/PA1 - {EXTI5, EXTI_CONFIG_PORTB}, // D4/PB5 - {EXTI6, EXTI_CONFIG_PORTB}, // D5/PB6 - {EXTI8, EXTI_CONFIG_PORTA}, // D6/PA8 - {EXTI9, EXTI_CONFIG_PORTA}, // D7/PA9 - {EXTI10, EXTI_CONFIG_PORTA}, // D8/PA10 - {EXTI7, EXTI_CONFIG_PORTB}, // D9/PB7 - {EXTI4, EXTI_CONFIG_PORTA}, // D10/PA4 - {EXTI7, EXTI_CONFIG_PORTA}, // D11/PA7 - {EXTI6, EXTI_CONFIG_PORTA}, // D12/PA6 - {EXTI5, EXTI_CONFIG_PORTA}, // D13/PA5 -}; - - /** * @brief Attach an interrupt handler to be triggered on a given * transition on the pin. Runs in interrupt context @@ -68,7 +45,7 @@ static ExtiInfo PIN_TO_EXTI_CHANNEL[NR_MAPLE_PINS] = { int attachInterrupt(uint8 pin, voidFuncPtr handler, uint32 mode) { uint8 outMode; /* Parameter checking */ - if (pin >= NR_MAPLE_PINS) { + if (pin >= NR_GPIO_PINS) { return EXT_INTERRUPT_INVALID_PIN; } @@ -100,7 +77,7 @@ int attachInterrupt(uint8 pin, voidFuncPtr handler, uint32 mode) { } int detachInterrupt(uint8 pin) { - if (!(pin < NR_MAPLE_PINS)) { + if (!(pin < NR_GPIO_PINS)) { return EXT_INTERRUPT_INVALID_PIN; } diff --git a/wirish/io.h b/wirish/io.h index fff551c..e779604 100644 --- a/wirish/io.h +++ b/wirish/io.h @@ -38,48 +38,6 @@ extern "C"{ #endif -/* stash these here for now */ -#define D0 0 -#define D1 1 -#define D2 2 -#define D3 3 -#define D4 4 -#define D5 5 -#define D6 6 -#define D7 7 -#define D8 8 -#define D9 9 -#define D10 10 -#define D11 11 -#define D12 12 -#define D13 13 -#define D14 14 -#define D15 15 -#define D16 16 -#define D16 16 -#define D17 17 -#define D18 18 -#define D19 19 -#define D20 20 -#define D21 21 -#define D22 22 -#define D23 23 -#define D24 24 -#define D25 25 -#define D26 26 -#define D27 27 -#define D28 28 -#define D29 29 -#define D30 30 -#define D31 31 -#define D32 32 -#define D33 33 -#define D34 34 -#define D35 35 -#define D36 36 -#define D37 37 -#define D38 38 -#define D39 39 typedef enum WiringPinMode { OUTPUT, @@ -92,15 +50,6 @@ typedef enum WiringPinMode { PWM } WiringPinMode; -typedef struct PinMapping { - GPIO_Port *port; - uint32 pin; - uint32 adc; - TimerCCR timer_channel; -} PinMapping; - -#define ADC_INVALID 0xFFFFFFFF -#define TIMER_INVALID (TimerCCR)0xFFFFFFFF /* Set pin to mode * pinMode(pin, mode): diff --git a/wirish/pwm.c b/wirish/pwm.c index 40715b5..995e2c7 100644 --- a/wirish/pwm.c +++ b/wirish/pwm.c @@ -31,12 +31,10 @@ #include "io.h" #include "pwm.h" -extern const PinMapping PIN_MAP[NR_MAPLE_PINS]; - void pwmWrite(uint8 pin, uint16 duty_cycle) { TimerCCR ccr; - if (pin >= NR_MAPLE_PINS) { + if (pin >= NR_GPIO_PINS) { return; } diff --git a/wirish/time.c b/wirish/time.c index c0fd03e..ea8ebe1 100644 --- a/wirish/time.c +++ b/wirish/time.c @@ -39,6 +39,7 @@ void delay(unsigned long ms) } void delayMicroseconds(uint32 us) { + // So (2^32)/12 micros max, or less than 6 minutes us *= 12; /* fudge for function call overhead */ diff --git a/wirish/time.h b/wirish/time.h index 45e82dc..f73d133 100644 --- a/wirish/time.h +++ b/wirish/time.h @@ -35,10 +35,9 @@ extern "C"{ #include "nvic.h" #include "systick.h" +#include "boards.h" -#define CYCLES_PER_MICROSECOND 72 #define US_PER_MS 1000 -#define MAPLE_RELOAD_VAL 72000 extern volatile uint32 systick_timer_millis; diff --git a/wirish/wirish.c b/wirish/wirish.c index 4281875..9f3b19e 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 NR_FSMC > 0 + 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); @@ -60,5 +70,9 @@ void init(void) { timer_init(2, 1); timer_init(3, 1); timer_init(4, 1); + #if NR_TIMERS >= 8 + timer_init(5, 1); + timer_init(8, 1); + #endif setupUSB(); } diff --git a/wirish/wirish.h b/wirish/wirish.h index 9ca5692..d293901 100644 --- a/wirish/wirish.h +++ b/wirish/wirish.h @@ -32,10 +32,11 @@ #define _WIRISH_H_ #include "libmaple.h" +#include "boards.h" +#include "time.h" #include "timers.h" #include "io.h" #include "bits.h" -#include "time.h" #include "pwm.h" #include "ext_interrupts.h" #include "wirish_math.h" @@ -52,9 +53,6 @@ extern "C"{ #endif -#define MAPLE 1 -#define NR_MAPLE_PINS 39 // temporary - /* Arduino wiring macros and bit defines */ #define HIGH 0x1 #define LOW 0x0 @@ -65,9 +63,6 @@ extern "C"{ #define LSBFIRST 0 #define MSBFIRST 1 -#define USER_ADDR_ROM 0x08005000 -#define USER_ADDR_RAM 0x20000C00 - #define lowByte(w) ((w) & 0xff) #define highByte(w) ((w) >> 8) #define bitRead(value, bit) (((value) >> (bit)) & 0x01) @@ -87,8 +82,5 @@ void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, byte val); } // extern "C" #endif - - - #endif diff --git a/wirish/wirish_analog.c b/wirish/wirish_analog.c index f4c1204..1b911bc 100644 --- a/wirish/wirish_analog.c +++ b/wirish/wirish_analog.c @@ -30,13 +30,12 @@ #include "wirish.h" #include "io.h" -extern const PinMapping PIN_MAP[NR_MAPLE_PINS]; - /* Assumes that the ADC has been initialized and * that the pin is set to ANALOG_INPUT */ uint32 analogRead(uint8 pin) { - if (pin >= NR_ANALOG_PINS) + if(PIN_MAP[pin].adc == ADC_INVALID) { return 0; + } return adc_read(PIN_MAP[pin].adc); } diff --git a/wirish/wirish_digital.c b/wirish/wirish_digital.c index 33217b6..c93c786 100644 --- a/wirish/wirish_digital.c +++ b/wirish/wirish_digital.c @@ -29,72 +29,10 @@ #include "wirish.h" #include "io.h" -#define ADC0 0 -#define ADC1 1 -#define ADC2 2 -#define ADC3 3 -#define ADC4 4 -#define ADC5 5 -#define ADC6 6 -#define ADC7 7 -#define ADC8 8 -#define ADC9 9 -#define ADC10 10 -#define ADC11 11 -#define ADC12 12 -#define ADC13 13 -#define ADC14 14 -#define ADC15 15 -#define ADC16 16 - -const PinMapping PIN_MAP[NR_MAPLE_PINS] = { - {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR}, // D0/PA3 - {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR}, // D1/PA2 - {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR}, // D2/PA0 - {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR}, // D3/PA1 - {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID}, // D4/PB5 - {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR}, // D5/PB6 - {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR}, // D6/PA8 - {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR}, // D7/PA9 - {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR}, // D8/PA10 - {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR}, // D9/PB7 - {GPIOA_BASE, 4, ADC4, TIMER_INVALID}, // D10/PA4 - {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR}, // D11/PA7 - {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR}, // D12/PA6 - {GPIOA_BASE, 5, ADC5, TIMER_INVALID}, // D13/PA5 - {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR}, // D14/PB8 - /* Little header */ - {GPIOC_BASE, 0, ADC10, TIMER_INVALID}, // D15/PC0 - {GPIOC_BASE, 1, ADC11, TIMER_INVALID}, // D16/PC1 - {GPIOC_BASE, 2, ADC12, TIMER_INVALID}, // D17/PC2 - {GPIOC_BASE, 3, ADC13, TIMER_INVALID}, // D18/PC3 - {GPIOC_BASE, 4, ADC14, TIMER_INVALID}, // D19/PC4 - {GPIOC_BASE, 5, ADC15, TIMER_INVALID}, // D20/PC5 - /* External header */ - {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D21/PC13 - {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D22/PC14 - {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D23/PC15 - {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR}, // D24/PB9 - {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID}, // D25/PD2 - {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D26/PC10 - {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR}, // D27/PB0 - {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR}, // D28/PB1 - {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D29/PB10 - {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID}, // D30/PB11 - {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID}, // D31/PB12 - {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D32/PB13 - {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D33/PB14 - {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D34/PB15 - {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID}, // D35/PC6 - {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID}, // D36/PC7 - {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID}, // D37/PC8 - {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID} // D38/PC9 -}; - void pinMode(uint8 pin, WiringPinMode mode) { uint8 outputMode; - if (pin >= NR_MAPLE_PINS) + if (pin >= NR_GPIO_PINS) return; switch(mode) { @@ -130,13 +68,13 @@ void pinMode(uint8 pin, WiringPinMode mode) { uint32 digitalRead(uint8 pin) { - if (pin >= NR_MAPLE_PINS) + if (pin >= NR_GPIO_PINS) return 0; return gpio_read_bit(PIN_MAP[pin].port, PIN_MAP[pin].pin); } void digitalWrite(uint8 pin, uint8 val) { - if (pin >= NR_MAPLE_PINS) + if (pin >= NR_GPIO_PINS) return; gpio_write_bit(PIN_MAP[pin].port, PIN_MAP[pin].pin, val); |