aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoriperry <iperry@749a229e-a60e-11de-b98f-4500b42dc123>2009-12-25 08:39:24 +0000
committeriperry <iperry@749a229e-a60e-11de-b98f-4500b42dc123>2009-12-25 08:39:24 +0000
commitb6674cd738cc22e61ea34cb659750ef45ce01df4 (patch)
treebfee2ae84883c32871ee13a6e0f346f144263cf6
parent3bb04834ffd3f90dc9015997ea11a56d9d150099 (diff)
downloadlibrambutan-b6674cd738cc22e61ea34cb659750ef45ce01df4.tar.gz
librambutan-b6674cd738cc22e61ea34cb659750ef45ce01df4.zip
Fixed delayMicroseconds, changed serial interface, added an (untested) runtime check for pwm/serial collision, moved more headers around.
git-svn-id: https://leaflabs.googlecode.com/svn/trunk/library@79 749a229e-a60e-11de-b98f-4500b42dc123
-rw-r--r--README.txt14
-rw-r--r--src/lib/gpio.c8
-rw-r--r--src/lib/gpio.h28
-rw-r--r--src/lib/systick.h2
-rw-r--r--src/lib/timers.c37
-rw-r--r--src/lib/timers.h1
-rw-r--r--src/lib/usart.h75
-rw-r--r--src/main.cpp9
-rw-r--r--src/wiring/comm/HardwareSerial.cpp3
-rw-r--r--src/wiring/time.c23
-rw-r--r--src/wiring/time.h14
-rw-r--r--src/wiring/wiring.c9
12 files changed, 82 insertions, 141 deletions
diff --git a/README.txt b/README.txt
index 802aa24..17f813e 100644
--- a/README.txt
+++ b/README.txt
@@ -7,22 +7,10 @@
* D15 is mapped to pin number 38. This is to retain compatiblity with the
* Arduino API, where digitalWrite() on pins 14-19 map to analog A0-A5
*
- * Fix serial/timer
- * Add external itnerrupts
- * Redo serial api
- *
- * Order some shields
- * buy some toner
- * LARW BOOK
- *
- *
- * wtf is smba/smbal?
- * serial.print
- *
- * 5v tolerance
*
* TODO:
* Using OSC32_IN/OSC32_OUT pins as GPIO ports PC14/PC15 152/995
+ * Runtime check for AF collisions on pins (eg serial and pwm).
* */
/* 51 GPIOs in general
diff --git a/src/lib/gpio.c b/src/lib/gpio.c
index 1e42d4d..f03c4fa 100644
--- a/src/lib/gpio.c
+++ b/src/lib/gpio.c
@@ -23,10 +23,6 @@
* @brief GPIO initialization routine
*/
-#ifndef _GPIO_H_
-#define _GPIO_H_
-
-#endif
#include "libmaple.h"
#include "stm32f10x_rcc.h"
#include "gpio.h"
@@ -36,11 +32,11 @@ void gpio_init(void) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC |
- RCC_APB2Periph_AFIO,
+ RCC_APB2Periph_AFIO,
ENABLE);
}
-void gpio_set_mode(GPIO_Port* port, uint8_t gpio_pin, uint8_t mode) {
+void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, uint8 mode) {
uint32_t tmp;
uint32_t shift = POS(gpio_pin % 8);
GPIOReg CR;
diff --git a/src/lib/gpio.h b/src/lib/gpio.h
index bc9bdde..5e7cf29 100644
--- a/src/lib/gpio.h
+++ b/src/lib/gpio.h
@@ -58,25 +58,17 @@
#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
-
typedef struct {
- volatile uint32_t CRL; // Port configuration register low
- volatile uint32_t CRH; // Port configuration register high
- volatile uint32_t IDR; // Port input data register
- volatile uint32_t ODR; // Port output data register
- volatile uint32_t BSRR; // Port bit set/reset register
- volatile uint32_t BRR; // Port bit reset register
- volatile uint32_t LCKR; // Port configuration lock register
+ volatile uint32 CRL; // Port configuration register low
+ volatile uint32 CRH; // Port configuration register high
+ volatile uint32 IDR; // Port input data register
+ volatile uint32 ODR; // Port output data register
+ volatile uint32 BSRR; // Port bit set/reset register
+ volatile uint32 BRR; // Port bit reset register
+ volatile uint32 LCKR; // Port configuration lock register
} GPIO_Port;
-typedef volatile uint32_t* GPIOReg;
+typedef volatile uint32* GPIOReg;
#define POS_MASK(shift) (~(0xF << shift))
#define POS(val) (val << 2)
@@ -86,9 +78,9 @@ extern "C"{
#endif
void gpio_init(void);
-void gpio_set_mode(GPIO_Port* port, uint8_t gpio_pin, uint8_t mode);
+void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, uint8 mode);
-static inline void gpio_write_bit(GPIO_Port *port, uint8_t gpio_pin, uint8_t val) {
+static inline void gpio_write_bit(GPIO_Port *port, uint8 gpio_pin, uint8 val) {
if (val){
port->BSRR = BIT(gpio_pin);
} else {
diff --git a/src/lib/systick.h b/src/lib/systick.h
index 3d846ef..61789c4 100644
--- a/src/lib/systick.h
+++ b/src/lib/systick.h
@@ -51,7 +51,7 @@ extern "C"{
void systick_init(void);
static inline uint32_t systick_get_count(void) {
- return (uint32_t)SYSTICK_CNT;
+ return (uint32_t)*(volatile uint32*)SYSTICK_CNT;
}
#ifdef __cplusplus
diff --git a/src/lib/timers.c b/src/lib/timers.c
index 2161d84..1e95f41 100644
--- a/src/lib/timers.c
+++ b/src/lib/timers.c
@@ -152,3 +152,40 @@ void timers_disable(void) {
timer->CR1 = 0;
}
}
+
+void timers_disable_channel(uint8 timer_num, uint8 channel) {
+ Timer *timer;
+ switch (timer_num) {
+ case 1:
+ timer = (Timer*)TIMER1_BASE;
+ break;
+ case 2:
+ timer = (Timer*)TIMER2_BASE;
+ break;
+ case 3:
+ timer = (Timer*)TIMER3_BASE;
+ break;
+ case 4:
+ timer = (Timer*)TIMER4_BASE;
+ break;
+ default:
+ ASSERT(0);
+ }
+
+ switch (channel) {
+ case 1:
+ timer->CCER &= ~(0x1);
+ break;
+ case 2:
+ timer->CCER &= ~(0x10);
+ break;
+ case 3:
+ timer->CCER &= ~(0x100);
+ break;
+ case 4:
+ timer->CCER &= ~(0x1000);
+ break;
+ default:
+ ASSERT(0);
+ }
+}
diff --git a/src/lib/timers.h b/src/lib/timers.h
index 9147fd4..18b0afb 100644
--- a/src/lib/timers.h
+++ b/src/lib/timers.h
@@ -117,6 +117,7 @@ typedef volatile uint32_t* TimerCCR;
* */
void timer_init(uint8_t, uint16_t);
void timers_disable(void);
+void timers_disable_channel(uint8, uint8);
/* 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.h b/src/lib/usart.h
index 4d0c586..b9efdd5 100644
--- a/src/lib/usart.h
+++ b/src/lib/usart.h
@@ -26,81 +26,6 @@
#ifndef _USART_H_
#define _USART_H_
-/* Transmit procedure:
- * 1. Enable the USART by writing the UE bit in USART_CR1 register to 1.
- *
- * 2. Program the M bit in USART_CR1 to define the word length.
- *
- * 3. Program the number of stop bits in USART_CR2.
- *
- * 4. Select DMA enable (DMAT) in USART_CR3 if Multi buffer Communication is
- * to take place. Configure the DMA register as explained in multibuffer
- * communication.
- *
- * 5. Select the desired baud rate using the USART_BRR register.
- *
- * 6. Set the TE bit in USART_CR1 to send an idle frame as first transmission.
- *
- * 7. Write the data to send in the USART_DR register (this clears the TXE
- * bit). Repeat this for each data to be transmitted in case of single buffer.
- *
- * 8. After writing the last data into the USART_DR register, wait until TC=1.
- * This indicates that the transmission of the last frame is complete. This is
- * required for instance when the USART is disabled or enters the Halt mode to
- * avoid corrupting the last transmission.
- *
- * Single byte communication
- * Clearing the TXE bit is always performed by a write to the data register.
- *
- * The TXE bit is set by hardware and it indicates:
- * ? The data has been moved from TDR to the shift register and the data transmission has
- * started.
- * ? The TDR register is empty.
- * ? The next data can be written in the USART_DR register without overwriting the
- * previous data.
- * This flag generates an interrupt if the TXEIE bit is set.
- *
- * When a transmission is taking place, a write instruction to the USART_DR
- * register stores the data in the TDR register and which is copied in the
- * shift register at the end of the current transmission.
- *
- * When no transmission is taking place, a write instruction to the USART_DR
- * register places the data directly in the shift register, the data
- * transmission starts, and the TXE bit is immediately set.
- *
- * If a frame is transmitted (after the stop bit) and the TXE bit is set, the
- * TC bit goes high. An interrupt is generated if the TCIE bit is set in the
- * USART_CR1 register. After writing the last data into the USART_DR register,
- * it is mandatory to wait for TC=1 before disabling the USART or causing the
- * microcontroller to enter the low power mode (see Figure 241: TC/TXE behavior
- * when transmitting).
- *
- * Clearing the TC bit is performed by the following software sequence:
- * 1. A read from the USART_SR register
- * 2. A write to the USART_DR register
- *
- *
- * For now, use 8N1
- *
- * Baud rate is generated by programming the mantissa and fraction values of
- * USARTDIV
- *
- * baud = fck / 16*USARTDIV
- * Fck = PLK1 for USART2 and USART3 = 36MHz
- * Fck = PCLK2 for USART1 = 72MHz
- *
- * Baud Actual USARTDIV_36MHZ Error USARTDIV_72MHZ Error
- * 2400 2.400 937.5 0% 1875 0%
- * 9600 9.600 234.375 0% 468.75 0%
- * 19200 19.2 117.1875 0% 234.375 0%
- * 57600 57.6 39.0625 0% 78.125 0.%
- * 115200 115.384 19.5 0.15% 39.0625 0%
- * 230400 230.769 9.75 0.16% 19.5 0.16%
- * 460800 461.538 4.875 0.16% 9.75 0.16%
- * 921600 923.076 2.4375 0.16% 4.875 0.16%
- * 225000 2250 1 0% 2 0%
- *
- * */
#define NR_USARTS 0x3
#ifdef __cplusplus
diff --git a/src/main.cpp b/src/main.cpp
index cf79329..8c90b7d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3,9 +3,6 @@
#include "math.h"
#include "usb.h"
-void setup();
-void loop();
-
int ledPin = 13;
uint8_t bytes_in;
@@ -26,6 +23,7 @@ void setup()
pinMode(6, PWM);
pwmWrite(6, 0x8000);
+ pinMode(7, OUTPUT);
Serial2.println("setup end");
@@ -37,8 +35,9 @@ void setup()
int toggle = 0;
-char* testMsg = "0123456\n";
-void loop() {
+const char* testMsg = "hello world!\n";
+
+static inline void loop() {
toggle ^= 1;
digitalWrite(ledPin, toggle);
delay(1000);
diff --git a/src/wiring/comm/HardwareSerial.cpp b/src/wiring/comm/HardwareSerial.cpp
index 84eb4c7..3d0a0ce 100644
--- a/src/wiring/comm/HardwareSerial.cpp
+++ b/src/wiring/comm/HardwareSerial.cpp
@@ -27,6 +27,7 @@
#include "HardwareSerial.h"
#include "usart.h"
#include "gpio.h"
+#include "timers.h"
#define USART1_TX_PORT GPIOA_BASE
#define USART1_TX_PIN 9
@@ -75,6 +76,8 @@ void HardwareSerial::begin(uint32_t baud) {
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);
+ /* Turn off any pwm */
+ timers_disable_channel(2, 3);
break;
case 3:
gpio_set_mode(USART3_TX_PORT, USART3_TX_PIN, GPIO_MODE_AF_OUTPUT_PP);
diff --git a/src/wiring/time.c b/src/wiring/time.c
index 1a91b5e..164d978 100644
--- a/src/wiring/time.c
+++ b/src/wiring/time.c
@@ -28,7 +28,7 @@
#include "time.h"
#define CYCLES_PER_MICROSECOND 72
-#define THE_SECRET_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING 42
+#define FUDGE 42
extern volatile uint32_t systick_timer_millis;
@@ -47,26 +47,13 @@ void delay(unsigned long ms)
}
-#define MAGIC 4096
-/* HZ = 1000
- * n HZ*/
+
+#if 1
void delayMicroseconds(uint32_t us) {
uint32_t target;
uint32_t last, cur, count;
-
-#if 0
- asm volatile("mov r0, %[count] \n\t"
-"1: \n\t"
- "subs r0, r0, #1 \n\t"
- "bne 1b"
- :
- : [count] "r" (count)
- : "r0", "cc");
-#endif
-
-#if 1
/* fudge factor hacky hack hack for function overhead */
- target = us * CYCLES_PER_MICROSECOND - THE_SECRET_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING;
+ target = us * CYCLES_PER_MICROSECOND - FUDGE;
/* Get current count */
last = systick_get_count();
@@ -81,5 +68,5 @@ void delayMicroseconds(uint32_t us) {
}
last = cur;
}
-#endif
}
+#endif
diff --git a/src/wiring/time.h b/src/wiring/time.h
index a97310a..68b3901 100644
--- a/src/wiring/time.h
+++ b/src/wiring/time.h
@@ -41,6 +41,20 @@ void delay(unsigned long ms);
/* Delay for us microseconds */
void delayMicroseconds(uint32_t us);
+#if 0
+static inline void delay_us(uint32 us) {
+ us *= 12;
+ asm volatile("mov r0, %[us] \n\t"
+ "subs r0, #2 \n\t"
+"1: \n\t"
+ "subs r0, r0, #1 \n\t"
+ "bne 1b"
+ :
+ : [us] "r" (us)
+ : "r0", "cc");
+
+}
+#endif
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/src/wiring/wiring.c b/src/wiring/wiring.c
index cecca20..04de78a 100644
--- a/src/wiring/wiring.c
+++ b/src/wiring/wiring.c
@@ -47,13 +47,12 @@ void init(void) {
gpio_init();
- /* off for debug */
-// adc_init();
+ adc_init();
timer_init(1, 1);
-// timer_init(2, 1);
-// timer_init(3, 1);
-// timer_init(4, 1);
+ timer_init(2, 1);
+ timer_init(3, 1);
+ timer_init(4, 1);
}
void NVIC_Configuration(void) {