aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple
diff options
context:
space:
mode:
Diffstat (limited to 'libmaple')
-rw-r--r--libmaple/adc.c6
-rw-r--r--libmaple/adc.h37
-rw-r--r--libmaple/dac.c2
-rw-r--r--libmaple/exti.h8
-rw-r--r--libmaple/flash.c8
-rw-r--r--libmaple/fsmc.c2
-rw-r--r--libmaple/gpio.c18
-rw-r--r--libmaple/gpio.h14
-rw-r--r--libmaple/libmaple.h110
-rw-r--r--libmaple/nvic.c34
-rw-r--r--libmaple/nvic.h34
-rw-r--r--libmaple/rcc.c148
-rw-r--r--libmaple/rcc.h221
-rw-r--r--libmaple/ring_buffer.h57
-rw-r--r--libmaple/spi.c4
-rw-r--r--libmaple/spi.h1
-rw-r--r--libmaple/syscalls.c7
-rw-r--r--libmaple/systick.c18
-rw-r--r--libmaple/systick.h25
-rw-r--r--libmaple/timers.c55
-rw-r--r--libmaple/timers.h16
-rw-r--r--libmaple/usart.c316
-rw-r--r--libmaple/usart.h91
-rw-r--r--libmaple/usb/descriptors.h2
-rw-r--r--libmaple/usb/usb_config.h6
-rw-r--r--libmaple/usb/usb_hardware.h1
-rw-r--r--libmaple/util.c11
-rw-r--r--libmaple/util.h11
28 files changed, 704 insertions, 559 deletions
diff --git a/libmaple/adc.c b/libmaple/adc.c
index 317a5ff..021758c 100644
--- a/libmaple/adc.c
+++ b/libmaple/adc.c
@@ -63,9 +63,9 @@
* At 55.5 cycles/sample, the external input impedance < 50kOhms*/
void adc_init(void) {
- rcc_set_adc_prescaler(PCLK2_DIV_2);
- rcc_enable_clk_adc1();
- rcc_reset_adc1();
+ rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6);
+ rcc_clk_enable(RCC_ADC1);
+ rcc_reset_dev(RCC_ADC1);
ADC_CR1 = 0;
ADC_CR2 = CR2_EXTSEL_SWSTART | CR2_EXTTRIG; // Software triggers conversions
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
index b9c7d63..ffc34f8 100644
--- a/libmaple/dac.c
+++ b/libmaple/dac.c
@@ -39,7 +39,7 @@ DAC_Map *dac = (DAC_Map*)(DAC_BASE);
void dac_init(void) {
// First turn on the clock
- rcc_enable_clk_dac();
+ rcc_clk_enable(RCC_DAC);
// Then setup ANALOG mode on PA4 and PA5
gpio_set_mode(GPIOA_BASE, 4, CNF_INPUT_ANALOG);
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/flash.c b/libmaple/flash.c
index 3fd35d6..828f938 100644
--- a/libmaple/flash.c
+++ b/libmaple/flash.c
@@ -22,12 +22,19 @@
* THE SOFTWARE.
* ****************************************************************************/
+/**
+ * @brief flash peripheral management functions
+ */
+
+
#include "libmaple.h"
#include "flash.h"
+/* flash registers */
#define FLASH_BASE 0x40022000
#define FLASH_ACR FLASH_BASE
+/* flash prefetcher */
#define ACR_PRFTBE BIT(4)
#define ACR_PRFTBE_ENABLE BIT(4)
@@ -37,7 +44,6 @@
#define FLASH_WRITE_ACR(val) __write(FLASH_ACR, val)
#define FLASH_READ_ACR() __read(FLASH_ACR)
-
/**
* @brief turn on the hardware prefetcher
*/
diff --git a/libmaple/fsmc.c b/libmaple/fsmc.c
index a8df2e1..502b7b4 100644
--- a/libmaple/fsmc.c
+++ b/libmaple/fsmc.c
@@ -90,7 +90,7 @@ void fsmc_native_sram_init(void) {
gpio_set_mode(GPIOE_BASE, 1, MODE_AF_OUTPUT_PP); // NBL1
// Next enable the clock
- rcc_enable_clk_fsmc();
+ rcc_clk_enable(RCC_FSMC);
// Then we configure channel 1 the FSMC SRAM peripheral
// (all SRAM channels are in "Bank 1" of the FSMC)
diff --git a/libmaple/gpio.c b/libmaple/gpio.c
index a47e623..c5bb450 100644
--- a/libmaple/gpio.c
+++ b/libmaple/gpio.c
@@ -33,14 +33,16 @@
#include "gpio.h"
void gpio_init(void) {
- rcc_enable_clk_gpioa();
- rcc_enable_clk_gpiob();
- rcc_enable_clk_gpioc();
- rcc_enable_clk_gpiod();
- rcc_enable_clk_gpioe();
- rcc_enable_clk_gpiof();
- rcc_enable_clk_gpiog();
- rcc_enable_clk_afio();
+ rcc_clk_enable(RCC_GPIOA);
+ 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);
}
void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, GPIOPinMode mode) {
diff --git a/libmaple/gpio.h b/libmaple/gpio.h
index edbd4f0..9099c9b 100644
--- a/libmaple/gpio.h
+++ b/libmaple/gpio.h
@@ -44,13 +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 GPIOE_BASE (GPIO_Port*)0x40011800
-#define GPIOF_BASE (GPIO_Port*)0x40011C00
-#define GPIOG_BASE (GPIO_Port*)0x40012000
+#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..8e072c3 100644
--- a/libmaple/libmaple.h
+++ b/libmaple/libmaple.h
@@ -32,6 +32,116 @@
#define _LIBMAPLE_H_
#include "libmaple_types.h"
+
+// General configuration
+#define MAPLE_DEBUG 0
+
+// 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
+
+ // Has an FSMC bus?
+ #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
+ #define VCOM_ID_VENDOR 0x1EAF
+ #define VCOM_ID_PRODUCT 0x0004
+ #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 2
+ #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
+
+ // Number of GPIO ports (GPIOA, GPIOB, etc), definately used
+ #define NR_GPIO_PORTS 7
+
+ // Total number of GPIO pins
+ #define NR_GPIO_PINS 63
+
+ // Number of timer devices ports, definately used
+ #define NR_TIMERS 8
+
+ // Has an FSMC bus?
+ #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
+ #define VCOM_ID_VENDOR 0x1EAF
+ #define VCOM_ID_PRODUCT 0x0004
+ #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 GPIOC_BASE
+ #define ERROR_LED_PIN 15
+ #define ERROR_USART_NUM 1
+ #define ERROR_USART_BAUD 9600
+ #define ERROR_TX_PIN 10
+ #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
+
+// 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 d8745a4..7aef26d 100644
--- a/libmaple/nvic.c
+++ b/libmaple/nvic.c
@@ -32,16 +32,6 @@
#include "nvic.h"
#include "systick.h"
-void nvic_disable_interrupts(void) {
- /* Turn off all interrupts */
- REG_SET(NVIC_ICER0, 0xFFFFFFFF);
- REG_SET(NVIC_ICER1, 0xFFFFFFFF);
-
- /* Turn off systick exception */
- REG_CLEAR_BIT(SYSTICK_CSR, 0);
-}
-
-
void nvic_set_vector_table(uint32 addr, uint32 offset) {
__write(SCB_VTOR, (uint32)addr | (offset & 0x1FFFFF80));
}
@@ -49,33 +39,29 @@ void nvic_set_vector_table(uint32 addr, uint32 offset) {
/**
* @brief turn on interrupt number n
- * @param[in] n interrupt number
+ * @param n interrupt number
*/
-void nvic_enable_interrupt(uint32 n) {
- if (n >= NVIC_NR_INTERRUPTS) {
- return;
- }
-
+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);
}
}
/**
* @brief turn off interrupt number n
- * @param[in] n interrupt number
+ * @param n interrupt number
*/
-void nvic_disable_interrupt(uint32 n) {
- if (n >= NVIC_NR_INTERRUPTS) {
- return;
- }
-
+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);
}
}
diff --git a/libmaple/nvic.h b/libmaple/nvic.h
index 8f18e4d..a24086a 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,20 +52,32 @@
#define NVIC_VectTab_RAM ((u32)0x20000000)
#define NVIC_VectTab_FLASH ((u32)0x08000000)
-#define NVIC_NR_INTERRUPTS 60
-
-/* Where to put code */
-#define USER_ADDR_ROM 0x08005000
-#define USER_ADDR_RAM 0x20000C00
-
#ifdef __cplusplus
extern "C"{
#endif
+enum {
+ NVIC_TIMER1 = 27,
+ 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)
+};
+
+
+#define nvic_globalirq_enable() asm volatile("cpsid i")
+#define nvic_globalirq_disable() asm volatile("cpsie i")
+
void nvic_init(void);
-void nvic_disable_interrupts(void);
-void nvic_enable_interrupt(uint32);
-void nvic_disable_interrupt(uint32);
+void nvic_irq_enable(uint32 device);
+void nvic_irq_disable(uint32 device);
#ifdef __cplusplus
}
diff --git a/libmaple/rcc.c b/libmaple/rcc.c
index fbf9160..9bd2663 100644
--- a/libmaple/rcc.c
+++ b/libmaple/rcc.c
@@ -23,66 +23,73 @@
* ****************************************************************************/
/**
- * @file rcc.c
- *
* @brief Implements pretty much only the basic clock setup on the stm32,
- * exposes a handful of clock enable/disable and peripheral reset commands.
+ * clock enable/disable and peripheral reset commands.
*/
#include "libmaple.h"
#include "flash.h"
#include "rcc.h"
-#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)
+enum {
+ APB1,
+ APB2,
+ AHB
+};
-#define RCC_WRITE_CFGR(val) __write(RCC_CFGR, val)
-#define RCC_READ_CFGR() __read(RCC_CFGR)
+struct rcc_dev_info {
+ const uint8 clk_domain;
+ const uint8 line_num;
+};
-#define RCC_WRITE_CR(val) __write(RCC_CR, val)
-#define RCC_READ_CR() __read(RCC_CR)
+/* device descriptor tables */
+static const struct rcc_dev_info rcc_dev_table[] = {
+ [RCC_GPIOA] = { .clk_domain = APB2, .line_num = 2 },
+ [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
+};
/**
- * @brief Initialize the clock control system. Sets up only the basics:
- * APB1 clock prescaler
- * APB2 clock prescaler
- * AHB clock prescaler
- * System clock source (Must be PLL)
- * PLL clock source (Must be high-speed external clock)
- * PLL Multiplier
- * @param dev initialization struct
- * @sideeffect Switches clock source to PLL, clock speed to HSE_CLK*PLLMUL
+ * @brief Initialize the clock control system. Initializes the system
+ * clock source to use the PLL driven by an external oscillator
+ * @param sysclk_src system clock source, must be PLL
+ * @param pll_src pll clock source, must be HSE
+ * @param pll_mul pll multiplier
*/
-void rcc_init(struct rcc_device *dev) {
+void rcc_clk_init(uint32 sysclk_src, uint32 pll_src, uint32 pll_mul) {
/* Assume that we're going to clock the chip off the PLL, fed by
* the HSE */
- ASSERT(dev->sysclk_src == RCC_CLKSRC_PLL &&
- dev->pll_src == RCC_PLLSRC_HSE);
+ ASSERT(sysclk_src == RCC_CLKSRC_PLL &&
+ pll_src == RCC_PLLSRC_HSE);
uint32 cfgr = 0;
uint32 cr = RCC_READ_CR();
- cfgr = (dev->apb1_prescale |
- dev->apb2_prescale |
- dev->ahb_prescale |
- dev->pll_src |
- dev->pll_mul);
+ cfgr = (pll_src | pll_mul);
RCC_WRITE_CFGR(cfgr);
/* Turn on the HSE */
@@ -104,3 +111,60 @@ void rcc_init(struct rcc_device *dev) {
while ((RCC_READ_CFGR() & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
;
}
+
+
+
+/**
+ * @brief Turn on the clock line on a device
+ * @param dev_num device to turn on
+ */
+void rcc_clk_enable(uint32 dev_num) {
+ static const uint32 enable_regs[] = {
+ [APB1] = RCC_APB1ENR,
+ [APB2] = RCC_APB2ENR,
+ [AHB] = RCC_AHBENR,
+ };
+
+ uint8 clk_domain = rcc_dev_table[dev_num].clk_domain;
+
+ __set_bits(enable_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num));
+}
+
+
+/**
+ * @brief Set the divider on a device prescaler
+ * @param prescaler prescaler to set
+ * @param divider prescaler divider
+ */
+void rcc_set_prescaler(uint32 prescaler, uint32 divider) {
+ static const uint32 masks[] = {
+ [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE,
+ [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1,
+ [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2,
+ [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE,
+ [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE,
+ };
+
+ uint32 cfgr = RCC_READ_CFGR();
+
+ cfgr &= ~masks[prescaler];
+ cfgr |= divider;
+ RCC_WRITE_CFGR(cfgr);
+}
+
+
+/**
+ * @brief reset a device
+ * @param dev_num device to reset
+ */
+void rcc_reset_dev(uint32 dev_num) {
+ static const uint32 reset_regs[] = {
+ [APB1] = RCC_APB1RSTR,
+ [APB2] = RCC_APB2RSTR,
+ };
+
+ uint8 clk_domain = rcc_dev_table[dev_num].clk_domain;
+
+ __set_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num));
+ __clear_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num));
+}
diff --git a/libmaple/rcc.h b/libmaple/rcc.h
index 2dca151..3651945 100644
--- a/libmaple/rcc.h
+++ b/libmaple/rcc.h
@@ -23,42 +23,84 @@
* ****************************************************************************/
/**
- * @file rcc.h
- *
- * @brief
+ * @brief reset and clock control definitions and prototypes
*/
#ifndef _RCC_H_
#define _RCC_H_
-struct rcc_device {
- uint32 apb1_prescale;
- uint32 apb2_prescale;
- uint32 ahb_prescale;
- uint32 sysclk_src;
- uint32 pll_src;
- uint32 pll_mul;
-};
+/* 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)
#define RCC_CLKSRC_PLL (0x2)
-#define RCC_PLLSRC_HSI_DIV_2 (0x0 << 16)
-#define RCC_PLLSRC_HSE (0x1 << 16)
+/* pll entry clock source */
+#define RCC_PLLSRC_HSE (0x1 << 16)
+#define RCC_PLLSRC_HSI_DIV_2 (0x0 << 16)
+/* adc prescaler dividers */
+#define RCC_ADCPRE_PCLK_DIV_2 (0x0 << 14)
+#define RCC_ADCPRE_PCLK_DIV_4 (0x1 << 14)
+#define RCC_ADCPRE_PCLK_DIV_6 (0x2 << 14)
+#define RCC_ADCPRE_PCLK_DIV_8 (0x3 << 14)
+
+/* apb1 prescaler dividers */
#define RCC_APB1_HCLK_DIV_1 (0x0 << 8)
#define RCC_APB1_HCLK_DIV_2 (0x4 << 8)
#define RCC_APB1_HCLK_DIV_4 (0x5 << 8)
#define RCC_APB1_HCLK_DIV_8 (0x6 << 8)
#define RCC_APB1_HCLK_DIV_16 (0x7 << 8)
+/* apb2 prescaler dividers */
#define RCC_APB2_HCLK_DIV_1 (0x0 << 11)
#define RCC_APB2_HCLK_DIV_2 (0x4 << 11)
#define RCC_APB2_HCLK_DIV_4 (0x5 << 11)
#define RCC_APB2_HCLK_DIV_8 (0x6 << 11)
#define RCC_APB2_HCLK_DIV_16 (0x7 << 11)
+/* ahb prescaler dividers */
#define RCC_AHB_SYSCLK_DIV_1 (0x0 << 4)
#define RCC_AHB_SYSCLK_DIV_2 (0x8 << 4)
#define RCC_AHB_SYSCLK_DIV_4 (0x9 << 4)
@@ -70,6 +112,7 @@ struct rcc_device {
#define RCC_AHB_SYSCLK_DIV_256 (0xE << 4)
#define RCC_AHB_SYSCLK_DIV_512 (0xF << 4)
+/* pll multipliers */
#define RCC_PLLMUL_2 (0x0 << 18)
#define RCC_PLLMUL_3 (0x1 << 18)
#define RCC_PLLMUL_4 (0x2 << 18)
@@ -86,118 +129,52 @@ struct rcc_device {
#define RCC_PLLMUL_15 (0xD << 18)
#define RCC_PLLMUL_16 (0xE << 18)
-/* remove!! */
-#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)
-/* APB2 reset bits */
-#define RCC_APB2RSTR_USART1RST BIT(14)
-#define RCC_APB2RSTR_SPI1RST BIT(12)
-#define RCC_APB2RSTR_TIM1RST BIT(11)
-#define RCC_APB2RSTR_ADC2RST BIT(10)
-#define RCC_APB2RSTR_ADC1RST BIT(9)
-#define RCC_APB2RSTR_IOERST BIT(6)
-#define RCC_APB2RSTR_IODRST BIT(5)
-#define RCC_APB2RSTR_IOCRST BIT(4)
-#define RCC_APB2RSTR_IOBRST BIT(3)
-#define RCC_APB2RSTR_IOARST BIT(2)
-#define RCC_APB2RSTR_AFIORST BIT(0)
-
-#define RCC_APB1RSTR_USB BIT(23)
-
-/* APB2 peripheral clock enable bits */
-#define RCC_APB2ENR_USART1EN BIT(14)
-#define RCC_APB2ENR_SPI1EN BIT(12)
-#define RCC_APB2ENR_TIM1EN BIT(11)
-#define RCC_APB2ENR_ADC2EN BIT(10)
-#define RCC_APB2ENR_ADC1EN BIT(9)
-#define RCC_APB2ENR_IOPGEN BIT(8)
-#define RCC_APB2ENR_IOPFEN BIT(7)
-#define RCC_APB2ENR_IOPEEN BIT(6)
-#define RCC_APB2ENR_IOPDEN BIT(5)
-#define RCC_APB2ENR_IOPCEN BIT(4)
-#define RCC_APB2ENR_IOPBEN BIT(3)
-#define RCC_APB2ENR_IOPAEN BIT(2)
-#define RCC_APB2ENR_AFIOEN BIT(0)
-
-/* APB1 peripheral clock enable bits */
-#define RCC_APB1ENR_TIM2EN BIT(0)
-#define RCC_APB1ENR_TIM3EN BIT(1)
-#define RCC_APB1ENR_TIM4EN BIT(2)
-#define RCC_APB1ENR_USART2EN BIT(17)
-#define RCC_APB1ENR_USART3EN BIT(18)
-#define RCC_APB1ENR_SPI2EN BIT(14)
-#define RCC_APB1ENR_USB BIT(23)
-#define RCC_APB1ENR_DACEN BIT(29)
-
-/* AHB peripheral clock enable bits */
-#define RCC_AHBENR_DMA1EN BIT(0)
-#define RCC_AHBENR_DMA2EN BIT(1)
-#define RCC_AHBENR_SRAMEN BIT(2)
-#define RCC_AHBENR_FLITFEN BIT(4)
-#define RCC_AHBENR_CRCEN BIT(6)
-#define RCC_AHBENR_FSMCEN BIT(8)
-#define RCC_AHBENR_SDIOEN BIT(10)
-
-#define rcc_enable_clk_fsmc() __set_bits(RCC_AHBENR, RCC_AHBENR_FSMCEN)
-
-#define rcc_enable_clk_spi1() __set_bits(RCC_APB2ENR, RCC_APB2ENR_SPI1EN)
-#define rcc_enable_clk_spi2() __set_bits(RCC_APB1ENR, RCC_APB1ENR_SPI2EN)
-
-#define rcc_enable_clk_timer1() __set_bits(RCC_APB2ENR, RCC_APB2ENR_TIM1EN)
-#define rcc_enable_clk_timer2() __set_bits(RCC_APB1ENR, RCC_APB1ENR_TIM2EN)
-#define rcc_enable_clk_timer3() __set_bits(RCC_APB1ENR, RCC_APB1ENR_TIM3EN)
-#define rcc_enable_clk_timer4() __set_bits(RCC_APB1ENR, RCC_APB1ENR_TIM4EN)
-
-#define rcc_enable_clk_gpioa() __set_bits(RCC_APB2ENR, RCC_APB2ENR_IOPAEN)
-#define rcc_enable_clk_gpiob() __set_bits(RCC_APB2ENR, RCC_APB2ENR_IOPBEN)
-#define rcc_enable_clk_gpioc() __set_bits(RCC_APB2ENR, RCC_APB2ENR_IOPCEN)
-#define rcc_enable_clk_gpiod() __set_bits(RCC_APB2ENR, RCC_APB2ENR_IOPDEN)
-#define rcc_enable_clk_gpioe() __set_bits(RCC_APB2ENR, RCC_APB2ENR_IOPEEN)
-#define rcc_enable_clk_gpiof() __set_bits(RCC_APB2ENR, RCC_APB2ENR_IOPFEN)
-#define rcc_enable_clk_gpiog() __set_bits(RCC_APB2ENR, RCC_APB2ENR_IOPGEN)
-#define rcc_enable_clk_afio() __set_bits(RCC_APB2ENR, RCC_APB2ENR_AFIOEN)
-
-#define rcc_enable_clk_usart1() __set_bits(RCC_APB2ENR, RCC_APB2ENR_USART1EN)
-#define rcc_enable_clk_usart2() __set_bits(RCC_APB1ENR, RCC_APB1ENR_USART2EN)
-#define rcc_enable_clk_usart3() __set_bits(RCC_APB1ENR, RCC_APB1ENR_USART3EN)
-
-#define rcc_enable_clk_adc1() __set_bits(RCC_APB2ENR, RCC_APB2ENR_ADC1EN)
-
-#define rcc_enable_clk_dac() __set_bits(RCC_APB1ENR, RCC_APB1ENR_DACEN)
-
-#define rcc_reset_adc1() { __set_bits(RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); \
- __clear_bits(RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); \
- }
-
-#define rcc_reset_usb() { __set_bits(RCC_APB1RSTR, RCC_APB1RSTR_USB); \
- __clear_bits(RCC_APB1RSTR, RCC_APB1RSTR_USB); \
- }
-
-
-#define PCLK2_DIV_2 0x00008000
-
-#ifdef __cplusplus
-extern "C"{
-#endif
+/* prescalers */
+enum {
+ RCC_PRESCALER_AHB,
+ RCC_PRESCALER_APB1,
+ RCC_PRESCALER_APB2,
+ RCC_PRESCALER_USB,
+ RCC_PRESCALER_ADC
+};
-void rcc_init(struct rcc_device *dev);
+// 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, // 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,
+ RCC_FSMC, // High-density devices only (Maple Native)
+ RCC_DAC, // High-density devices only (Maple Native)
+};
-#ifdef __cplusplus
-}
-#endif
-#endif
+void rcc_clk_init(uint32 sysclk_src, uint32 pll_src, uint32 pll_mul);
+void rcc_clk_enable(uint32 dev);
+void rcc_reset_dev(uint32 dev);
+void rcc_set_prescaler(uint32 prescaler, uint32 divider);
+#endif
diff --git a/libmaple/ring_buffer.h b/libmaple/ring_buffer.h
new file mode 100644
index 0000000..95b9dd8
--- /dev/null
+++ b/libmaple/ring_buffer.h
@@ -0,0 +1,57 @@
+/**
+ * @brief simple circular buffer
+ */
+
+#ifndef _RING_BUFFER_H_
+#define _RING_BUFFER_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+/* The buffer is empty when head == tail.
+ * The buffer is full when the head is one byte in front of the tail
+ * The total buffer size must be a power of two
+ * One byte is left free to distinguish empty from full */
+typedef struct ring_buffer {
+ uint32 head;
+ uint32 tail;
+ uint8 size;
+ uint8 *buf;
+} ring_buffer;
+
+static inline void rb_init(ring_buffer *rb, uint8 size, uint8 *buf) {
+ ASSERT(IS_POWER_OF_TWO(size));
+ rb->head = 0;
+ rb->tail = 0;
+ rb->size = size;
+ rb->buf = buf;
+}
+
+static inline void rb_insert(ring_buffer *rb, uint8 element) {
+ rb->buf[(rb->tail)++] = element;
+ rb->tail &= (rb->size - 1);
+}
+
+static inline uint8 rb_remove(ring_buffer *rb) {
+ uint8 ch = rb->buf[rb->head++];
+ rb->head &= (rb->size - 1);
+ return ch;
+}
+
+static inline uint32 rb_full_count(ring_buffer *rb) {
+ return rb->tail - rb->head;
+}
+
+static inline void rb_reset(ring_buffer *rb) {
+ rb->tail = rb->head;
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+
+#endif
+
diff --git a/libmaple/spi.c b/libmaple/spi.c
index aa75c5f..68855a5 100644
--- a/libmaple/spi.c
+++ b/libmaple/spi.c
@@ -89,12 +89,12 @@ void spi_init(uint32 spi_num,
/* limit to 18 mhz max speed */
ASSERT(prescale != CR1_BR_PRESCALE_2);
spi = (SPI*)SPI1_BASE;
- rcc_enable_clk_spi1();
+ rcc_clk_enable(RCC_SPI1);
spi_gpio_cfg(&spi_dev1);
break;
case 2:
spi = (SPI*)SPI2_BASE;
- rcc_enable_clk_spi2();
+ rcc_clk_enable(RCC_SPI2);
spi_gpio_cfg(&spi_dev2);
break;
}
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/systick.c b/libmaple/systick.c
index a333528..8b0d92a 100644
--- a/libmaple/systick.c
+++ b/libmaple/systick.c
@@ -31,23 +31,25 @@
#include "libmaple.h"
#include "systick.h"
-#define MILLIS_INC 1
+#define SYSTICK_RELOAD 0xE000E014 // Reload value register
+#define SYSTICK_CNT 0xE000E018 // Current value register
+#define SYSTICK_CALIB 0xE000E01C // Calibration value register
+
+#define SYSTICK_SRC_HCLK BIT(2) // Use core clock
+#define SYSTICK_TICKINT BIT(1) // Interrupt on systick countdown
+#define SYSTICK_ENABLE BIT(0) // Turn on the counter
volatile uint32 systick_timer_millis = 0;
-void systick_init(void) {
+void systick_init(uint32 reload_val) {
/* Set the reload counter to tick every 1ms */
- REG_SET_MASK(SYSTICK_RELOAD, MAPLE_RELOAD_VAL);
-// SYSTICK_RELOAD = MAPLE_RELOAD_VAL;
+ __write(SYSTICK_RELOAD, reload_val);
/* Clock the system timer with the core clock
* and turn it on, interrrupt every 1ms to keep track of millis()*/
- REG_SET(SYSTICK_CSR, SYSTICK_SRC_HCLK |
+ __write(SYSTICK_CSR, SYSTICK_SRC_HCLK |
SYSTICK_ENABLE |
SYSTICK_TICKINT);
-// SYSTICK_CSR = SYSTICK_SRC_HCLK |
-// SYSTICK_ENABLE |
-// SYSTICK_TICKINT;
}
void SysTickHandler(void) {
diff --git a/libmaple/systick.h b/libmaple/systick.h
index d0a623f..57b724a 100644
--- a/libmaple/systick.h
+++ b/libmaple/systick.h
@@ -33,30 +33,23 @@
#include "libmaple.h"
-/* To the ARM technical manual... there's nearly nothing on the systick
- * timer in the stm32 manual */
+#define SYSTICK_CSR 0xE000E010 // Control and status register
+#define SYSTICK_CNT 0xE000E018 // Current value register
-#define SYSTICK_CSR 0xE000E010 // Control and status register
-#define SYSTICK_RELOAD 0xE000E014 // Reload value register
-#define SYSTICK_CNT 0xE000E018 // Current value register
-#define SYSTICK_CALIB 0xE000E01C // Calibration value register
-
-#define SYSTICK_SRC_HCLK BIT(2) // Use core clock
-#define SYSTICK_TICKINT BIT(1) // Interrupt on systick countdown
-#define SYSTICK_ENABLE BIT(0) // Turn on the counter
-
-/* We use the systick timer to tick once
- * every millisecond */
-#define MAPLE_RELOAD_VAL 72000
+#define SYSTICK_CSR_COUNTFLAG BIT(16)
#ifdef __cplusplus
extern "C"{
#endif
-void systick_init(void);
+void systick_init(uint32 reload_val);
static inline uint32 systick_get_count(void) {
- return (uint32)*(volatile uint32*)SYSTICK_CNT;
+ return __read(SYSTICK_CNT);
+}
+
+static inline uint32 systick_check_underflow(void) {
+ return (__read(SYSTICK_CSR) & SYSTICK_CSR_COUNTFLAG);
}
#ifdef __cplusplus
diff --git a/libmaple/timers.c b/libmaple/timers.c
index da85680..6fa2848 100644
--- a/libmaple/timers.c
+++ b/libmaple/timers.c
@@ -28,8 +28,11 @@
* @brief General timer routines
*/
+// TODO: actually support timer5 and timer8
+
#include "libmaple.h"
#include "rcc.h"
+#include "nvic.h"
#include "timers.h"
typedef struct {
@@ -81,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
@@ -94,21 +101,35 @@ void timer_init(uint8 timer_num, uint16 prescale) {
switch(timer_num) {
case 1:
timer = (Timer*)TIMER1_BASE;
- rcc_enable_clk_timer1();
+ rcc_clk_enable(RCC_TIMER1);
is_advanced = 1;
break;
case 2:
timer = (Timer*)TIMER2_BASE;
- rcc_enable_clk_timer2();
+ rcc_clk_enable(RCC_TIMER2);
break;
case 3:
timer = (Timer*)TIMER3_BASE;
- rcc_enable_clk_timer3();
+ rcc_clk_enable(RCC_TIMER3);
break;
case 4:
timer = (Timer*)TIMER4_BASE;
- rcc_enable_clk_timer4();
+ 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
@@ -171,6 +192,9 @@ void timer_pause(uint8 timer_num) {
case 4:
timer = (Timer*)TIMER4_BASE;
break;
+ default:
+ ASSERT(0);
+ return;
}
timer->CR1 &= ~(0x0001); // CEN
}
@@ -193,6 +217,9 @@ void timer_resume(uint8 timer_num) {
case 4:
timer = (Timer*)TIMER4_BASE;
break;
+ default:
+ ASSERT(0);
+ return;
}
timer->CR1 |= 0x0001; // CEN
}
@@ -217,6 +244,9 @@ ASSERT(timer_num > 0 && timer_num <= 4);
case 4:
timer = (Timer*)TIMER4_BASE;
break;
+ default:
+ ASSERT(0);
+ return;
}
timer->CNT = value;
}
@@ -240,6 +270,9 @@ uint16 timer_get_count(uint8 timer_num) {
case 4:
timer = (Timer*)TIMER4_BASE;
break;
+ default:
+ ASSERT(0);
+ return;
}
return timer->CNT;
}
@@ -262,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;
}
@@ -285,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;
}
@@ -476,25 +515,25 @@ void timer_attach_interrupt(uint8 timer_num, uint8 compare_num, voidFuncPtr hand
case 1:
timer = (Timer*)TIMER1_BASE;
timer1_handlers[compare_num-1] = handler;
- nvic_enable_interrupt(27);
+ nvic_irq_enable(NVIC_TIMER1);
timer->DIER |= (1 << compare_num); // 1-indexed compare nums
break;
case 2:
timer = (Timer*)TIMER2_BASE;
timer2_handlers[compare_num-1] = handler;
- nvic_enable_interrupt(28);
+ nvic_irq_enable(NVIC_TIMER2);
timer->DIER |= (1 << compare_num); // 1-indexed compare nums
break;
case 3:
timer = (Timer*)TIMER3_BASE;
timer3_handlers[compare_num-1] = handler;
- nvic_enable_interrupt(29);
+ nvic_irq_enable(NVIC_TIMER3);
timer->DIER |= (1 << compare_num); // 1-indexed compare nums
break;
case 4:
timer = (Timer*)TIMER4_BASE;
timer4_handlers[compare_num-1] = handler;
- nvic_enable_interrupt(30);
+ nvic_irq_enable(NVIC_TIMER4);
timer->DIER |= (1 << compare_num); // 1-indexed compare nums
break;
}
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 282fc5d..d08d3cf 100644
--- a/libmaple/usart.c
+++ b/libmaple/usart.c
@@ -36,123 +36,95 @@
#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_TXE BIT(7)
#define USART_TC BIT(6)
-#define USART_STOP_BITS_1 BIT_MASK_SHIFT(0b0, 12)
-#define USART_STOP_BITS_05 BIT_MASK_SHIFT(0b01, 12)
-#define USART_STOP_BITS_2 BIT_MASK_SHIFT(0b02, 12)
-#define USART_STOP_BITS_15 BIT_MASK_SHIFT(0b02, 12)
-
-#define USART1_CLK 72000000UL
-#define USART2_CLK 36000000UL
-#define USART3_CLK 36000000UL
-
-#define USART_RECV_BUF_SIZE 64
-
-/* Ring buffer notes:
- * The buffer is empty when head == tail.
- * The buffer is full when the head is one byte in front of the tail
- * The total buffer size must be a power of two
- * Note, one byte is necessarily left free with this scheme */
-typedef struct usart_ring_buf {
- uint32 head;
- uint32 tail;
- uint8 buf[USART_RECV_BUF_SIZE];
-} usart_ring_buf;
-
-static usart_ring_buf ring_buf1;
-static usart_ring_buf ring_buf2;
-static usart_ring_buf ring_buf3;
-
-typedef struct usart_port {
- volatile uint32 SR; // Status register
- volatile uint32 DR; // Data register
- volatile uint32 BRR; // Baud rate register
- volatile uint32 CR1; // Control register 1
- volatile uint32 CR2; // Control register 2
- volatile uint32 CR3; // Control register 3
- volatile uint32 GTPR; // Guard time and prescaler register
-} usart_port;
-
+/* usart descriptor table */
+struct usart_dev usart_dev_table[] = {
+ [USART1] = {
+ .base = (usart_port*)USART1_BASE,
+ .rcc_dev_num = RCC_USART1,
+ .nvic_dev_num = NVIC_USART1
+ },
+ [USART2] = {
+ .base = (usart_port*)USART2_BASE,
+ .rcc_dev_num = RCC_USART2,
+ .nvic_dev_num = NVIC_USART2
+ },
+ [USART3] = {
+ .base = (usart_port*)USART3_BASE,
+ .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 */
void USART1_IRQHandler(void) {
- /* Read the data */
- ring_buf1.buf[ring_buf1.tail++] = (uint8)(((usart_port*)(USART1_BASE))->DR);
- ring_buf1.tail %= USART_RECV_BUF_SIZE;
+ rb_insert(&(usart_dev_table[USART1].rb), (uint8)(((usart_port*)(USART1_BASE))->DR));
}
-/* Don't overrun your buffer, seriously */
void USART2_IRQHandler(void) {
- /* Read the data */
- ring_buf2.buf[ring_buf2.tail++] = (uint8)(((usart_port*)(USART2_BASE))->DR);
- ring_buf2.tail %= USART_RECV_BUF_SIZE;
+ rb_insert(&(usart_dev_table[USART2].rb), (uint8)(((usart_port*)(USART2_BASE))->DR));
}
-/* Don't overrun your buffer, seriously */
+
void USART3_IRQHandler(void) {
- /* Read the data */
- ring_buf3.buf[ring_buf3.tail++] = (uint8)(((usart_port*)(USART3_BASE))->DR);
- ring_buf3.tail %= USART_RECV_BUF_SIZE;
+ 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
- * receiver mode.
- *
+ * receiver mode.
* @param usart_num USART to be initialized
* @param baud Baud rate to be set at
- * @param recvBuf buf buffer for receiver
- * @param len size of recvBuf
- *
- * @sideeffect Turns on the specified USART
*/
void usart_init(uint8 usart_num, uint32 baud) {
- ASSERT((usart_num <= NR_USARTS) && (usart_num > 0));
- ASSERT(baud && (baud < USART_MAX_BAUD));
-
+ ASSERT(usart_num <= NR_USART);
usart_port *port;
- usart_ring_buf *ring_buf;
+ ring_buffer *ring_buf;
uint32 clk_speed;
uint32 integer_part;
uint32 fractional_part;
uint32 tmp;
- switch (usart_num) {
- case 1:
- port = (usart_port*)USART1_BASE;
- ring_buf = &ring_buf1;
- clk_speed = USART1_CLK;
- rcc_enable_clk_usart1();
- REG_SET(NVIC_ISER1, BIT(5));
- break;
- case 2:
- port = (usart_port*)USART2_BASE;
- ring_buf = &ring_buf2;
- clk_speed = USART2_CLK;
- rcc_enable_clk_usart2();
- REG_SET(NVIC_ISER1, BIT(6));
- break;
- case 3:
- port = (usart_port*)USART3_BASE;
- ring_buf = &ring_buf3;
- clk_speed = USART3_CLK;
- rcc_enable_clk_usart3();
- REG_SET(NVIC_ISER1, BIT(7));
- break;
- default:
- /* should never get here */
- ASSERT(0);
- }
+ port = usart_dev_table[usart_num].base;
+ rcc_clk_enable(usart_dev_table[usart_num].rcc_dev_num);
+ nvic_irq_enable(usart_dev_table[usart_num].nvic_dev_num);
+
+ /* usart1 is mad fast */
+ clk_speed = (usart_num == USART1) ? 72000000UL : 36000000UL;
- /* Initialize ring buffer */
- ring_buf->head = 0;
- ring_buf->tail = 0;
+ /* Initialize rx ring buffer */
+ rb_init(&usart_dev_table[usart_num].rb,
+ sizeof (usart_dev_table[usart_num].rx_buf),
+ usart_dev_table[usart_num].rx_buf);
/* Set baud rate */
integer_part = ((25 * clk_speed) / (4 * baud));
@@ -172,36 +144,25 @@ void usart_init(uint8 usart_num, uint32 baud) {
port->CR1 |= USART_UE;
}
+/**
+ * @brief Turn off all USARTs.
+ */
+void usart_disable_all() {
+ usart_disable(1);
+ usart_disable(2);
+ usart_disable(3);
+ #if NR_USART >= 5
+ usart_disable(4);
+ usart_disable(5);
+ #endif
+}
/**
* @brief Turn off a USART.
- *
* @param USART to be disabled
- *
- * @sideeffect Turns off the specified USART
*/
void usart_disable(uint8 usart_num) {
- ASSERT((usart_num <= NR_USARTS) && (usart_num > 0));
- usart_port *port;
-
- switch (usart_num) {
- case 1:
- port = (usart_port*)USART1_BASE;
- break;
- case 2:
- port = (usart_port*)USART2_BASE;
- break;
- case 3:
- port = (usart_port*)USART3_BASE;
- break;
- default:
- /* should never get here */
- ASSERT(0);
- }
-
- /* Is this usart enabled? */
- if (!(port->SR & USART_UE))
- return;
+ usart_port *port = usart_dev_table[usart_num].base;
/* TC bit must be high before disabling the usart */
while ((port->SR & USART_TC) == 0)
@@ -211,18 +172,17 @@ void usart_disable(uint8 usart_num) {
port->CR1 = 0;
/* Clean up buffer */
- usart_clear_buffer(usart_num);
+ usart_reset_rx(usart_num);
}
/**
* @brief Print a null terminated string to the specified USART
*
- * @param[in] usart_num USART to send on
- * @param[in] str String to send
+ * @param usart_num usart to send on
+ * @param str string to send
*/
void usart_putstr(uint8 usart_num, const char* str) {
- ASSERT((usart_num <= NR_USARTS) && (usart_num > 0));
char ch;
while((ch = *(str++)) != '\0') {
@@ -233,11 +193,10 @@ void usart_putstr(uint8 usart_num, const char* str) {
/**
* @brief Print an unsigned integer to the specified usart
*
- * @param[in] usart_num usart to send on
- * @param[in] val number to print
+ * @param usart_num usart to send on
+ * @param val number to print
*/
void usart_putudec(uint8 usart_num, uint32 val) {
- ASSERT((usart_num <= NR_USARTS) && (usart_num > 0));
char digits[12];
int i;
@@ -249,125 +208,4 @@ void usart_putudec(uint8 usart_num, uint32 val) {
while (--i >= 0) {
usart_putc(usart_num, digits[i]);
}
-
-}
-
-
-/**
- * @brief Return one character from the receive buffer. Assumes
- * that there is data available.
- *
- * @param[in] usart_num number of the usart to read from
- *
- * @return character from ring buffer
- *
- * @sideeffect may update the head pointer of the recv buffer
- */
-uint8 usart_getc(uint8 usart_num) {
- uint8 ch;
- usart_ring_buf *rb;
-
- switch (usart_num) {
- case 1:
- rb = &ring_buf1;
- break;
- case 2:
- rb = &ring_buf2;
- break;
- case 3:
- rb = &ring_buf3;
- break;
- default:
- ASSERT(0);
- }
-
- /* Make sure there's actually data to be read */
- ASSERT(rb->head != rb->tail);
-
- /* Read the data and check for wraparound */
- ch = rb->buf[rb->head++];
- rb->head %= USART_RECV_BUF_SIZE;
-
- return ch;
-}
-
-uint32 usart_data_available(uint8 usart_num) {
- usart_ring_buf *rb;
-
- switch (usart_num) {
- case 1:
- rb = &ring_buf1;
- break;
- case 2:
- rb = &ring_buf2;
- break;
- case 3:
- rb = &ring_buf3;
- break;
- default:
- ASSERT(0);
- }
-
- return rb->tail - rb->head;
-}
-
-void usart_clear_buffer(uint8 usart_num) {
- usart_ring_buf *rb;
-
- switch (usart_num) {
- case 1:
- rb = &ring_buf1;
- break;
- case 2:
- rb = &ring_buf2;
- break;
- case 3:
- rb = &ring_buf3;
- break;
- default:
- ASSERT(0);
- }
-
- rb->tail = rb->head;
-}
-
-
-
-/**
- * @brief Output a byte out the uart
- *
- * @param[in] usart_num usart number to output on
- * @param[in] byte byte to send
- *
- */
-void usart_putc(uint8 usart_num, uint8 byte) {
- ASSERT((usart_num <= NR_USARTS) && (usart_num > 0));
- usart_port *port;
-
- switch (usart_num) {
- case 1:
- port = (usart_port*)USART1_BASE;
- break;
- case 2:
- port = (usart_port*)USART2_BASE;
- break;
- case 3:
- port = (usart_port*)USART3_BASE;
- break;
- default:
- /* Should never get here */
- ASSERT(0);
- }
-
-// if (ch == '\n') {
-// usart_putc(usart_num, '\r');
-// }
-
- port->DR = byte;
-
- /* Wait for transmission to complete */
- while ((port->SR & USART_TXE) == 0)
- ;
}
-
-
diff --git a/libmaple/usart.h b/libmaple/usart.h
index 02fb6e0..2bc472f 100644
--- a/libmaple/usart.h
+++ b/libmaple/usart.h
@@ -23,32 +23,101 @@
* ****************************************************************************/
/**
- * @file usart.h
- *
- * @brief USART Definitions
+ * @brief USART definitions and prototypes
*/
#ifndef _USART_H_
#define _USART_H_
-#define NR_USARTS 0x3
+#include "ring_buffer.h"
#ifdef __cplusplus
extern "C"{
#endif
-#define USART_MAX_BAUD 225000
+#define USART_TXE BIT(7)
+
+/* usart device numbers */
+enum {
+ USART1,
+ USART2,
+ USART3,
+ UART4,
+ UART5,
+};
+
+/* peripheral register struct */
+typedef struct usart_port {
+ volatile uint32 SR; // Status register
+ volatile uint32 DR; // Data register
+ volatile uint32 BRR; // Baud rate register
+ volatile uint32 CR1; // Control register 1
+ volatile uint32 CR2; // Control register 2
+ volatile uint32 CR3; // Control register 3
+ volatile uint32 GTPR; // Guard time and prescaler register
+} usart_port;
+
+/* usart descriptor */
+struct usart_dev {
+ usart_port *base;
+ ring_buffer rb;
+ uint8 rx_buf[64];
+ const uint8 rcc_dev_num;
+ const uint8 nvic_dev_num;
+};
+
+extern struct usart_dev usart_dev_table[];
+
+
+/**
+ * @brief send one character on a usart
+ * @param usart_num usart to send on
+ * @param byte byte to send
+ */
+static inline void usart_putc(uint8 usart_num, uint8 byte) {
+ usart_port *port = usart_dev_table[usart_num].base;
+
+ port->DR = byte;
+
+ /* Wait for transmission to complete */
+ while ((port->SR & USART_TXE) == 0)
+ ;
+}
+
+
+/**
+ * @brief read one character from a usart
+ * @param usart_num usart to read from
+ * @return byte read
+ */
+static inline uint8 usart_getc(uint8 usart_num) {
+ return rb_remove(&usart_dev_table[usart_num].rb);
+}
+
+
+/**
+ * @brief return the amount of data available in the rx buffer
+ * @param usart_num which usart to check
+ * @return number of bytes in the rx buffer
+ */
+static inline uint32 usart_data_available(uint8 usart_num) {
+ return rb_full_count(&usart_dev_table[usart_num].rb);
+}
+
+
+/**
+ * @brief removes the contents of the rx fifo
+ * @param usart_num which usart to reset
+ */
+static inline void usart_reset_rx(uint8 usart_num) {
+ rb_reset(&usart_dev_table[usart_num].rb);
+}
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);
-void usart_putc(uint8 usart_num, uint8 ch);
-
-uint32 usart_data_available(uint8 usart_num);
-uint8 usart_getc(uint8 usart_num);
-void usart_clear_buffer(uint8 usart_num);
#ifdef __cplusplus
} // extern "C"
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_config.h b/libmaple/usb/usb_config.h
index 9f6b600..27294dc 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
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 8c25257..61beab8 100644
--- a/libmaple/util.c
+++ b/libmaple/util.c
@@ -36,13 +36,6 @@
#include "adc.h"
#include "timers.h"
-#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 10
-#define ERROR_TX_PORT GPIOA_BASE
-
/* Error assert + fade */
void _fail(const char* file, int line, const char* exp) {
int32 slope = 1;
@@ -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);
diff --git a/libmaple/util.h b/libmaple/util.h
index 1aae7bd..053731a 100644
--- a/libmaple/util.h
+++ b/libmaple/util.h
@@ -32,8 +32,6 @@
#ifndef _UTIL_H_
#define _UTIL_H_
-#define MAPLE_DEBUG 1
-
#define BIT(shift) (1 << (shift))
#define BIT_MASK_SHIFT(mask, shift) ((mask) << (shift))
@@ -41,16 +39,9 @@
#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 COUNTFLAG *((volatile unsigned char*) (BITBAND_PERI(SYSTICK_CSR,2)))
-
#define REG_SET(reg, val) (*(volatile uint32*)(reg) = (val))
#define REG_SET_BIT(reg, bit) (*(volatile uint32*)(reg) |= BIT(bit))
#define REG_CLEAR_BIT(reg, bit) (*(volatile uint32*)(reg) &= ~BIT(bit))
@@ -66,6 +57,8 @@
#define __read(reg) *(volatile uint32*)(reg)
#define __write(reg, value) *(volatile uint32*)(reg) = (value)
+#define IS_POWER_OF_TWO(v) (v && !(v & (v - 1)))
+
#ifdef __cplusplus
extern "C"{
#endif