aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authoriperry <iperry@749a229e-a60e-11de-b98f-4500b42dc123>2009-12-19 10:53:07 +0000
committeriperry <iperry@749a229e-a60e-11de-b98f-4500b42dc123>2009-12-19 10:53:07 +0000
commitacf59b1abb346998c492b93fee4a680a32f538d5 (patch)
treec49dd57f489769608095736457a0db9350868a47 /src
parentaf4c4985cef82b80b936584d686c80d9538082b6 (diff)
downloadlibrambutan-acf59b1abb346998c492b93fee4a680a32f538d5.tar.gz
librambutan-acf59b1abb346998c492b93fee4a680a32f538d5.zip
Added licensing. Moved lots of header files around. Added HardwareSerial reads, writes. Tweaked some of the util and assert functions. Added various useful routines for printing stuff to the serial port. Continued moving out stm32lib. Slightly more consistent naming, this will come in another change.
git-svn-id: https://leaflabs.googlecode.com/svn/trunk/library@74 749a229e-a60e-11de-b98f-4500b42dc123
Diffstat (limited to 'src')
-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
40 files changed, 1549 insertions, 398 deletions
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/