aboutsummaryrefslogtreecommitdiffstats
path: root/wirish
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@mit.edu>2010-12-08 23:39:37 -0500
committerMarti Bolivar <mbolivar@mit.edu>2010-12-08 23:39:37 -0500
commitb67d281d85bd59a9738a9a43c4db1027f81d9208 (patch)
tree1940b4743a945160d21eb37c8578fa46e9118d4e /wirish
parentb34f826ae1470aaa791bd8ed8dd66ccd4d96d82c (diff)
downloadlibrambutan-b67d281d85bd59a9738a9a43c4db1027f81d9208.tar.gz
librambutan-b67d281d85bd59a9738a9a43c4db1027f81d9208.zip
Servo library tested and debugged.
Some additional HardwareTimer methods introduced to make this convenient; ancillary libmaple/timers.h changes resulted.
Diffstat (limited to 'wirish')
-rw-r--r--wirish/HardwareTimer.cpp150
-rw-r--r--wirish/HardwareTimer.h176
-rw-r--r--wirish/boards.h101
-rw-r--r--wirish/comm/HardwareSerial.cpp11
-rw-r--r--wirish/comm/HardwareSerial.h6
-rw-r--r--wirish/pwm.c4
-rw-r--r--wirish/time.h6
-rw-r--r--wirish/wirish.c2
-rw-r--r--wirish/wirish_math.cpp5
-rw-r--r--wirish/wirish_math.h5
10 files changed, 289 insertions, 177 deletions
diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp
index 5b80ec1..92c6adf 100644
--- a/wirish/HardwareTimer.cpp
+++ b/wirish/HardwareTimer.cpp
@@ -29,13 +29,10 @@
#include "wirish.h"
#include "HardwareTimer.h"
-HardwareTimer::HardwareTimer(uint8 timerNum) {
- ASSERT(timerNum <= NR_TIMERS && timerNum != 6 && timerNum != 7);
+HardwareTimer::HardwareTimer(timer_dev_num timerNum) {
+ ASSERT(timerNum != TIMER_INVALID);
this->timerNum = timerNum;
-
- // Need to remember over flow for bounds checking
- this->overflow = 0xFFFF;
}
void HardwareTimer::resume(void) {
@@ -46,122 +43,158 @@ void HardwareTimer::pause(void) {
timer_pause(this->timerNum);
}
+uint16 HardwareTimer::getPrescaleFactor(void) {
+ return timer_get_prescaler(this->timerNum) + 1;
+}
+
void HardwareTimer::setPrescaleFactor(uint16 factor) {
// The prescaler register is zero-indexed
timer_set_prescaler(this->timerNum, factor-1);
}
-void HardwareTimer::setOverflow(uint16 val) {
- this->overflow = val;
- timer_set_reload(this->timerNum, val);
+uint16 HardwareTimer::getOverflow() {
+ return timer_get_reload(this->timerNum);
}
-void HardwareTimer::setCount(uint16 val) {
- if(val > this->overflow) {
- val = this->overflow;
- }
- timer_set_count(this->timerNum, val);
+void HardwareTimer::setOverflow(uint16 val) {
+ timer_set_reload(this->timerNum, val);
}
uint16 HardwareTimer::getCount(void) {
return timer_get_count(this->timerNum);
}
-uint16 HardwareTimer::setPeriod(uint32 microseconds) {
- // XXX: 72MHz shouldn't be hard coded in here... global define?
+void HardwareTimer::setCount(uint16 val) {
+ uint16 ovf = this->getOverflow();
+ timer_set_count(this->timerNum, min(val, ovf));
+}
+uint16 HardwareTimer::setPeriod(uint32 microseconds) {
// Not the best way to handle this edge case?
if(!microseconds) {
setPrescaleFactor(1);
setOverflow(1);
- return this->overflow;
+ return this->getOverflow();
}
+ uint32 cycles = microseconds * CYCLES_PER_MICROSECOND;
- // With a prescale factor of 1, there are 72counts/ms
- uint16 ps = ((microseconds*72)/65536) + 1;
+ // With a prescale factor of 1, there are CYCLES_PER_MICROSECOND
+ // counts/ms
+ uint16 ps = (uint16)((cycles >> 16) + 1);
setPrescaleFactor(ps);
// Finally, this overflow will always be less than 65536
- setOverflow(((microseconds*72)/ps) - 1);
- return this->overflow;
+ setOverflow((cycles/ps) - 1);
+
+ return this->getOverflow();
+}
+
+inline void HardwareTimer::setChannelMode(int channel, TimerMode mode) {
+ timer_set_mode(this->timerNum, channel, mode);
}
void HardwareTimer::setChannel1Mode(TimerMode mode) {
- timer_set_mode(this->timerNum,1,mode);
+ this->setChannelMode(1, mode);
}
void HardwareTimer::setChannel2Mode(TimerMode mode) {
- timer_set_mode(this->timerNum,2,mode);
+ this->setChannelMode(2, mode);
}
void HardwareTimer::setChannel3Mode(TimerMode mode) {
- timer_set_mode(this->timerNum,3,mode);
+ this->setChannelMode(3, mode);
}
void HardwareTimer::setChannel4Mode(TimerMode mode) {
- timer_set_mode(this->timerNum,4,mode);
+ this->setChannelMode(4, mode);
+}
+
+inline uint16 HardwareTimer::getCompare(int channel) {
+ return timer_get_compare_value(this->timerNum, channel);
+}
+
+uint16 HardwareTimer::getCompare1() {
+ return this->getCompare(1);
+}
+
+uint16 HardwareTimer::getCompare2() {
+ return this->getCompare(2);
+}
+
+uint16 HardwareTimer::getCompare3() {
+ return this->getCompare(3);
+}
+
+uint16 HardwareTimer::getCompare4() {
+ return this->getCompare(4);
+}
+
+inline void HardwareTimer::setCompare(int channel, uint16 val) {
+ uint16 ovf = this->getOverflow();
+ timer_set_compare_value(this->timerNum, channel, min(val, ovf));
}
void HardwareTimer::setCompare1(uint16 val) {
- if(val > this->overflow) {
- val = this->overflow;
- }
- timer_set_compare_value(this->timerNum,1,val);
+ this->setCompare(1, val);
}
void HardwareTimer::setCompare2(uint16 val) {
- if(val > this->overflow) {
- val = this->overflow;
- }
- timer_set_compare_value(this->timerNum,2,val);
+ this->setCompare(2, val);
}
void HardwareTimer::setCompare3(uint16 val) {
- if(val > this->overflow) {
- val = this->overflow;
- }
- timer_set_compare_value(this->timerNum,3,val);
+ this->setCompare(3, val);
}
void HardwareTimer::setCompare4(uint16 val) {
- if(val > this->overflow) {
- val = this->overflow;
- }
- timer_set_compare_value(this->timerNum,4,val);
+ this->setCompare(4, val);
+}
+
+inline void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) {
+ timer_attach_interrupt(this->timerNum, channel, handler);
}
void HardwareTimer::attachCompare1Interrupt(voidFuncPtr handler) {
- timer_attach_interrupt(this->timerNum,1,handler);
+ this->attachInterrupt(1, handler);
}
void HardwareTimer::attachCompare2Interrupt(voidFuncPtr handler) {
- timer_attach_interrupt(this->timerNum,2,handler);
+ this->attachInterrupt(2, handler);
}
void HardwareTimer::attachCompare3Interrupt(voidFuncPtr handler) {
- timer_attach_interrupt(this->timerNum,3,handler);
+ this->attachInterrupt(3, handler);
}
void HardwareTimer::attachCompare4Interrupt(voidFuncPtr handler) {
- timer_attach_interrupt(this->timerNum,4,handler);
+ this->attachInterrupt(4, handler);
+}
+
+inline void HardwareTimer::detachInterrupt(int channel) {
+ timer_detach_interrupt(this->timerNum, channel);
}
void HardwareTimer::detachCompare1Interrupt(void) {
- timer_detach_interrupt(this->timerNum,1);
+ this->detachInterrupt(1);
}
void HardwareTimer::detachCompare2Interrupt(void) {
- timer_detach_interrupt(this->timerNum,2);
+ this->detachInterrupt(2);
}
void HardwareTimer::detachCompare3Interrupt(void) {
- timer_detach_interrupt(this->timerNum,3);
+ this->detachInterrupt(3);
}
void HardwareTimer::detachCompare4Interrupt(void) {
- timer_detach_interrupt(this->timerNum,4);
+ this->detachInterrupt(4);
+}
+
+void HardwareTimer::generateUpdate(void) {
+ timer_generate_update(this->timerNum);
}
+
HardwareTimer Timer1(TIMER1);
HardwareTimer Timer2(TIMER2);
HardwareTimer Timer3(TIMER3);
@@ -171,3 +204,24 @@ HardwareTimer Timer5(TIMER5); // High-density devices only
HardwareTimer Timer8(TIMER8); // High-density devices only
#endif
+HardwareTimer* getTimer(timer_dev_num timerNum) {
+ switch (timerNum) {
+ case TIMER1:
+ return &Timer1;
+ case TIMER2:
+ return &Timer2;
+ case TIMER3:
+ return &Timer3;
+ case TIMER4:
+ return &Timer4;
+#if NR_TIMERS >= 8
+ case TIMER5:
+ return &Timer5;
+ case TIMER8:
+ return &Timer8;
+#endif
+ default:
+ ASSERT(0);
+ return 0;
+ }
+}
diff --git a/wirish/HardwareTimer.h b/wirish/HardwareTimer.h
index b05085f..c72175f 100644
--- a/wirish/HardwareTimer.h
+++ b/wirish/HardwareTimer.h
@@ -26,8 +26,10 @@
* @brief wirish timer class to manage the four 16-bit timer peripherals
*/
-#ifndef _TIMER_H_
-#define _TIMER_H_
+#ifndef _HARDWARETIMER_H_
+#define _HARDWARETIMER_H_
+
+#include "timers.h"
/**
* Interface to one of the 16-bit timer peripherals.
@@ -51,11 +53,16 @@
*/
class HardwareTimer {
private:
- uint16 overflow;
- uint8 timerNum;
+ timer_dev_num timerNum;
public:
- HardwareTimer(uint8 timer_num);
+ HardwareTimer(timer_dev_num timer_num);
+
+ /**
+ * Return this timer's device number. For example,
+ * Timer1.getTimerNum() == TIMER1
+ */
+ timer_dev_num getTimerNum() { return timerNum; }
/**
* Stop the counter, without affecting its configuration.
@@ -90,6 +97,12 @@ class HardwareTimer {
void resume(void);
/**
+ * Returns the timer's prescale factor.
+ * @see HardwareTimer::setPrescaleFactor()
+ */
+ uint16 getPrescaleFactor();
+
+ /**
* Set the timer prescale.
*
* The prescaler acts as a clock divider to slow down the rate at
@@ -112,6 +125,12 @@ class HardwareTimer {
void setPrescaleFactor(uint16 factor);
/**
+ * Gets the timer overflow value.
+ * @see HardwareTimer::setOverflow()
+ */
+ uint16 getOverflow();
+
+ /**
* Sets the timer overflow (or "reload") value.
*
* When the timer's counter reaches this, value it resets to
@@ -122,11 +141,17 @@ class HardwareTimer {
* value for the channel compare values.
*
* @param val The new overflow value to set
- * @see HardwareTimer::setOverflow()
*/
void setOverflow(uint16 val);
/**
+ * Retrieve the current timer count.
+ *
+ * @return The timer's current count value
+ */
+ uint16 getCount(void);
+
+ /**
* Set the current timer count.
*
* Note that there is some function call overhead associated with
@@ -140,13 +165,6 @@ class HardwareTimer {
void setCount(uint16 val);
/**
- * Retrieve the current timer count.
- *
- * @return The timer's current count value
- */
- uint16 getCount(void);
-
- /**
* Configure the prescaler and overflow values to generate a timer
* reload with a period as close to the given number of
* microseconds as possible.
@@ -164,6 +182,18 @@ class HardwareTimer {
uint16 setPeriod(uint32 microseconds);
/**
+ * Set the given channel of this timer to the given mode.
+ *
+ * Note: Timer1.setChannel1Mode(TIMER_PWM) may not work as
+ * expected; if you want PWM functionality on a channel make sure
+ * you don't set it to something else!
+ *
+ * @param channel Timer channel, from 1 to 4
+ * @param mode Mode to set
+ */
+ void setChannelMode(int channel, TimerMode mode);
+
+ /**
* Set channel 1 of this timer to the given mode.
*
* Note: Timer1.setChannel1Mode(TIMER_PWM) may not work as
@@ -193,7 +223,25 @@ class HardwareTimer {
void setChannel4Mode(TimerMode mode);
/**
- * Sets the compare value for channel 1.
+ * Gets the compare value for the given channel.
+ * @see HardwareTimer::setCompare()
+ */
+ uint16 getCompare(int channel);
+
+ /** Like getCompare(1) */
+ uint16 getCompare1();
+
+ /** Like getCompare(2) */
+ uint16 getCompare2();
+
+ /** Like getCompare(3) */
+ uint16 getCompare3();
+
+ /** Like getCompare(4) */
+ uint16 getCompare4();
+
+ /**
+ * Sets the compare value for the given channel.
*
* When the counter reaches this value the interrupt for this
* channel will fire if channel 1 mode is TIMER_OUTPUTCOMPARE and
@@ -210,49 +258,40 @@ class HardwareTimer {
* overheads mean that the smallest increment rate is at least a
* few microseconds.
*
+ * @param channel the channel whose compare to set, from 1 to 4.
* @param val The compare value to set. If greater than this
* timer's overflow value, it will be truncated to the
* overflow value.
*
* @see TimerMode
- * @see HardwareTimer::setChannel1Mode()
+ * @see HardwareTimer::setChannelMode()
*/
- void setCompare1(uint16 val);
+ void setCompare(int channel, uint16 compare);
/**
- * Sets the compare value for channel 2.
- *
- * @param val The compare value to set. If greater than this
- * timer's overflow value, it will be truncated to the
- * overflow value.
- * @see HardwareTimer::setCompare1()
+ * Like setCompare(1, compare).
*/
- void setCompare2(uint16 val);
+ void setCompare1(uint16 compare);
/**
- * Sets the compare value for channel 3.
- *
- * @param val The compare value to set. If greater than this
- * timer's overflow value, it will be truncated to the
- * overflow value.
- * @see HardwareTimer::setCompare1()
+ * Like setCompare(2, compare).
*/
- void setCompare3(uint16 val);
+ void setCompare2(uint16 compare);
/**
- * Sets the compare value for channel 4.
- *
- * @param val The compare value to set. If greater than this
- * timer's overflow value, it will be truncated to the
- * overflow value.
- * @see HardwareTimer::setCompare1()
+ * Like setCompare(3, compare).
+ */
+ void setCompare3(uint16 compare);
+
+ /**
+ * Like setCompare(4, compare).
*/
- void setCompare4(uint16 val);
+ void setCompare4(uint16 compare);
/**
- * Attach an interrupt handler to this timer's channel 1. This
+ * Attach an interrupt handler to the given channel. This
* interrupt handler will be called when the timer's counter
- * reaches its channel 1 compare value.
+ * reaches the given channel compare value.
*
* The argument should be a function which takes no arguments and
* has no return value; i.e. it should have signature
@@ -267,56 +306,75 @@ class HardwareTimer {
* if you have a delay() in your interrupt routine, you're probably
* doing it wrong.
*
- * @param handler The ISR to attach to channel 1.
+ * @param channel the channel to attach the ISR to, from 1 to 4.
+ * @param handler The ISR to attach to the given channel.
* @see voidFuncPtr
*/
+ void attachInterrupt(int channel, voidFuncPtr handler);
+
+ /**
+ * Like attachCompareInterrupt(1, handler).
+ * @see HardwareTimer::attachCompareInterrupt()
+ */
void attachCompare1Interrupt(voidFuncPtr handler);
/**
- * Like attachCompare1Interrupt(), but for channel 2.
- * @see HardwareTimer::attachCompare1Interrupt()
+ * Like attachCompareInterrupt(2, handler).
+ * @see HardwareTimer::attachCompareInterrupt()
*/
void attachCompare2Interrupt(voidFuncPtr handler);
/**
- * Like attachCompare1Interrupt(), but for channel 3.
- * @see HardwareTimer::attachCompare1Interrupt()
+ * Like attachCompareInterrupt(3, handler).
+ * @see HardwareTimer::attachCompareInterrupt()
*/
void attachCompare3Interrupt(voidFuncPtr handler);
/**
- * Like attachCompare1Interrupt(), but for channel 4.
- * @see HardwareTimer::attachCompare1Interrupt()
+ * Like attachCompareInterrupt(4, handler).
+ * @see HardwareTimer::attachCompareInterrupt()
*/
void attachCompare4Interrupt(voidFuncPtr handler);
/**
- * Remove the interrupt handler attached to channel 1, if any.
- * The handler will no longer be called by this timer.
- * @see HardwareTimer::attachCompare1Interrupt()
+ * Remove the interrupt handler attached to the given channel, if
+ * any. The handler will no longer be called by this timer.
+ *
+ * @param channel the channel whose interrupt to detach, from 1 to 4.
+ * @see HardwareTimer::attachInterrupt()
+ */
+ void detachInterrupt(int channel);
+
+ /**
+ * Like detachInterrupt(1).
+ * @see HardwareTimer::detachInterrupt()
*/
void detachCompare1Interrupt(void);
/**
- * Remove the interrupt handler attached to channel 2, if any.
- * The handler will no longer be called by this timer.
- * @see HardwareTimer::attachCompare1Interrupt()
+ * Like detachInterrupt(2).
+ * @see HardwareTimer::detachInterrupt()
*/
void detachCompare2Interrupt(void);
/**
- * Remove the interrupt handler attached to channel 3, if any.
- * The handler will no longer be called by this timer.
- * @see HardwareTimer::attachCompare1Interrupt()
+ * Like detachInterrupt(3).
+ * @see HardwareTimer::detachInterrupt()
*/
void detachCompare3Interrupt(void);
/**
- * Remove the interrupt handler attached to channel 4, if any.
- * The handler will no longer be called by this timer.
- * @see HardwareTimer::attachCompare1Interrupt()
+ * Like detachInterrupt(4).
+ * @see HardwareTimer::detachInterrupt()
*/
void detachCompare4Interrupt(void);
+
+ /**
+ * Re-initializes the counter (to 0 in upcounting mode, which is
+ * the default), and generates an update of the prescale and
+ * overflow registers.
+ */
+ void generateUpdate(void);
};
/** Pre-instantiated timer for use by user code. */
@@ -336,5 +394,7 @@ extern HardwareTimer Timer5;
extern HardwareTimer Timer8;
#endif
+HardwareTimer* getTimer(timer_dev_num timerNum);
+
#endif
diff --git a/wirish/boards.h b/wirish/boards.h
index 558e1c3..84ff44f 100644
--- a/wirish/boards.h
+++ b/wirish/boards.h
@@ -57,16 +57,15 @@ enum {
ADC12, ADC13, ADC14, ADC15, ADC16, ADC17, ADC18, ADC19, ADC20, };
#define ADC_INVALID 0xFFFFFFFF
-#define TIMER_INVALID 0xFFFFFFFF
/* Types used for the tables below */
typedef struct PinMapping {
GPIO_Port *port;
uint32 pin;
uint32 adc;
- uint32 timer_channel;
+ TimerCCR timer_ccr;
uint32 exti_port;
- uint32 timer_num;
+ timer_dev_num timer_num;
uint32 timer_chan;
} PinMapping;
@@ -74,7 +73,7 @@ typedef struct PinMapping {
#ifdef BOARD_maple
#define CYCLES_PER_MICROSECOND 72
- #define MAPLE_RELOAD_VAL 71999 /* takes a cycle to reload */
+ #define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */
#define BOARD_BUTTON_PIN 38
#define BOARD_LED_PIN 13
@@ -89,7 +88,7 @@ typedef struct PinMapping {
/* D3/PA1 */
{GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2},
/* D4/PB5 */
- {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D5/PB6 */
{GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1},
/* D6/PA8 */
@@ -101,69 +100,69 @@ typedef struct PinMapping {
/* D9/PB7 */
{GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 2},
/* D10/PA4 */
- {GPIOA_BASE, 4, ADC4, TIMER_INVALID, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
+ {GPIOA_BASE, 4, ADC4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
/* D11/PA7 */
{GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2},
/* D12/PA6 */
{GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1},
/* D13/PA5 */
- {GPIOA_BASE, 5, ADC5, TIMER_INVALID, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
+ {GPIOA_BASE, 5, ADC5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
/* D14/PB8 */
{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, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 0, ADC10, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D16/PC1 */
- {GPIOC_BASE, 1, ADC11, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 1, ADC11, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D17/PC2 */
- {GPIOC_BASE, 2, ADC12, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 2, ADC12, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D18/PC3 */
- {GPIOC_BASE, 3, ADC13, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 3, ADC13, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D19/PC4 */
- {GPIOC_BASE, 4, ADC14, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 4, ADC14, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D20/PC5 */
- {GPIOC_BASE, 5, ADC15, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 5, ADC15, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* External header */
/* D21/PC13 */
- {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D22/PC14 */
- {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D23/PC15 */
- {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D24/PB9 */
{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, TIMER_INVALID, TIMER_INVALID},
+ {GPIOD_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID},
/* D26/PC10 */
- {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D27/PB0 */
- {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3},
+ {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3},
/* D28/PB1 */
- {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4},
+ {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4},
/* D29/PB10 */
- {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D30/PB11 */
- {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D31/PB12 */
- {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D32/PB13 */
- {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D33/PB14 */
- {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D34/PB15 */
- {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D35/PC6 */
- {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D36/PC7 */
- {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 7, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D37/PC8 */
- {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* PC9 (BUT) */
- {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}
+ {GPIOC_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}
};
#define BOARD_INIT do { \
@@ -174,7 +173,7 @@ typedef struct PinMapping {
/* LeafLabs Maple Native (prototype) */
#define CYCLES_PER_MICROSECOND 72
- #define MAPLE_RELOAD_VAL 71999 /* takes a cycle to reload */
+ #define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */
// TODO:
static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = {
@@ -299,14 +298,14 @@ typedef struct PinMapping {
#elif defined(BOARD_maple_mini)
#define CYCLES_PER_MICROSECOND 72
- #define MAPLE_RELOAD_VAL 71999 /* takes a cycle to reload */
+ #define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */
#define BOARD_BUTTON_PIN 32
#define BOARD_LED_PIN 33
static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = {
/* D0/PC15 */
- {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D1/PA0 */
{GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA, TIMER2, 1},
/* D2/PA1 */
@@ -316,9 +315,9 @@ typedef struct PinMapping {
/* D4/PA3 */
{GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA, TIMER2, 4},
/* D5/PA4 */
- {GPIOA_BASE, 4, ADC4, TIMER_INVALID, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
+ {GPIOA_BASE, 4, ADC4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
/* D6/PA5 */
- {GPIOA_BASE, 5, ADC5, TIMER_INVALID, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
+ {GPIOA_BASE, 5, ADC5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
/* D7/PA6 */
{GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1},
/* D8/PA7 */
@@ -328,17 +327,17 @@ typedef struct PinMapping {
/* D10/PB1 */
{GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4},
/* D11/PB2 */
- {GPIOB_BASE, 2, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D12/PB10 */
- {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D13/PB11 */
- {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D14/PB13 */
- {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D15/PB14 */
- {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D16/PB15 */
- {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D17/PA8 */
{GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTB, TIMER1, 1},
/* D18/PA9 */
@@ -348,31 +347,31 @@ typedef struct PinMapping {
/* D20/PA11 */
{GPIOA_BASE, 11, ADC_INVALID, TIMER1_CH4_CCR, EXTI_CONFIG_PORTA, TIMER1, 4},
/* D21/PA12 */
- {GPIOA_BASE, 12, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
+ {GPIOA_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
/* D22/PA13 */
- {GPIOA_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
+ {GPIOA_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
/* D23/PA14 */
- {GPIOA_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
+ {GPIOA_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
/* D24/PA15 */
- {GPIOA_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
+ {GPIOA_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID},
/* D25/PB3 */
- {GPIOB_BASE, 3, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D26/PB4 */
- {GPIOB_BASE, 4, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D27/PB5 */
- {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
/* D28/PB6 */
{GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1},
/* D29/PB7 */
{GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 1},
/* D30/PC13 */
- {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D31/PC14 */
- {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
+ {GPIOC_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID},
/* D32/PB8 */
{GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR, EXTI_CONFIG_PORTB, TIMER4, 3},
/* D33/PB12 */
- {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
+ {GPIOB_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID},
};
/* since we want the Serial Wire/JTAG pins as GPIOs, disable both
diff --git a/wirish/comm/HardwareSerial.cpp b/wirish/comm/HardwareSerial.cpp
index 425c610..d6c7e82 100644
--- a/wirish/comm/HardwareSerial.cpp
+++ b/wirish/comm/HardwareSerial.cpp
@@ -34,9 +34,9 @@
#include "gpio.h"
#include "timers.h"
-HardwareSerial Serial1(USART1, 4500000UL, GPIOA_BASE, 9, 10, TIMER1, 2);
-HardwareSerial Serial2(USART2, 2250000UL, GPIOA_BASE, 2, 3, TIMER2, 3);
-HardwareSerial Serial3(USART3, 2250000UL, GPIOB_BASE, 10, 11, 0, 0);
+HardwareSerial Serial1(USART1, 4500000UL, GPIOA_BASE, 9,10, TIMER1, 2);
+HardwareSerial Serial2(USART2, 2250000UL, GPIOA_BASE, 2, 3, TIMER2, 3);
+HardwareSerial Serial3(USART3, 2250000UL, GPIOB_BASE, 10,11, TIMER_INVALID, 0);
// TODO: High density device ports
HardwareSerial::HardwareSerial(uint8 usart_num,
@@ -44,7 +44,7 @@ HardwareSerial::HardwareSerial(uint8 usart_num,
GPIO_Port *gpio_port,
uint8 tx_pin,
uint8 rx_pin,
- uint8 timer_num,
+ timer_dev_num timer_num,
uint8 compare_num) {
this->usart_num = usart_num;
this->max_baud = max_baud;
@@ -75,8 +75,7 @@ void HardwareSerial::begin(uint32 baud) {
gpio_set_mode(gpio_port, tx_pin, GPIO_MODE_AF_OUTPUT_PP);
gpio_set_mode(gpio_port, rx_pin, GPIO_MODE_INPUT_FLOATING);
- if ((usart_num == USART1) ||
- (usart_num == USART2)) {
+ if (timer_num != TIMER_INVALID) {
/* turn off any pwm if there's a conflict on this usart */
timer_set_mode(timer_num, compare_num, TIMER_DISABLED);
}
diff --git a/wirish/comm/HardwareSerial.h b/wirish/comm/HardwareSerial.h
index 17be49f..f67f09a 100644
--- a/wirish/comm/HardwareSerial.h
+++ b/wirish/comm/HardwareSerial.h
@@ -31,6 +31,8 @@
#ifndef _HARDWARESERIAL_H_
#define _HARDWARESERIAL_H_
+#include "timers.h"
+
#include "Print.h"
class HardwareSerial : public Print {
@@ -40,7 +42,7 @@ class HardwareSerial : public Print {
GPIO_Port *gpio_port;
uint8 tx_pin;
uint8 rx_pin;
- uint8 timer_num;
+ timer_dev_num timer_num;
uint8 compare_num;
public:
HardwareSerial(uint8 usart_num,
@@ -48,7 +50,7 @@ class HardwareSerial : public Print {
GPIO_Port *gpio_port,
uint8 tx_pin,
uint8 rx_pin,
- uint8 timer_num,
+ timer_dev_num timer_num,
uint8 compare_num);
void begin(uint32);
void end(void);
diff --git a/wirish/pwm.c b/wirish/pwm.c
index 0bf27aa..25a7415 100644
--- a/wirish/pwm.c
+++ b/wirish/pwm.c
@@ -38,9 +38,9 @@ void pwmWrite(uint8 pin, uint16 duty_cycle) {
return;
}
- ccr = (TimerCCR)(PIN_MAP[pin].timer_channel);
+ ccr = PIN_MAP[pin].timer_ccr;
- if (ccr == (TimerCCR)TIMER_INVALID) {
+ if (ccr == 0) {
return;
}
diff --git a/wirish/time.h b/wirish/time.h
index fad47a4..c3dfe2d 100644
--- a/wirish/time.h
+++ b/wirish/time.h
@@ -59,10 +59,10 @@ static inline uint32 micros(void) {
nvic_globalirq_enable();
- /* MAPLE_RELOAD_VAL is 1 less than the number of cycles it actually
- takes to complete a systick reload */
+ /* SYSTICK_RELOAD_VAL is 1 less than the number of cycles it
+ actually takes to complete a SysTick reload */
res = (ms * US_PER_MS) +
- (MAPLE_RELOAD_VAL + 1 - cycle_cnt)/CYCLES_PER_MICROSECOND;
+ (SYSTICK_RELOAD_VAL + 1 - cycle_cnt)/CYCLES_PER_MICROSECOND;
return res;
}
diff --git a/wirish/wirish.c b/wirish/wirish.c
index 3239838..db38050 100644
--- a/wirish/wirish.c
+++ b/wirish/wirish.c
@@ -62,7 +62,7 @@ void init(void) {
rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1);
nvic_init();
- systick_init(MAPLE_RELOAD_VAL);
+ systick_init(SYSTICK_RELOAD_VAL);
gpio_init();
adc_init();
timer_init(TIMER1, 1);
diff --git a/wirish/wirish_math.cpp b/wirish/wirish_math.cpp
index 12a21c3..5aa6510 100644
--- a/wirish/wirish_math.cpp
+++ b/wirish/wirish_math.cpp
@@ -47,8 +47,3 @@ long random(long howsmall, long howbig) {
return random(diff) + howsmall;
}
-long map(long x, long in_min, long in_max, long out_min, long out_max) {
- return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
-}
-
-
diff --git a/wirish/wirish_math.h b/wirish/wirish_math.h
index 4543c1b..ae73d61 100644
--- a/wirish/wirish_math.h
+++ b/wirish/wirish_math.h
@@ -32,7 +32,10 @@
void randomSeed(unsigned int);
long random(long);
long random(long, long);
-long map(long, long, long, long, long);
+/* TODO: profile code bloat due to inlining this */
+inline long map(long x, long in_min, long in_max, long out_min, long out_max) {
+ return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+}
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398