aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@mit.edu>2010-10-14 23:31:33 -0400
committerMarti Bolivar <mbolivar@mit.edu>2010-10-14 23:31:33 -0400
commit8bcd7de4fff752f173a253026e6c671bdad03505 (patch)
tree61adef4ade428dec8597ed9dc48d1591532bda04
parentd8ec48c9312d87d8c358e32550f950fa851c0599 (diff)
parentaa7a43efce35fa41d57f9858ee41be0c33e84709 (diff)
downloadlibrambutan-8bcd7de4fff752f173a253026e6c671bdad03505.tar.gz
librambutan-8bcd7de4fff752f173a253026e6c671bdad03505.zip
Merge branch 'master' of github.com:leaflabs/libmaple
-rw-r--r--libmaple/timers.c4
-rw-r--r--libmaple/timers.h54
-rw-r--r--wirish/boards.h84
-rw-r--r--wirish/pwm.c4
-rw-r--r--wirish/wirish_digital.c16
5 files changed, 88 insertions, 74 deletions
diff --git a/libmaple/timers.c b/libmaple/timers.c
index 5b97e20..334ec0b 100644
--- a/libmaple/timers.c
+++ b/libmaple/timers.c
@@ -103,19 +103,15 @@ void timer_init(uint8 timer_num, uint16 prescale) {
* we'll worry about that later. */
timer->CCR1 = 0x8FFF; // PWM start value
timer->CCMR1 |= 0x68; // PWM mode 1, enable preload register.
- timer->CCER |= 0x001; // enable ch
timer->CCR2 = 0x8FFF; // PWM start value
timer->CCMR1 |= (0x68 << 8);// PWM mode 1, enable preload register.
- timer->CCER |= 0x010; // enable ch
timer->CCR3 = 0x8FFF; // PWM start value
timer->CCMR2 |= 0x68; // PWM mode 1, enable preload register.
- timer->CCER |= 0x100; // enable ch
timer->CCR4 = 0x8FFF; // PWM start value
timer->CCMR2 |= (0x68 << 8);// PWM mode 1, enable preload register.
- timer->CCER |= 0x1000; // enable ch
/* Advanced timer? */
if (is_advanced) {
diff --git a/libmaple/timers.h b/libmaple/timers.h
index cbdf088..ba8245c 100644
--- a/libmaple/timers.h
+++ b/libmaple/timers.h
@@ -98,39 +98,39 @@ typedef volatile uint32* TimerCCR;
#define TIMER_CCR(NUM,CHAN) TIMER ## NUM ## _CH ## CHAN ## _CRR
-#define TIMER1_CH1_CCR (TimerCCR)(TIMER1_BASE + 0x34)
-#define TIMER1_CH2_CCR (TimerCCR)(TIMER1_BASE + 0x38)
-#define TIMER1_CH3_CCR (TimerCCR)(TIMER1_BASE + 0x3C)
-#define TIMER1_CH4_CCR (TimerCCR)(TIMER1_BASE + 0x40)
-
-#define TIMER2_CH1_CCR (TimerCCR)(TIMER2_BASE + 0x34)
-#define TIMER2_CH2_CCR (TimerCCR)(TIMER2_BASE + 0x38)
-#define TIMER2_CH3_CCR (TimerCCR)(TIMER2_BASE + 0x3C)
-#define TIMER2_CH4_CCR (TimerCCR)(TIMER2_BASE + 0x40)
-
-#define TIMER3_CH1_CCR (TimerCCR)(TIMER3_BASE + 0x34)
-#define TIMER3_CH2_CCR (TimerCCR)(TIMER3_BASE + 0x38)
-#define TIMER3_CH3_CCR (TimerCCR)(TIMER3_BASE + 0x3C)
-#define TIMER3_CH4_CCR (TimerCCR)(TIMER3_BASE + 0x40)
-
-#define TIMER4_CH1_CCR (TimerCCR)(TIMER4_BASE + 0x34)
-#define TIMER4_CH2_CCR (TimerCCR)(TIMER4_BASE + 0x38)
-#define TIMER4_CH3_CCR (TimerCCR)(TIMER4_BASE + 0x3C)
-#define TIMER4_CH4_CCR (TimerCCR)(TIMER4_BASE + 0x40)
+#define TIMER1_CH1_CCR TIMER1_BASE + 0x34
+#define TIMER1_CH2_CCR TIMER1_BASE + 0x38
+#define TIMER1_CH3_CCR TIMER1_BASE + 0x3C
+#define TIMER1_CH4_CCR TIMER1_BASE + 0x40
+
+#define TIMER2_CH1_CCR TIMER2_BASE + 0x34
+#define TIMER2_CH2_CCR TIMER2_BASE + 0x38
+#define TIMER2_CH3_CCR TIMER2_BASE + 0x3C
+#define TIMER2_CH4_CCR TIMER2_BASE + 0x40
+
+#define TIMER3_CH1_CCR TIMER3_BASE + 0x34
+#define TIMER3_CH2_CCR TIMER3_BASE + 0x38
+#define TIMER3_CH3_CCR TIMER3_BASE + 0x3C
+#define TIMER3_CH4_CCR TIMER3_BASE + 0x40
+
+#define TIMER4_CH1_CCR TIMER4_BASE + 0x34
+#define TIMER4_CH2_CCR TIMER4_BASE + 0x38
+#define TIMER4_CH3_CCR TIMER4_BASE + 0x3C
+#define TIMER4_CH4_CCR TIMER4_BASE + 0x40
/* Timer5 and Timer8 are in high-density devices only (such as Maple
Native). Timer6 and Timer7 in these devices have no output compare
pins. */
-#define TIMER5_CH1_CCR (TimerCCR)(TIMER5_BASE + 0x34)
-#define TIMER5_CH2_CCR (TimerCCR)(TIMER5_BASE + 0x38)
-#define TIMER5_CH3_CCR (TimerCCR)(TIMER5_BASE + 0x3C)
-#define TIMER5_CH4_CCR (TimerCCR)(TIMER5_BASE + 0x40)
+#define TIMER5_CH1_CCR TIMER5_BASE + 0x34
+#define TIMER5_CH2_CCR TIMER5_BASE + 0x38
+#define TIMER5_CH3_CCR TIMER5_BASE + 0x3C
+#define TIMER5_CH4_CCR TIMER5_BASE + 0x40
-#define TIMER8_CH1_CCR (TimerCCR)(TIMER8_BASE + 0x34)
-#define TIMER8_CH2_CCR (TimerCCR)(TIMER8_BASE + 0x38)
-#define TIMER8_CH3_CCR (TimerCCR)(TIMER8_BASE + 0x3C)
-#define TIMER8_CH4_CCR (TimerCCR)(TIMER8_BASE + 0x40)
+#define TIMER8_CH1_CCR TIMER8_BASE + 0x34
+#define TIMER8_CH2_CCR TIMER8_BASE + 0x38
+#define TIMER8_CH3_CCR TIMER8_BASE + 0x3C
+#define TIMER8_CH4_CCR TIMER8_BASE + 0x40
#define TIMER_DISABLED 0
#define TIMER_PWM 1
diff --git a/wirish/boards.h b/wirish/boards.h
index eed3e26..fed5ead 100644
--- a/wirish/boards.h
+++ b/wirish/boards.h
@@ -57,15 +57,17 @@ enum {
ADC12, ADC13, ADC14, ADC15, ADC16, ADC17, ADC18, ADC19, ADC20, };
#define ADC_INVALID 0xFFFFFFFF
-#define TIMER_INVALID (TimerCCR)0xFFFFFFFF
+#define TIMER_INVALID 0xFFFFFFFF
/* Types used for the tables below */
typedef struct PinMapping {
GPIO_Port *port;
uint32 pin;
uint32 adc;
- TimerCCR timer_channel;
+ uint32 timer_channel;
uint32 exti_port;
+ uint32 timer_num;
+ uint32 timer_chan;
} PinMapping;
/* LeafLabs Maple rev3, rev4 */
@@ -76,89 +78,89 @@ typedef struct PinMapping {
static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = {
/* D0/PA3 */
- {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA},
+ {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA, TIMER2, 4},
/* D1/PA2 */
- {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA},
+ {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA, TIMER2, 3},
/* D2/PA0 */
- {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA},
+ {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA, TIMER2, 1},
/* D3/PA1 */
- {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA},
+ {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2},
/* D4/PB5 */
- {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D5/PB6 */
- {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1},
/* D6/PA8 */
- {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTA},
+ {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTA, TIMER1, 1},
/* D7/PA9 */
- {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA},
+ {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA, TIMER1, 2},
/* D8/PA10 */
- {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA},
+ {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA, TIMER1, 3},
/* D9/PB7 */
- {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 2},
/* D10/PA4 */
- {GPIOA_BASE, 4, ADC4, TIMER_INVALID, EXTI_CONFIG_PORTA},
+ {GPIOA_BASE, 4, ADC4, TIMER_INVALID, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
/* D11/PA7 */
- {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA},
+ {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2},
/* D12/PA6 */
- {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA},
+ {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1},
/* D13/PA5 */
- {GPIOA_BASE, 5, ADC5, TIMER_INVALID, EXTI_CONFIG_PORTA},
+ {GPIOA_BASE, 5, ADC5, TIMER_INVALID, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
/* D14/PB8 */
- {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR, EXTI_CONFIG_PORTB, TIMER4, 3},
/* Little header */
/* D15/PC0 */
- {GPIOC_BASE, 0, ADC10, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 0, ADC10, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D16/PC1 */
- {GPIOC_BASE, 1, ADC11, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 1, ADC11, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D17/PC2 */
- {GPIOC_BASE, 2, ADC12, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 2, ADC12, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D18/PC3 */
- {GPIOC_BASE, 3, ADC13, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 3, ADC13, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D19/PC4 */
- {GPIOC_BASE, 4, ADC14, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 4, ADC14, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D20/PC5 */
- {GPIOC_BASE, 5, ADC15, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 5, ADC15, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* External header */
/* D21/PC13 */
- {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D22/PC14 */
- {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D23/PC15 */
- {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D24/PB9 */
- {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D25/PD2 */
- {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTD},
+ {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID},
/* D26/PC10 */
- {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D27/PB0 */
- {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3},
/* D28/PB1 */
- {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4},
/* D29/PB10 */
- {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D30/PB11 */
- {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D31/PB12 */
- {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D32/PB13 */
- {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D33/PB14 */
- {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D34/PB15 */
- {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB},
+ {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D35/PC6 */
- {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D36/PC7 */
- {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D37/PC8 */
- {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC},
+ {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* PC9 (BUT) */
- {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}
+ {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}
};
#endif
diff --git a/wirish/pwm.c b/wirish/pwm.c
index 2f555ab..0bf27aa 100644
--- a/wirish/pwm.c
+++ b/wirish/pwm.c
@@ -38,9 +38,9 @@ void pwmWrite(uint8 pin, uint16 duty_cycle) {
return;
}
- ccr = PIN_MAP[pin].timer_channel;
+ ccr = (TimerCCR)(PIN_MAP[pin].timer_channel);
- if (ccr == TIMER_INVALID) {
+ if (ccr == (TimerCCR)TIMER_INVALID) {
return;
}
diff --git a/wirish/wirish_digital.c b/wirish/wirish_digital.c
index f4868da..9298b60 100644
--- a/wirish/wirish_digital.c
+++ b/wirish/wirish_digital.c
@@ -31,6 +31,7 @@
void pinMode(uint8 pin, WiringPinMode mode) {
uint8 outputMode;
+ uint32 pwm = 0;
if (pin >= NR_GPIO_PINS) {
return;
@@ -58,9 +59,11 @@ void pinMode(uint8 pin, WiringPinMode mode) {
break;
case PWM:
outputMode = GPIO_MODE_AF_OUTPUT_PP;
+ pwm = 1;
break;
case PWM_OPEN_DRAIN:
outputMode = GPIO_MODE_AF_OUTPUT_OD;
+ pwm = 1;
break;
default:
ASSERT(0);
@@ -68,6 +71,19 @@ void pinMode(uint8 pin, WiringPinMode mode) {
}
gpio_set_mode(PIN_MAP[pin].port, PIN_MAP[pin].pin, outputMode);
+
+ if (PIN_MAP[pin].timer_num != TIMER_INVALID) {
+ /* enable/disable timer channels if we're switching into or out of pwm */
+ if (pwm) {
+ timer_set_mode(PIN_MAP[pin].timer_num,
+ PIN_MAP[pin].timer_chan,
+ TIMER_PWM);
+ } else {
+ timer_set_mode(PIN_MAP[pin].timer_num,
+ PIN_MAP[pin].timer_chan,
+ TIMER_DISABLED);
+ }
+ }
}