aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--src/lib/adc.c29
-rw-r--r--src/lib/adc.h26
-rw-r--r--src/lib/exti.c47
-rw-r--r--src/lib/exti.h51
-rw-r--r--src/lib/gpio.c48
-rw-r--r--src/lib/gpio.h71
-rw-r--r--src/lib/libmaple.h33
-rw-r--r--src/lib/libmaple_types.h42
-rw-r--r--src/lib/nvic.c41
-rw-r--r--src/lib/nvic.h62
-rw-r--r--src/lib/syscalls.c13
-rw-r--r--src/lib/systick.c50
-rw-r--r--src/lib/systick.h37
-rw-r--r--src/lib/timers.c44
-rw-r--r--src/lib/timers.h26
-rw-r--r--src/lib/usart.c322
-rw-r--r--src/lib/usart.h73
-rw-r--r--src/lib/util.c99
-rw-r--r--src/lib/util.cpp47
-rw-r--r--src/lib/util.h25
-rw-r--r--src/main.cpp49
-rw-r--r--src/stm32lib/inc/stm32f10x_map.h20
-rw-r--r--src/wiring/Print.cpp26
-rw-r--r--src/wiring/comm/HardwareSerial.cpp92
-rw-r--r--src/wiring/comm/HardwareSerial.h48
-rw-r--r--src/wiring/comm/Serial.cpp67
-rw-r--r--src/wiring/comm/Serial.h20
-rw-r--r--src/wiring/ext_interrupts.c49
-rw-r--r--src/wiring/ext_interrupts.h39
-rw-r--r--src/wiring/io.h56
-rw-r--r--src/wiring/math.h4
-rw-r--r--src/wiring/pwm.c25
-rw-r--r--src/wiring/pwm.h27
-rw-r--r--src/wiring/time.c26
-rw-r--r--src/wiring/time.h27
-rw-r--r--src/wiring/wiring.c30
-rw-r--r--src/wiring/wiring.h12
-rw-r--r--src/wiring/wiring_analog.c30
-rw-r--r--src/wiring/wiring_digital.c112
-rw-r--r--src/wiring/wiring_shift.c2
41 files changed, 1553 insertions, 401 deletions
diff --git a/Makefile b/Makefile
index 8da91d2..f84d6c8 100644
--- a/Makefile
+++ b/Makefile
@@ -64,7 +64,9 @@ CSRC = lib/systick.c \
lib/stm32f10x_it.c \
lib/exti.c \
lib/gpio.c \
+ lib/nvic.c \
lib/usart.c \
+ lib/util.c \
lib/usb.c \
wiring/wiring.c \
wiring/wiring_shift.c \
@@ -76,10 +78,9 @@ CSRC = lib/systick.c \
CSRC += $(STM32SRCS)
-CPPSRC = lib/util.cpp \
- wiring/math.cpp \
+CPPSRC = wiring/math.cpp \
wiring/Print.cpp \
- wiring/comm/Serial.cpp \
+ wiring/comm/HardwareSerial.cpp \
main.cpp
# i really have no idea what i'm doing
diff --git a/src/lib/adc.c b/src/lib/adc.c
index bcdf874..7169824 100644
--- a/src/lib/adc.c
+++ b/src/lib/adc.c
@@ -1,3 +1,28 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:34:47
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file adc.c
+ *
+ * @brief Analog to digital converter routines
+ */
+
#include "stm32f10x_rcc.h"
#include "adc.h"
#include <stdio.h>
@@ -49,6 +74,7 @@ void adc_init(void) {
ADC_SQR1 = 0;
/* Up the sample conversion time to 55.5 cycles/sec, see note above */
+ /* TODO: fix magic numbers */
ADC_SMPR1 = 0xB6DB6D;
ADC_SMPR2 = 0x2DB6DB6D;
@@ -66,3 +92,6 @@ void adc_init(void) {
}
+void adc_disable(void) {
+ CR2_ADON_BIT = 0;
+}
diff --git a/src/lib/adc.h b/src/lib/adc.h
index 41f975e..d554b02 100644
--- a/src/lib/adc.h
+++ b/src/lib/adc.h
@@ -1,3 +1,28 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:35:10
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file adc.h
+ *
+ * @brief ADC prototypes and defines
+ */
+
#ifndef _ADC_H_
#define _ADC_H_
#include <inttypes.h>
@@ -40,6 +65,7 @@ extern "C"{
/* Initialize ADC1 to do one-shot conversions */
void adc_init(void);
+void adc_disable(void);
/* Perform a single conversion on ADC[0-16],
* PRECONDITIONS:
diff --git a/src/lib/exti.c b/src/lib/exti.c
index 8e46bb1..bdaa204 100644
--- a/src/lib/exti.c
+++ b/src/lib/exti.c
@@ -1,5 +1,31 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:35:22
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file exti.c
+ *
+ * @brief External interrupt control routines
+ */
+
+#include "libmaple.h"
#include "exti.h"
-#include "util.h"
+#include "nvic.h"
volatile static voidFuncPtr exti_handlers[NR_EXTI_CHANNELS];
@@ -22,7 +48,7 @@ void EXTI0_IRQHandler(void) {
exti_handlers[EXTI0]();
}
- /* Clear pending bit*/
+ /* Clear pending bit*/
clear_pending(EXTI0);
}
@@ -33,7 +59,7 @@ void EXTI1_IRQHandler(void) {
exti_handlers[EXTI1]();
}
- /* Clear pending bit*/
+ /* Clear pending bit*/
clear_pending(EXTI1);
}
@@ -44,7 +70,7 @@ void EXTI2_IRQHandler(void) {
exti_handlers[EXTI2]();
}
- /* Clear pending bit*/
+ /* Clear pending bit*/
clear_pending(EXTI2);
}
@@ -55,7 +81,7 @@ void EXTI3_IRQHandler(void) {
exti_handlers[EXTI3]();
}
- /* Clear pending bit*/
+ /* Clear pending bit*/
clear_pending(EXTI3);
}
@@ -66,7 +92,7 @@ void EXTI4_IRQHandler(void) {
exti_handlers[EXTI4]();
}
- /* Clear pending bit*/
+ /* Clear pending bit*/
clear_pending(EXTI4);
}
@@ -80,6 +106,7 @@ void EXTI9_5_IRQHandler(void) {
/* Dispatch every handler if the pending bit is set */
for (i = 0; i < 5; i++) {
if (pending & 0x1) {
+ ASSERT(exti_handlers[EXTI5 + i]);
exti_handlers[EXTI5 + i]();
clear_pending(EXTI5 + i);
}
@@ -97,6 +124,7 @@ void EXTI15_10_IRQHandler(void) {
/* Dispatch every handler if the pending bit is set */
for (i = 0; i < 6; i++) {
if (pending & 0x1) {
+ ASSERT(exti_handlers[EXTI10 + i]);
exti_handlers[EXTI10 + i]();
clear_pending(EXTI10 + i);
}
@@ -110,6 +138,7 @@ void exti_attach_interrupt(uint8_t channel, uint8_t port, voidFuncPtr handler, u
ASSERT(port < NR_EXTI_PORTS);
ASSERT(mode < NR_EXTI_MODES);
ASSERT(EXTI0 == 0);
+ ASSERT(handler);
/* Note: All of the following code assumes that EXTI0 = 0 */
@@ -128,7 +157,7 @@ void exti_attach_interrupt(uint8_t channel, uint8_t port, voidFuncPtr handler, u
case EXTI7:
REG_SET_MASK(AFIO_EXTICR2, BIT_MASK_SHIFT(port, (channel-4)*4));
break;
-
+
case EXTI8:
case EXTI9:
case EXTI10:
@@ -225,7 +254,7 @@ void exti_detach_interrupt(uint8_t channel) {
case EXTI7:
case EXTI8:
case EXTI9:
- /* Are there any other channels enabled?
+ /* Are there any other channels enabled?
* If so, don't disable the interrupt handler */
if (GET_BITS(REG_GET(EXTI_IMR), 5, 9) == 0) {
REG_SET(NVIC_ICER0, BIT(23));
@@ -237,7 +266,7 @@ void exti_detach_interrupt(uint8_t channel) {
case EXTI13:
case EXTI14:
case EXTI15:
- /* Are there any other channels enabled?
+ /* Are there any other channels enabled?
* If so, don't disable the interrupt handler */
if (GET_BITS(REG_GET(EXTI_IMR), 10, 15) == 0) {
REG_SET(NVIC_ICER1, BIT(8));
diff --git a/src/lib/exti.h b/src/lib/exti.h
index ccae3a4..c728454 100644
--- a/src/lib/exti.h
+++ b/src/lib/exti.h
@@ -1,3 +1,28 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:35:33
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file exti.h
+ *
+ * @brief External interrupt control prototypes and defines
+ */
+
#ifndef _EXTI_H_
#define _EXTI_H_
@@ -26,14 +51,14 @@
*
* RM0008, page 107: "PD0, PD1 cannot be used for external interrupt/event generation
* on 36, 48, 64-bin packages."
- *
+ *
* ----------------------------------------------------------------------------
* Pin to EXTI Line Mappings:
- * EXTI0 EXTI1 EXTI2 EXTI3 EXTI4
+ * EXTI0 EXTI1 EXTI2 EXTI3 EXTI4
* ----------------------------------------------------------------------------
* D2/PA0 D3/PA1 D1/PA2 D0/A6/PA3 D10/A10/PA4
* D26/EXT7/PB0 D27/EXT8/PB1 D16/A2/PC2 D17/A3/PC3 D18/A4/PC4
- * D14/A0/PC0 D15/PC1 D25/EXT5/PD2
+ * D14/A0/PC0 D15/PC1 D25/EXT5/PD2
*
* EXTI5 EXTI6 EXTI7 EXTI8 EXTI9
* ----------------------------------------------------------------------------
@@ -53,7 +78,7 @@
* D22/EXT3/PC15
*
*
- * The 16 EXTI interrupts are mapped to 7 interrupt handlers.
+ * The 16 EXTI interrupts are mapped to 7 interrupt handlers.
*
* EXTI Lines to Interrupt Mapping:
* EXTI0 -> EXTI0
@@ -64,7 +89,7 @@
* EXTI[5-9] -> EXT9_5
* EXTI[10-15] -> EXT15_10
*
- *
+ *
* */
#define NR_EXTI_CHANNELS 16
@@ -84,21 +109,6 @@
#define AFIO_EXTICR3 (AFIO_EVCR + 0x10)
#define AFIO_EXTICR4 (AFIO_EVCR + 0x14)
-#define NVIC_EXTI1_OFFSET (NVIC_ISER0 + 0x07)
-#define NVIC_EXTI9_5_OFFSET (NVIC_ISER0 + 0x17)
-
-/* NVIC Interrupt Enable registers */
-#define NVIC_ISER0 0xE000E100
-#define NVIC_ISER1 0xE000E104
-#define NVIC_ISER2 0xE000E108
-#define NVIC_ISER3 0xE000E10C
-
-/* NVIC Interrupt Clear registers */
-#define NVIC_ICER0 0xE000E180
-#define NVIC_ICER1 0xE000E184
-#define NVIC_ICER2 0xE000E188
-#define NVIC_ICER3 0xE000E18C
-
#define EXTI_RISING 0
#define EXTI_FALLING 1
#define EXTI_RISING_FALLING 2
@@ -125,7 +135,6 @@
#define EXTI_CONFIG_PORTC 2
#define EXTI_CONFIG_PORTD 3
-typedef void (*voidFuncPtr)(void);
#ifdef __cplusplus
extern "C"{
diff --git a/src/lib/gpio.c b/src/lib/gpio.c
index db511c4..1e42d4d 100644
--- a/src/lib/gpio.c
+++ b/src/lib/gpio.c
@@ -1,7 +1,35 @@
-#include "wiring.h"
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:35:49
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file gpio.c
+ *
+ * @brief GPIO initialization routine
+ */
+
+#ifndef _GPIO_H_
+#define _GPIO_H_
+
+#endif
+#include "libmaple.h"
#include "stm32f10x_rcc.h"
#include "gpio.h"
-#include "util.h"
void gpio_init(void) {
/* Turn on clocks for GPIO */
@@ -12,3 +40,19 @@ void gpio_init(void) {
ENABLE);
}
+void gpio_set_mode(GPIO_Port* port, uint8_t gpio_pin, uint8_t mode) {
+ uint32_t tmp;
+ uint32_t shift = POS(gpio_pin % 8);
+ GPIOReg CR;
+
+ ASSERT(port);
+ ASSERT(gpio_pin < 16);
+
+ CR = (gpio_pin < 8) ? &(port->CRL) : &(port->CRH);
+
+ tmp = *CR;
+ tmp &= POS_MASK(shift);
+ tmp |= mode << shift;
+
+ *CR = tmp;
+}
diff --git a/src/lib/gpio.h b/src/lib/gpio.h
index 7620f96..bc9bdde 100644
--- a/src/lib/gpio.h
+++ b/src/lib/gpio.h
@@ -1,9 +1,30 @@
-#ifndef _GPIO_H
-#define _GPIO_H
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:36:01
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
-#include <inttypes.h>
-#include "util.h"
+/**
+ * @file gpio.h
+ *
+ * @brief GPIO prototypes, defines, and inlined access functions
+ */
+#ifndef _GPIO_H
+#define _GPIO_H
/* Each of the GPIO port bits can be in the following modes (STM32 138/995):
* Input floating
@@ -13,15 +34,15 @@
* Output open-drain
* Output push-pull
* Alternate function push-pull
- * Alternate function open-drain
+ * Alternate function open-drain
*
* - 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
/* Pin modes are set by [CNFx[1:0] : MODEx[1:0]] */
#define GPIO_SPEED_50MHZ (0x3) // Max output speed 50 MHz
@@ -37,13 +58,13 @@
#define GPIO_MODE_INPUT_PD (0x02 << 2)
#define GPIO_MODE_INPUT_PU (0x02 << 2)
-#define INPUT_ANALOG GPIO_MODE_INPUT_ANALOG
-#define INPUT_DIGITAL GPIO_MODE_INPUT_FLOATING
-#define INPUT_FLOATING GPIO_MODE_INPUT_FLOATING
-#define INPUT_PULLDOWN GPIO_MODE_INPUT_PD
-#define INPUT_PULLUP GPIO_MODE_INPUT_PU
-#define INPUT GPIO_MODE_INPUT_FLOATING
-#define OUTPUT GPIO_MODE_OUTPUT_PP
+//#define INPUT_ANALOG GPIO_MODE_INPUT_ANALOG
+//#define INPUT_DIGITAL GPIO_MODE_INPUT_FLOATING
+//#define INPUT_FLOATING GPIO_MODE_INPUT_FLOATING
+//#define INPUT_PULLDOWN GPIO_MODE_INPUT_PD
+//#define INPUT_PULLUP GPIO_MODE_INPUT_PU
+//#define INPUT GPIO_MODE_INPUT_FLOATING
+//#define OUTPUT GPIO_MODE_OUTPUT_PP
typedef struct {
volatile uint32_t CRL; // Port configuration register low
@@ -65,23 +86,7 @@ extern "C"{
#endif
void gpio_init(void);
-
-static inline void gpio_set_mode(GPIO_Port* port, uint8_t gpio_pin, uint8_t mode) {
- uint32_t tmp;
- uint32_t shift = POS(gpio_pin % 8);
- GPIOReg CR;
-
- ASSERT(port);
- ASSERT(gpio_pin < 16);
-
- CR = (gpio_pin < 8) ? &(port->CRL) : &(port->CRH);
-
- tmp = *CR;
- tmp &= POS_MASK(shift);
- tmp |= mode << shift;
-
- *CR = tmp;
-}
+void gpio_set_mode(GPIO_Port* port, uint8_t gpio_pin, uint8_t mode);
static inline void gpio_write_bit(GPIO_Port *port, uint8_t gpio_pin, uint8_t val) {
if (val){
diff --git a/src/lib/libmaple.h b/src/lib/libmaple.h
new file mode 100644
index 0000000..dc9ffd2
--- /dev/null
+++ b/src/lib/libmaple.h
@@ -0,0 +1,33 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/19/09 02:37:22 EST
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file libmaple.h
+ *
+ * @brief general include file for libmaple
+ */
+
+#ifndef _LIBMAPLE_H_
+#define _LIBMAPLE_H_
+
+#include "libmaple_types.h"
+#include "util.h"
+
+#endif
+
diff --git a/src/lib/libmaple_types.h b/src/lib/libmaple_types.h
new file mode 100644
index 0000000..b798587
--- /dev/null
+++ b/src/lib/libmaple_types.h
@@ -0,0 +1,42 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/19/09 02:35:14 EST
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file libmaple_types.h
+ *
+ * @brief libmaple types
+ */
+
+#ifndef _LIBMAPLE_TYPES_H_
+#define _LIBMAPLE_TYPES_H_
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+
+typedef signed char int8;
+typedef short int16;
+typedef int int32;
+typedef long long int64;
+
+typedef void (*voidFuncPtr)(void);
+
+#endif
+
diff --git a/src/lib/nvic.c b/src/lib/nvic.c
new file mode 100644
index 0000000..61e1d34
--- /dev/null
+++ b/src/lib/nvic.c
@@ -0,0 +1,41 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:36:19
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file nvic.c
+ *
+ * @brief Nested interrupt controller routines
+ */
+
+#include "libmaple.h"
+#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_t *addr, uint32_t offset) {
+// SCB->VTOR = NVIC_VectTab | (Offset & (u32)0x1FFFFF80);
+}
diff --git a/src/lib/nvic.h b/src/lib/nvic.h
new file mode 100644
index 0000000..a2d5c24
--- /dev/null
+++ b/src/lib/nvic.h
@@ -0,0 +1,62 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:36:47
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file nvic.h
+ *
+ * @brief Nested interrupt controller defines and prototypes
+ */
+
+#ifndef _NVIC_H_
+#define _NVIC_H_
+
+#define NVIC_EXTI1_OFFSET (NVIC_ISER0 + 0x07)
+#define NVIC_EXTI9_5_OFFSET (NVIC_ISER0 + 0x17)
+
+/* NVIC Interrupt Enable registers */
+#define NVIC_ISER0 0xE000E100
+#define NVIC_ISER1 0xE000E104
+#define NVIC_ISER2 0xE000E108
+#define NVIC_ISER3 0xE000E10C
+
+/* NVIC Interrupt Clear registers */
+#define NVIC_ICER0 0xE000E180
+#define NVIC_ICER1 0xE000E184
+#define NVIC_ICER2 0xE000E188
+#define NVIC_ICER3 0xE000E18C
+
+/* System control registers */
+#define SCB_VTOR 0xE000ED08 // Vector table offset register
+
+#define NVIC_VectTab_RAM ((u32)0x20000000)
+#define NVIC_VectTab_FLASH ((u32)0x08000000)
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+void nvic_disable_interrupts(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
diff --git a/src/lib/syscalls.c b/src/lib/syscalls.c
index 6095bd3..390cecd 100644
--- a/src/lib/syscalls.c
+++ b/src/lib/syscalls.c
@@ -1,5 +1,5 @@
+#include "libmaple.h"
#include <sys/stat.h>
-#include "stm32f10x_usart.h"
/* _end is set in the linker command file */
extern caddr_t _end;
@@ -72,8 +72,9 @@ int _lseek(int fd, off_t pos, int whence)
unsigned char getch(void)
{
- while (!(USART2->SR & USART_FLAG_RXNE));
- return USART2->DR;
+// while (!(USART2->SR & USART_FLAG_RXNE));
+// return USART2->DR;
+ return 0;
}
@@ -86,10 +87,10 @@ int _read(int fd, char *buf, size_t cnt)
void putch(unsigned char c)
{
- if (c == '\n') putch('\r');
+// if (c == '\n') putch('\r');
- while (!(USART2->SR & USART_FLAG_TXE));
- USART2->DR = c;
+// while (!(USART2->SR & USART_FLAG_TXE));
+// USART2->DR = c;
}
void cgets(char *s, int bufsize)
diff --git a/src/lib/systick.c b/src/lib/systick.c
index f328ae0..47be69e 100644
--- a/src/lib/systick.c
+++ b/src/lib/systick.c
@@ -1,30 +1,52 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:37:24
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file systick.c
+ *
+ * @brief System timer interrupt handler and initialization routines
+ */
+
+#include "libmaple.h"
#include "systick.h"
#define MILLIS_INC 1
-volatile uint32_t systick_timer_overflow_count = 0;
volatile uint32_t systick_timer_millis = 0;
-static uint8_t systick_timer_fract = 0;
void systick_init(void) {
/* Set the reload counter to tick every 1ms */
- SYSTICK_RELOAD = MAPLE_RELOAD_VAL;
+ REG_SET_MASK(SYSTICK_RELOAD, MAPLE_RELOAD_VAL);
+// SYSTICK_RELOAD = MAPLE_RELOAD_VAL;
/* Clock the system timer with the core clock
* and turn it on, interrrupt every 1ms to keep track of millis()*/
- SYSTICK_CSR = SYSTICK_SRC_HCLK |
- SYSTICK_ENABLE |
- SYSTICK_TICKINT;
+ REG_SET(SYSTICK_CSR, SYSTICK_SRC_HCLK |
+ SYSTICK_ENABLE |
+ SYSTICK_TICKINT);
+// SYSTICK_CSR = SYSTICK_SRC_HCLK |
+// SYSTICK_ENABLE |
+// SYSTICK_TICKINT;
}
-void SysTickHandler(void)
-{
- uint32_t m = systick_timer_millis;
- uint8_t f = systick_timer_fract;
-
- m += MILLIS_INC;
- systick_timer_millis = m;
- systick_timer_overflow_count++;
+void SysTickHandler(void) {
+ systick_timer_millis++;
}
diff --git a/src/lib/systick.h b/src/lib/systick.h
index 42d33d0..3d846ef 100644
--- a/src/lib/systick.h
+++ b/src/lib/systick.h
@@ -1,15 +1,40 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:37:37
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file systick.h
+ *
+ * @brief Various system timer definitions
+ */
+
#ifndef _SYSTICK_H_
#define _SYSTICK_H_
-#include <inttypes.h>
-#include "util.h"
+
+#include "libmaple.h"
/* To the ARM technical manual... there's nearly nothing on the systick
* timer in the stm32 manual */
-#define SYSTICK_CSR *(volatile int*)0xE000E010 // Control and status register
-#define SYSTICK_RELOAD *(volatile int*)0xE000E014 // Reload value register
-#define SYSTICK_CNT *(volatile int*)0xE000E018 // Current value register
-#define SYSTICK_CALIB *(volatile int*)0xE000E01C // Calibration 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
diff --git a/src/lib/timers.c b/src/lib/timers.c
index 401b267..2161d84 100644
--- a/src/lib/timers.c
+++ b/src/lib/timers.c
@@ -1,7 +1,31 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:37:54
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file timers.c
+ *
+ * @brief General timer routines
+ */
+
+#include "libmaple.h"
#include "stm32f10x_rcc.h"
-#include "wiring.h"
#include "timers.h"
-#include "util.h"
typedef struct {
volatile uint16_t CR1;
@@ -112,3 +136,19 @@ void timer_init(uint8_t timer_num, uint16_t prescale) {
timer->EGR = 1; // Initialize update event and shadow registers
timer->CR1 |= 1; // Enable timer
}
+
+void timers_disable(void) {
+ Timer *timer;
+ int i;
+ Timer *timers[4] = {
+ (Timer*)TIMER1_BASE,
+ (Timer*)TIMER2_BASE,
+ (Timer*)TIMER3_BASE,
+ (Timer*)TIMER4_BASE,
+ };
+
+ for (i = 0; i < 4; i++) {
+ timer = timers[i];
+ timer->CR1 = 0;
+ }
+}
diff --git a/src/lib/timers.h b/src/lib/timers.h
index 27e5999..9147fd4 100644
--- a/src/lib/timers.h
+++ b/src/lib/timers.h
@@ -1,3 +1,28 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:38:10
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file timers.h
+ *
+ * @brief Timer prototypes and various definitions
+ */
+
/* Note to self:
* The timer clock frequencies are automatically fixed by hardware.
* There are two cases:
@@ -91,6 +116,7 @@ typedef volatile uint32_t* TimerCCR;
* prescale -> {1-65535}
* */
void timer_init(uint8_t, uint16_t);
+void timers_disable(void);
/* Turn on PWM with duty_cycle on the specified channel in timer.
* This function takes in a pointer to the corresponding CCR
diff --git a/src/lib/usart.c b/src/lib/usart.c
index c1a7f43..a06690e 100644
--- a/src/lib/usart.c
+++ b/src/lib/usart.c
@@ -1,44 +1,332 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:38:26
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file usart.c
+ *
+ * @brief USART control routines
+ */
+
+#include "libmaple.h"
#include "stm32f10x_rcc.h"
#include "usart.h"
+#include "nvic.h"
-static inline void usart_putc(usart_port *port, uint8_t ch) {
- port->DR = ch;
+#define USART1_BASE 0x40013800
+#define USART2_BASE 0x40004400
+#define USART3_BASE 0x40004800
- /* Wait till TXE = 1 */
- while ((port->SR & USART_TXE) == 0)
- ;
+#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;
+
+
+/* Don't overrun your buffer, seriously */
+void USART2_IRQHandler(void) {
+ /* Read the data */
+ ring_buf2.buf[ring_buf2.tail++] = (uint8_t)(((usart_port*)(USART2_BASE))->DR);
+ ring_buf2.tail %= USART_RECV_BUF_SIZE;
}
-int32_t usart_init(uint8_t usart_num) {
- ASSERT((usart_num < NR_USARTS) && (usart_num > 0));
+
+/**
+ * @brief Enable a USART in single buffer transmission mode, multibuffer
+ * 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));
+
usart_port *port;
- uint32_t clk_speed;
+ usart_ring_buf *ring_buf;
+
+ uint32 clk_speed;
+ uint32 integer_part;
+ uint32 fractional_part;
+ uint32 tmp;
switch (usart_num) {
case 1:
- port = USART1_BASE;
+ port = (usart_port*)USART1_BASE;
+ ring_buf = &ring_buf1;
clk_speed = USART1_CLK;
break;
case 2:
- port = USART2_BASE;
+ port = (usart_port*)USART2_BASE;
+ ring_buf = &ring_buf2;
clk_speed = USART2_CLK;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
break;
case 3:
- port = USART3_BASE;
+ port = (usart_port*)USART3_BASE;
+ ring_buf = &ring_buf3;
+ clk_speed = USART3_CLK;
break;
default:
/* should never get here */
ASSERT(0);
}
- uint32_t baud = 9600;
- uint32_t usartdiv = clk_speed / baud;
+
+ /* Initialize ring buffer */
+ ring_buf->head = 0;
+ ring_buf->tail = 0;
/* Set baud rate */
- port->BRR = BIT_MASK_SHIFT(B9600_MANTISSA, 4) | B9600_FRACTION;
+ integer_part = ((25 * clk_speed) / (4 * baud));
+ tmp = (integer_part / 100) << 4;
+
+ fractional_part = integer_part - (100 * (tmp >> 4));
+ tmp |= (((fractional_part * 16) + 50) / 100) & ((uint8)0x0F);
+
+ port->BRR = (uint16_t)tmp;
+
+ port->CR1 = USART_TE | // transmitter enable
+ USART_RE | // receiver enable
+ USART_RXNEIE; // receive interrupt enable
+
+ /* Turn it on in the nvic */
+ REG_SET(NVIC_ISER1, BIT(6));
+
+ /* Enable the USART and set mode to 8n1 */
+ port->CR1 |= USART_UE;
+}
+
+
+/**
+ * @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;
+
+ /* TC bit must be high before disabling the usart */
+ while ((port->SR & USART_TC) == 0)
+ ;
+
+ /* Disable UE */
+ port->CR1 = 0;
+}
+
+
+/**
+ * @brief Print a null terminated string to the specified USART
+ *
+ * @param[in] usart_num USART to send on
+ * @param[in] 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') {
+ usart_putc(usart_num, ch);
+ }
+}
+
+/**
+ * @brief Print an unsigned integer to the specified usart
+ *
+ * @param[in] usart_num usart to send on
+ * @param[in] 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;
+
+ i = 0;
+ do {
+ digits[i++] = val % 10 + '0';
+ val /= 10;
+ } while (val > 0);
+ while (--i >= 0) {
+ usart_putc(usart_num, digits[i]);
+ }
+
+}
- /* Enable the USART and set 8n1 (M bit clear) enable transmitter*/
- port->CR1 = USART_UE | USART_TE;
- return 0;
+/**
+ * @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;
+}
+
+
+
+/**
+ * @brief Output a character out the uart
+ *
+ * @param[in] usart_num usart number to output on
+ * @param[in] ch character to send
+ *
+ */
+void usart_putc(uint8 usart_num, uint8 ch) {
+ 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 = ch;
+
+ /* Wait for transmission to complete */
+ while ((port->SR & USART_TXE) == 0)
+ ;
+}
+
+
diff --git a/src/lib/usart.h b/src/lib/usart.h
index 30f7dc1..4d0c586 100644
--- a/src/lib/usart.h
+++ b/src/lib/usart.h
@@ -1,7 +1,30 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:38:35
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file usart.h
+ *
+ * @brief USART Definitions
+ */
+
#ifndef _USART_H_
#define _USART_H_
-#include <inttypes.h>
-#include <util.h>
/* Transmit procedure:
* 1. Enable the USART by writing the UE bit in USART_CR1 register to 1.
@@ -77,50 +100,24 @@
* 921600 923.076 2.4375 0.16% 4.875 0.16%
* 225000 2250 1 0% 2 0%
*
- * USART_BRR[15:4] = mantissa
- * USART_BRR[3:0] = fraction
- * 111010
- * 0110
* */
#define NR_USARTS 0x3
-//#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_TXE BIT(7)
-#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 B9600_MANTISSA 0xEA
-#define B9600_FRACTION 0x06
-
-
-typedef struct usart_port {
- volatile uint32_t SR;
- volatile uint32_t DR;
- volatile uint32_t BRR;
- volatile uint32_t CR1;
- volatile uint32_t CR2;
- volatile uint32_t CR3;
- volatile uint32_t GTPR;
-} usart_port;
-
#ifdef __cplusplus
extern "C"{
#endif
-int32_t usart_init(uint8_t);
+#define USART_MAX_BAUD 225000
+
+void usart_init(uint8 usart_num, uint32 baud);
+void usart_disable(uint8 usart_num);
+
+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);
#ifdef __cplusplus
} // extern "C"
diff --git a/src/lib/util.c b/src/lib/util.c
new file mode 100644
index 0000000..c75031f
--- /dev/null
+++ b/src/lib/util.c
@@ -0,0 +1,99 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:38:44
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file util.h
+ *
+ * @brief Utility procedures for debugging, mostly an error LED fade and
+ * messages dumped over a uart for failed asserts.
+ */
+
+#include "libmaple.h"
+#include "usart.h"
+#include "gpio.h"
+#include "nvic.h"
+#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_t slope = 1;
+ int32_t CC = 0x0000;
+ int32_t TOP_CNT = 0x02FF;
+ int32_t i = 0;
+
+ /* Turn off interrupts */
+ nvic_disable_interrupts();
+
+ /* Turn off timers */
+ timers_disable();
+
+ /* Turn off ADC */
+ adc_disable();
+
+ /* Turn off all usarts */
+ usart_disable(1);
+ usart_disable(2);
+ usart_disable(3);
+
+ /* Initialize the error usart */
+ gpio_set_mode(ERROR_TX_PORT, ERROR_TX_PIN, GPIO_MODE_AF_OUTPUT_PP);
+ usart_init(ERROR_USART_NUM, ERROR_USART_BAUD);
+
+ /* Print failed assert message */
+ usart_putstr(ERROR_USART_NUM, "ERROR: FAILED ASSERT(");
+ usart_putstr(ERROR_USART_NUM, exp);
+ usart_putstr(ERROR_USART_NUM, "): ");
+ usart_putstr(ERROR_USART_NUM, file);
+ usart_putstr(ERROR_USART_NUM, ": ");
+ usart_putudec(ERROR_USART_NUM, line);
+ usart_putc(ERROR_USART_NUM, '\n');
+
+ /* Turn on the error LED */
+ gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT_PP);
+
+ /* Error fade */
+ while (1) {
+ if (CC == TOP_CNT) {
+ slope = -1;
+ } else if (CC == 0) {
+ slope = 1;
+ }
+
+ if (i == TOP_CNT) {
+ CC += slope;
+ i = 0;
+ }
+
+ if (i < CC) {
+ gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 1);
+ } else {
+ gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 0);
+ }
+ i++;
+ }
+}
+
diff --git a/src/lib/util.cpp b/src/lib/util.cpp
deleted file mode 100644
index 4eb4fe0..0000000
--- a/src/lib/util.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "wiring.h"
-#include "Serial.h"
-#include "util.h"
-#include "io.h"
-
-#define ERROR_PIN 13
-
-/* Required for C++ hackery */
-extern "C" void __cxa_pure_virtual(void) {
- while(1)
- ;
-}
-
-/* Error assert + fade */
-void _fail(const char* file, int line, const char* exp) {
- int32_t slope = 1;
- int32_t CC = 0x0000;
- int32_t TOP_CNT = 0x02FF;
- int32_t i = 0;
-
- Serial1.print("ERROR: FAILED ASSERT(");
- Serial1.print(exp);
- Serial1.print("): ");
- Serial1.print(file);
- Serial1.print(":");
- Serial1.println(line);
-
- while (1) {
- if (CC == TOP_CNT) {
- slope = -1;
- } else if (CC == 0) {
- slope = 1;
- }
-
- if (i == TOP_CNT) {
- CC += slope;
- i = 0;
- }
-
- if (i < CC) {
- digitalWrite(ERROR_PIN, HIGH);
- } else {
- digitalWrite(ERROR_PIN, LOW);
- }
- i++;
- }
-}
diff --git a/src/lib/util.h b/src/lib/util.h
index 8701af1..e425cc0 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -1,3 +1,28 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:39:27
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file util.h
+ *
+ * @brief Various macros and utility procedures.
+ */
+
/* Generally "useful" utility procedures */
#ifndef _UTIL_H_
#define _UTIL_H_
diff --git a/src/main.cpp b/src/main.cpp
index 2266f3d..46037bd 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,17 +1,6 @@
-#include "stm32f10x_map.h"
-#include "stm32f10x_lib.h"
-#include "stm32f10x_flash.h"
-#include "stm32f10x_usart.h"
-#include "Serial.h"
-#include "timers.h"
#include "wiring.h"
-#include "util.h"
-#include "systick.h"
-#include "adc.h"
-#include "gpio.h"
-#include "pwm.h"
-#include "ext_interrupts.h"
-#include "usart.h"
+#include "HardwareSerial.h"
+#include "math.h"
#include "usb.h"
void setup();
@@ -19,21 +8,17 @@ void loop();
int ledPin = 13;
+
void setup()
{
-// Serial1.begin(9600);
-// Serial1.println("setup start");
-
-// pinMode(ledPin, OUTPUT);
- pinMode(1, GPIO_MODE_AF_OUTPUT_PP);
- pinMode(0, INPUT);
-
pinMode(ledPin, OUTPUT);
+ Serial2.begin(9600);
+ Serial2.println("setup start");
-// usart_init(2);
-
+ pinMode(6, PWM);
+ pwmWrite(6, 0x8000);
-// Serial1.println("setup end");
+ Serial2.println("setup end");
}
int toggle = 0;
@@ -50,8 +35,7 @@ void loop() {
}
-int main(void)
-{
+int main(void) {
init();
setup();
@@ -61,13 +45,10 @@ int main(void)
return 0;
}
-
-/* Implemented:
- * void pinMode(pin, mode)
- * void digitalWrite(pin, value)
- * uint32_t digitalRead(pin)
- * uint32_t analogRead(pin)
- * void randomSeed(seed)
- * long random(max)
- * long random(min, max)
+/* Required for C++ hackery */
+/* TODO: This really shouldn't go here... move it later
* */
+extern "C" void __cxa_pure_virtual(void) {
+ while(1)
+ ;
+}
diff --git a/src/stm32lib/inc/stm32f10x_map.h b/src/stm32lib/inc/stm32f10x_map.h
index 33829fc..3dabb05 100644
--- a/src/stm32lib/inc/stm32f10x_map.h
+++ b/src/stm32lib/inc/stm32f10x_map.h
@@ -621,8 +621,8 @@ typedef struct
#define IWDG_BASE (APB1PERIPH_BASE + 0x3000)
#define SPI2_BASE (APB1PERIPH_BASE + 0x3800)
#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00)
-#define USART2_BASE (APB1PERIPH_BASE + 0x4400)
-#define USART3_BASE (APB1PERIPH_BASE + 0x4800)
+//#define USART2_BASE (APB1PERIPH_BASE + 0x4400)
+//#define USART3_BASE (APB1PERIPH_BASE + 0x4800)
#define UART4_BASE (APB1PERIPH_BASE + 0x4C00)
#define UART5_BASE (APB1PERIPH_BASE + 0x5000)
#define I2C1_BASE (APB1PERIPH_BASE + 0x5400)
@@ -634,19 +634,19 @@ typedef struct
#define AFIO_BASE (APB2PERIPH_BASE + 0x0000)
#define EXTI_BASE (APB2PERIPH_BASE + 0x0400)
-#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
-#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
-#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
-#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
-#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
-#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00)
-#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000)
+//#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
+//#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
+//#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
+//#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
+//#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
+//#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00)
+//#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000)
#define ADC1_BASE (APB2PERIPH_BASE + 0x2400)
#define ADC2_BASE (APB2PERIPH_BASE + 0x2800)
#define TIM1_BASE (APB2PERIPH_BASE + 0x2C00)
#define SPI1_BASE (APB2PERIPH_BASE + 0x3000)
#define TIM8_BASE (APB2PERIPH_BASE + 0x3400)
-#define USART1_BASE (APB2PERIPH_BASE + 0x3800)
+//#define USART1_BASE (APB2PERIPH_BASE + 0x3800)
#define ADC3_BASE (APB2PERIPH_BASE + 0x3C00)
#define SDIO_BASE (PERIPH_BASE + 0x18000)
diff --git a/src/wiring/Print.cpp b/src/wiring/Print.cpp
index 20f5e40..c7e0cc6 100644
--- a/src/wiring/Print.cpp
+++ b/src/wiring/Print.cpp
@@ -98,14 +98,14 @@ void Print::print(double n)
void Print::println(void)
{
- print('\r');
- print('\n');
+// print('\r');
+ print('\n');
}
void Print::println(char c)
{
print(c);
- println();
+ println();
}
void Print::println(const char c[])
@@ -135,13 +135,13 @@ void Print::println(unsigned int n)
void Print::println(long n)
{
print(n);
- println();
+ println();
}
void Print::println(unsigned long n)
{
print(n);
- println();
+ println();
}
void Print::println(long n, int base)
@@ -160,13 +160,13 @@ void Print::println(double n)
void Print::printNumber(unsigned long n, uint8_t base)
{
- unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
+ unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
unsigned long i = 0;
if (n == 0) {
print('0');
return;
- }
+ }
while (n > 0) {
buf[i++] = n % base;
@@ -179,8 +179,8 @@ void Print::printNumber(unsigned long n, uint8_t base)
'A' + buf[i - 1] - 10));
}
-void Print::printFloat(double number, uint8_t digits)
-{
+void Print::printFloat(double number, uint8_t digits)
+{
// Handle negative numbers
if (number < 0.0)
{
@@ -192,7 +192,7 @@ void Print::printFloat(double number, uint8_t digits)
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
-
+
number += rounding;
// Extract the integer part of the number and print it
@@ -202,7 +202,7 @@ void Print::printFloat(double number, uint8_t digits)
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
- print(".");
+ print(".");
// Extract digits from the remainder one at a time
while (digits-- > 0)
@@ -210,6 +210,6 @@ void Print::printFloat(double number, uint8_t digits)
remainder *= 10.0;
int toPrint = int(remainder);
print(toPrint);
- remainder -= toPrint;
- }
+ remainder -= toPrint;
+ }
}
diff --git a/src/wiring/comm/HardwareSerial.cpp b/src/wiring/comm/HardwareSerial.cpp
new file mode 100644
index 0000000..84eb4c7
--- /dev/null
+++ b/src/wiring/comm/HardwareSerial.cpp
@@ -0,0 +1,92 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/19/09 05:15:24 EST
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file HardwareSerial.cpp
+ *
+ * @brief Wiring-like serial api
+ */
+
+#include "wiring.h"
+#include "HardwareSerial.h"
+#include "usart.h"
+#include "gpio.h"
+
+#define USART1_TX_PORT GPIOA_BASE
+#define USART1_TX_PIN 9
+#define USART1_RX_PORT GPIOA_BASE
+#define USART1_RX_PIN 10
+
+#define USART2_TX_PORT GPIOA_BASE
+#define USART2_TX_PIN 2
+#define USART2_RX_PORT GPIOA_BASE
+#define USART2_RX_PIN 3
+
+#define USART3_TX_PORT GPIOB_BASE
+#define USART3_TX_PIN 10
+#define USART3_RX_PORT GPIOB_BASE
+#define USART3_RX_PIN 11
+
+HardwareSerial::HardwareSerial(uint8_t usartNum) {
+ ASSERT(usartNum == 1 ||
+ usartNum == 2 ||
+ usartNum == 3);
+ this->usartNum = usartNum;
+}
+
+uint8_t HardwareSerial::read(void) {
+ return usart_getc(usartNum);
+}
+
+uint32 HardwareSerial::available(void) {
+
+ return usart_data_available(usartNum);
+}
+
+void HardwareSerial::write(unsigned char ch) {
+ usart_putc(usartNum, ch);
+}
+
+void HardwareSerial::begin(uint32_t baud) {
+ ASSERT(!(baud > USART_MAX_BAUD));
+
+ /* Set appropriate pin modes */
+ switch (usartNum) {
+ case 1:
+ gpio_set_mode(USART1_TX_PORT, USART1_TX_PIN, GPIO_MODE_AF_OUTPUT_PP);
+ gpio_set_mode(USART1_RX_PORT, USART1_RX_PIN, GPIO_MODE_INPUT_FLOATING);
+ break;
+ case 2:
+ gpio_set_mode(USART2_TX_PORT, USART2_TX_PIN, GPIO_MODE_AF_OUTPUT_PP);
+ gpio_set_mode(USART2_RX_PORT, USART2_RX_PIN, GPIO_MODE_INPUT_FLOATING);
+ break;
+ case 3:
+ gpio_set_mode(USART3_TX_PORT, USART3_TX_PIN, GPIO_MODE_AF_OUTPUT_PP);
+ gpio_set_mode(USART3_RX_PORT, USART3_RX_PIN, GPIO_MODE_INPUT_FLOATING);
+ break;
+ default:
+ ASSERT(0);
+ }
+
+ usart_init(usartNum, baud);
+}
+
+HardwareSerial Serial1(1);
+HardwareSerial Serial2(2);
+HardwareSerial Serial3(3);
diff --git a/src/wiring/comm/HardwareSerial.h b/src/wiring/comm/HardwareSerial.h
new file mode 100644
index 0000000..a3913f9
--- /dev/null
+++ b/src/wiring/comm/HardwareSerial.h
@@ -0,0 +1,48 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/19/09 05:45:37 EST
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file HardwareSerial.h
+ *
+ * @brief
+ */
+
+#ifndef _HARDWARESERIAL_H_
+#define _HARDWARESERIAL_H_
+
+#include "Print.h"
+
+class HardwareSerial : public Print {
+ private:
+ uint8 usartNum;
+ public:
+ HardwareSerial(uint8_t);
+ void begin(uint32_t);
+ uint32 available(void);
+ uint8_t read(void);
+ void flush(void);
+ virtual void write(unsigned char);
+ using Print::write;
+};
+
+extern HardwareSerial Serial1;
+extern HardwareSerial Serial2;
+extern HardwareSerial Serial3;
+#endif
+
diff --git a/src/wiring/comm/Serial.cpp b/src/wiring/comm/Serial.cpp
deleted file mode 100644
index 3c43436..0000000
--- a/src/wiring/comm/Serial.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-//#include "stm32f10x_usart.h"
-#include "stm32f10x_gpio.h"
-#include "stm32f10x_rcc.h"
-#include "gpio.h"
-#include "Serial.h"
-#include "wiring.h"
-
-int SendChar (int ch) {
- /* Write character to Serial Port */
-// USART_SendData(USART2, (unsigned char) ch);
-// while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
-// ;
-//
-// // while (!(USART2->SR & USART_FLAG_TXE));
-// return (ch);
-}
-
-void uart_send(const char* str) {
- while (*str != '\0') {
- SendChar(*str);
- str++;
- }
-}
-
-
-Serial::Serial() {
-}
-
-void Serial::write(uint8_t c) {
- SendChar(c);
-}
-
-void Serial::begin(uint32_t baud) {
- // USART_InitTypeDef USART_InitStructure;
-
- /* Turn on the clock */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
-
-#if 0
- /* Configure USART2 Tx as alternate function push-pull */
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- /* Configure USART2 Rx as input floating */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-#endif
-
- pinMode(1, GPIO_MODE_AF_OUTPUT_PP);
- pinMode(0, GPIO_MODE_INPUT_FLOATING);
-
- /* Enable USART2 */
-// USART_InitStructure.USART_BaudRate = baud;
-// USART_InitStructure.USART_WordLength = USART_WordLength_8b;
-// USART_InitStructure.USART_StopBits = USART_StopBits_1;
-// USART_InitStructure.USART_Parity = USART_Parity_No ;
-// USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
-// USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
-// USART_Init(USART2, &USART_InitStructure);
-// USART_Cmd(USART2, ENABLE);
-}
-
-Serial Serial1;
diff --git a/src/wiring/comm/Serial.h b/src/wiring/comm/Serial.h
deleted file mode 100644
index 0e7a126..0000000
--- a/src/wiring/comm/Serial.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef _SERIAL_H_
-#define _SERIAL_H_
-
-#include <inttypes.h>
-#include <Print.h>
-
-class Serial : public Print {
- public:
- Serial();
- void begin(uint32_t);
- uint8_t available(void);
- int read(void);
- void flush(void);
- virtual void write(uint8_t);
- using Print::write;
-};
-
-extern Serial Serial1;
-#endif
-
diff --git a/src/wiring/ext_interrupts.c b/src/wiring/ext_interrupts.c
index 0a35472..20ec11f 100644
--- a/src/wiring/ext_interrupts.c
+++ b/src/wiring/ext_interrupts.c
@@ -1,3 +1,28 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:39:48
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file ext_interrupts.c
+ *
+ * @brief Wiring-like interface for external interrupts
+ */
+
#include "wiring.h"
#include "exti.h"
#include "ext_interrupts.h"
@@ -25,7 +50,6 @@ static ExtiInfo PIN_TO_EXTI_CHANNEL[NR_MAPLE_PINS] = {
};
-
/**
* @brief Attach an interrupt handler to be triggered on a given
* transition on the pin. Runs in interrupt context
@@ -36,23 +60,38 @@ static ExtiInfo PIN_TO_EXTI_CHANNEL[NR_MAPLE_PINS] = {
*
* @sideeffect Registers a handler
*/
-int attachInterrupt(uint8_t pin, void (*handler)(void), uint8_t mode) {
+int attachInterrupt(uint8_t pin, voidFuncPtr handler, ExtInterruptTriggerMode mode) {
+ uint8_t outMode;
/* Parameter checking */
if (pin >= NR_MAPLE_PINS) {
return EXT_INTERRUPT_INVALID_PIN;
}
if (!handler) {
+ ASSERT(0);
return EXT_INTERRUPT_INVALID_FUNCTION;
}
- if (!(mode < NR_EXTI_MODES)) {
- return EXT_INTERRUPT_INVALID_MODE;
+ switch (mode) {
+ case RISING:
+ outMode = EXTI_RISING;
+ break;
+ case FALLING:
+ outMode = EXTI_FALLING;
+ break;
+ case CHANGE:
+ outMode = EXTI_RISING_FALLING;
+ break;
+ default:
+ ASSERT(0);
+ return EXT_INTERRUPT_INVALID_MODE;;
}
- exti_attach_interrupt(PIN_TO_EXTI_CHANNEL[pin].channel,
+ exti_attach_interrupt(PIN_TO_EXTI_CHANNEL[pin].channel,
PIN_TO_EXTI_CHANNEL[pin].port,
handler, mode);
+
+ return 0;
}
int detachInterrupt(uint8_t pin) {
diff --git a/src/wiring/ext_interrupts.h b/src/wiring/ext_interrupts.h
index d6fb23f..d0e6365 100644
--- a/src/wiring/ext_interrupts.h
+++ b/src/wiring/ext_interrupts.h
@@ -1,11 +1,36 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:40:09
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file ext_interrupts.h
+ *
+ * @brief External interrupt wiring prototypes and types
+ */
+
#ifndef _EXT_INTERRUPTS_H_
#define _EXT_INTERRUPTS_H_
-#include "exti.h"
-
-#define RISING EXTI_RISING
-#define FALLING EXTI_FALLING
-#define CHANGE EXTI_RISING_FALLING
+typedef enum ExtInterruptTriggerMode {
+ RISING,
+ FALLING,
+ CHANGE
+} ExtInterruptTriggerMode;
enum ExtInterruptError {
@@ -19,8 +44,8 @@ enum ExtInterruptError {
extern "C"{
#endif
-int attachInterrupt(uint8_t, void ((*)(void)), uint8_t);
-int detachInterrupt(uint8_t);
+int attachInterrupt(uint8_t pin, voidFuncPtr, ExtInterruptTriggerMode mode);
+int detachInterrupt(uint8_t pin);
#ifdef __cplusplus
}
diff --git a/src/wiring/io.h b/src/wiring/io.h
index 387326a..9c226c5 100644
--- a/src/wiring/io.h
+++ b/src/wiring/io.h
@@ -1,3 +1,28 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:40:56
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file io.h
+ *
+ * @brief
+ */
+
#ifndef _IO_H
#define _IO_H
@@ -67,6 +92,31 @@ extern "C"{
#define A14 D26
#define A15 D11
+typedef enum WiringPinMode {
+ OUTPUT,
+ INPUT,
+ INPUT_PULLUP,
+ INPUT_PULLDOWN,
+ INPUT_FLOATING,
+ PWM
+} WiringPinMode;
+
+#if 0
+typedef enum PinMode {
+ INPUT_FLOATING,
+ INPUT_ANALOG,
+ INPUT_DIGITAL,
+ INPUT_PULLDOWN,
+ INPUT_PULLUP,
+ INPUT,
+ OUTPUT,
+ PWM,
+ SERIAL,
+ SPI,
+ I2C,
+} PinMode;
+#endif
+
/* Set pin to mode
* pinMode(pin, mode):
* pin -> {0-38, D0-D39, A0-16}
@@ -81,7 +131,7 @@ extern "C"{
*/
void pinMode(uint8_t, uint8_t);
-/*
+/*
* Writes VALUE to digital pin[0-38]
* digitalWrite(pin, value):
* pin -> {0-38, D0-D39, A0-16}
@@ -91,13 +141,13 @@ void digitalWrite(uint8_t, uint8_t);
/* Read a digital value from pin, the pin mode must be set to
* {INPUT, INPUT_PULLUP, INPUT_PULLDOWN}
- * digitalRead(pin)
+ * digitalRead(pin)
* pin -> {0-38, D0-D39, A0-16}
*/
uint32_t digitalRead(uint8_t);
/* Read an analog value from pin, the pin mode must be set
- * to INPUT_ANALOG
+ * to INPUT_ANALOG
* analogRead(pin)
* pin -> {A0-A16}
* */
diff --git a/src/wiring/math.h b/src/wiring/math.h
index ee269e9..8f30396 100644
--- a/src/wiring/math.h
+++ b/src/wiring/math.h
@@ -1,5 +1,5 @@
-#ifndef _MAPLE_MATH_H_
-#define _MAPLE_MATH_H_
+#ifndef _MATH_H_
+#define _MATH_H_
void randomSeed(unsigned int);
long random(long);
diff --git a/src/wiring/pwm.c b/src/wiring/pwm.c
index 0c33c3a..e6e100f 100644
--- a/src/wiring/pwm.c
+++ b/src/wiring/pwm.c
@@ -1,3 +1,28 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:41:24
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file pwm.c
+ *
+ * @brief
+ */
+
#include "wiring.h"
#include "timers.h"
#include "gpio.h"
diff --git a/src/wiring/pwm.h b/src/wiring/pwm.h
index 3ff440b..60d805d 100644
--- a/src/wiring/pwm.h
+++ b/src/wiring/pwm.h
@@ -1,3 +1,28 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:41:27
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file pwm.h
+ *
+ * @brief
+ */
+
#ifndef _PWM_H
#define _PWM_H
@@ -5,8 +30,6 @@
extern "C"{
#endif
-#define PWM GPIO_MODE_AF_OUTPUT_PP
-
void pwmWrite(uint8_t, uint16_t);
#ifdef __cplusplus
diff --git a/src/wiring/time.c b/src/wiring/time.c
index bf6a28b..1a91b5e 100644
--- a/src/wiring/time.c
+++ b/src/wiring/time.c
@@ -1,3 +1,29 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:41:36
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file time.c
+ *
+ * @brief
+ */
+
+#include "libmaple.h"
#include "systick.h"
#include "time.h"
diff --git a/src/wiring/time.h b/src/wiring/time.h
index 694545b..a97310a 100644
--- a/src/wiring/time.h
+++ b/src/wiring/time.h
@@ -1,8 +1,31 @@
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:41:40
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file time.h
+ *
+ * @brief
+ */
+
#ifndef _TIME_H
#define _TIME_H
-#include <inttypes.h>
-
#ifdef __cplusplus
extern "C"{
#endif
diff --git a/src/wiring/wiring.c b/src/wiring/wiring.c
index 7fcd5fd..9d77a5b 100644
--- a/src/wiring/wiring.c
+++ b/src/wiring/wiring.c
@@ -1,9 +1,33 @@
-#include <inttypes.h>
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:41:47
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file wiring.c
+ *
+ * @brief
+ */
+
+#include "wiring.h"
#include "stm32f10x_flash.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_map.h"
#include "stm32f10x_nvic.h"
-#include "wiring.h"
#include "systick.h"
#include "gpio.h"
@@ -26,7 +50,7 @@ void init(void) {
/* off for debug */
// adc_init();
-// timer_init(1, 1);
+ timer_init(1, 1);
// timer_init(2, 1);
// timer_init(3, 1);
// timer_init(4, 1);
diff --git a/src/wiring/wiring.h b/src/wiring/wiring.h
index 4bf93bc..2a33b75 100644
--- a/src/wiring/wiring.h
+++ b/src/wiring/wiring.h
@@ -1,16 +1,20 @@
#ifndef _WIRING_H_
#define _WIRING_H_
-#include <inttypes.h>
+#include "libmaple.h"
#include "timers.h"
#include "io.h"
#include "binary.h"
+#include "bits.h"
#include "time.h"
+#include "pwm.h"
+#include "ext_interrupts.h"
#ifdef __cplusplus
extern "C"{
#endif
+
#define MAPLE 1
#define NR_MAPLE_PINS 14 // temporary
@@ -38,12 +42,10 @@ extern "C"{
#define bit(b) (1UL << (b))
-typedef uint8_t boolean;
-typedef uint8_t byte;
+typedef uint8 boolean;
+typedef uint8 byte;
void init(void);
-
-
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val);
diff --git a/src/wiring/wiring_analog.c b/src/wiring/wiring_analog.c
index abcf7c6..0426f85 100644
--- a/src/wiring/wiring_analog.c
+++ b/src/wiring/wiring_analog.c
@@ -1,7 +1,31 @@
-#include "adc.h"
-#include "gpio.h"
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:41:55
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file wiring_analog.c
+ *
+ * @brief
+ */
+
+#include "libmaple.h"
#include "wiring.h"
-#include <stdio.h>
+#include "adc.h"
/* Indexed by pins A[0-15] */
uint32_t PIN_TO_ADC[NR_ANALOG_PINS] = {
diff --git a/src/wiring/wiring_digital.c b/src/wiring/wiring_digital.c
index 1ece41a..456f5da 100644
--- a/src/wiring/wiring_digital.c
+++ b/src/wiring/wiring_digital.c
@@ -1,42 +1,104 @@
-#include "gpio.h"
+/* *****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created: 12/18/09 02:42:00
+ * Copyright (c) 2009 Perry L. Hung. All rights reserved.
+ *
+ * ****************************************************************************/
+
+/**
+ * @file wiring_digital.c
+ *
+ * @brief
+ */
+
#include "wiring.h"
-#include "util.h"
+#include "io.h"
+#include "gpio.h"
+
+typedef enum AFMode{
+ AF_NONE,
+ AF_PWM,
+ AF_SERIAL,
+ AF_I2C, // unused for now
+ AF_SPI, // unusued for now
+} AFMode;
+
typedef struct PinGPIOMapping {
GPIO_Port *port;
- uint32_t pin;
+ uint32 pin;
} PinGPIOMapping;
+
+/* Reset state is input floating */
static const PinGPIOMapping PIN_TO_GPIO[NR_MAPLE_PINS] = {
- {_GPIOA_BASE, 3}, // D0/PA3
- {_GPIOA_BASE, 2}, // D1/PA2
- {_GPIOA_BASE, 0}, // D2/PA0
- {_GPIOA_BASE, 1}, // D3/PA1
- {_GPIOB_BASE, 5}, // D4/PB5
- {_GPIOB_BASE, 6}, // D5/PB6
- {_GPIOA_BASE, 8}, // D6/PA8
- {_GPIOA_BASE, 9}, // D7/PA9
- {_GPIOA_BASE, 10}, // D8/PA10
- {_GPIOB_BASE, 7}, // D9/PB7
- {_GPIOA_BASE, 4}, // D10/PA4
- {_GPIOA_BASE, 7}, // D11/PA7
- {_GPIOA_BASE, 6}, // D12/PA6
- {_GPIOA_BASE, 5}, // D13/PA5
+ {GPIOA_BASE, 3}, // D0/PA3
+ {GPIOA_BASE, 2}, // D1/PA2
+ {GPIOA_BASE, 0}, // D2/PA0
+ {GPIOA_BASE, 1}, // D3/PA1
+ {GPIOB_BASE, 5}, // D4/PB5
+ {GPIOB_BASE, 6}, // D5/PB6
+ {GPIOA_BASE, 8}, // D6/PA8
+ {GPIOA_BASE, 9}, // D7/PA9
+ {GPIOA_BASE, 10}, // D8/PA10
+ {GPIOB_BASE, 7}, // D9/PB7
+ {GPIOA_BASE, 4}, // D10/PA4
+ {GPIOA_BASE, 7}, // D11/PA7
+ {GPIOA_BASE, 6}, // D12/PA6
+ {GPIOA_BASE, 5}, // D13/PA5
+/* for later */
#if 0
- {_GPIOC_BASE, 0}, // D14/A0/PC0
- {_GPIOC_BASE, 1}, // D15/A1/PC1
- {_GPIOC_BASE, 2}, // D16/A2/PC2
- {_GPIOC_BASE, 3}, // D17/A3/PC3
- {_GPIOC_BASE, 4}, // D18/A4/PC4
- {_GPIOC_BASE, 5}, // D19/A5/PC5
+ {GPIOC_BASE, 0}, // D14/A0/PC0
+ {GPIOC_BASE, 1}, // D15/A1/PC1
+ {GPIOC_BASE, 2}, // D16/A2/PC2
+ {GPIOC_BASE, 3}, // D17/A3/PC3
+ {GPIOC_BASE, 4}, // D18/A4/PC4
+ {GPIOC_BASE, 5}, // D19/A5/PC5
#endif
};
-void pinMode(uint8_t pin, uint8_t mode) {
+void pinMode(uint8_t pin, WiringPinMode mode) {
+ uint8 outputMode;
+
if (pin >= NR_MAPLE_PINS)
return;
- gpio_set_mode(PIN_TO_GPIO[pin].port, PIN_TO_GPIO[pin].pin, mode);
+ switch(mode) {
+ case OUTPUT:
+ outputMode = GPIO_MODE_OUTPUT_PP;
+ break;
+ case INPUT:
+ case INPUT_FLOATING:
+ outputMode = GPIO_MODE_INPUT_FLOATING;
+ break;
+ case INPUT_PULLUP:
+ outputMode = GPIO_MODE_INPUT_PU;
+ break;
+ case INPUT_PULLDOWN:
+ outputMode = GPIO_MODE_INPUT_PD;
+ break;
+ case PWM:
+ outputMode = GPIO_MODE_AF_OUTPUT_PP;
+ break;
+ default:
+ ASSERT(0);
+ return;
+ }
+
+
+ gpio_set_mode(PIN_TO_GPIO[pin].port, PIN_TO_GPIO[pin].pin, outputMode);
}
diff --git a/src/wiring/wiring_shift.c b/src/wiring/wiring_shift.c
index c138b56..28c6dfc 100644
--- a/src/wiring/wiring_shift.c
+++ b/src/wiring/wiring_shift.c
@@ -1,5 +1,3 @@
-/* copied straight from arduino/wiring_shift.c */
-
/*
wiring_shift.c - shiftOut() function
Part of Arduino - http://www.arduino.cc/