diff options
Diffstat (limited to 'wirish')
-rw-r--r-- | wirish/HardwareTimer.cpp | 39 | ||||
-rw-r--r-- | wirish/HardwareTimer.h | 14 | ||||
-rw-r--r-- | wirish/boards.h | 219 | ||||
-rw-r--r-- | wirish/comm/HardwareSerial.cpp | 89 | ||||
-rw-r--r-- | wirish/comm/HardwareSerial.h | 18 | ||||
-rw-r--r-- | wirish/ext_interrupts.c | 29 | ||||
-rw-r--r-- | wirish/ext_interrupts.h | 8 | ||||
-rw-r--r-- | wirish/io.h | 51 | ||||
-rw-r--r-- | wirish/pwm.c | 4 | ||||
-rw-r--r-- | wirish/time.c | 54 | ||||
-rw-r--r-- | wirish/time.h | 50 | ||||
-rw-r--r-- | wirish/wirish.c | 60 | ||||
-rw-r--r-- | wirish/wirish.h | 12 | ||||
-rw-r--r-- | wirish/wirish_analog.c | 5 | ||||
-rw-r--r-- | wirish/wirish_digital.c | 68 |
15 files changed, 414 insertions, 306 deletions
diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp index 3c8e9f4..5675948 100644 --- a/wirish/HardwareTimer.cpp +++ b/wirish/HardwareTimer.cpp @@ -32,10 +32,7 @@ #include "HardwareTimer.h" HardwareTimer::HardwareTimer(uint8 timerNum) { - ASSERT(timerNum == 1 || - timerNum == 2 || - timerNum == 3 || - timerNum == 4); + ASSERT(timerNum < NR_TIMERS); this->timerNum = timerNum; // Need to remember over flow for bounds checking this->overflow = 0xFFFF; @@ -141,9 +138,43 @@ void HardwareTimer::detachCompare3Interrupt(void) { void HardwareTimer::detachCompare4Interrupt(void) { timer_detach_interrupt(this->timerNum,4); } +#if NR_TIMERS >= 8 +void HardwareTimer::setChannel5Mode(uint8 mode) { + timer_set_mode(this->timerNum,5,mode); +} +void HardwareTimer::setChannel8Mode(uint8 mode) { + timer_set_mode(this->timerNum,8,mode); +} +void HardwareTimer::setCompare5(uint16 val) { + if(val > this->overflow) + val = this->overflow; + timer_set_compare_value(this->timerNum,5,val); +} +void HardwareTimer::setCompare8(uint16 val) { + if(val > this->overflow) + val = this->overflow; + timer_set_compare_value(this->timerNum,8,val); +} +void HardwareTimer::attachCompare5Interrupt(voidFuncPtr handler) { + timer_attach_interrupt(this->timerNum,5,handler); +} +void HardwareTimer::attachCompare8Interrupt(voidFuncPtr handler) { + timer_attach_interrupt(this->timerNum,8,handler); +} +void HardwareTimer::detachCompare5Interrupt(void) { + timer_detach_interrupt(this->timerNum,5); +} +void HardwareTimer::detachCompare8Interrupt(void) { + timer_detach_interrupt(this->timerNum,8); +} +#endif HardwareTimer Timer1(1); HardwareTimer Timer2(2); HardwareTimer Timer3(3); HardwareTimer Timer4(4); +#if NR_TIMERS >= 8 +HardwareTimer Timer5(5); // High-density devices only +HardwareTimer Timer8(8); // High-density devices only +#endif diff --git a/wirish/HardwareTimer.h b/wirish/HardwareTimer.h index c79f54f..3f986e4 100644 --- a/wirish/HardwareTimer.h +++ b/wirish/HardwareTimer.h @@ -62,12 +62,26 @@ class HardwareTimer { void detachCompare2Interrupt(void); void detachCompare3Interrupt(void); void detachCompare4Interrupt(void); + #if NR_TIMERS >= 8 + void setChannel5Mode(uint8 mode); + void setChannel8Mode(uint8 mode); + void setCompare5(uint16 val); // truncates to overflow + void setCompare8(uint16 val); // truncates to overflow + void attachCompare5Interrupt(voidFuncPtr handler); + void attachCompare8Interrupt(voidFuncPtr handler); + void detachCompare5Interrupt(void); + void detachCompare8Interrupt(void); + #endif }; extern HardwareTimer Timer1; extern HardwareTimer Timer2; extern HardwareTimer Timer3; extern HardwareTimer Timer4; +#if NR_TIMERS >= 8 +extern HardwareTimer Timer5; +extern HardwareTimer Timer8; +#endif #endif diff --git a/wirish/boards.h b/wirish/boards.h new file mode 100644 index 0000000..035868a --- /dev/null +++ b/wirish/boards.h @@ -0,0 +1,219 @@ +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Bryan Newbold. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +// This file contains BOARD-specific pin mapping tables. To add a new board +// type, copy the "BOARD_maple" section below and edit it as needed, then +// update your build toolchain with a new "BOARD" type. This must match the +// seperate MCU type (which determines the ../libmaple configuration). + +#ifndef _BOARDS_H_ +#define _BOARDS_H_ + +#include "libmaple.h" +#include "gpio.h" +#include "timers.h" +#include "exti.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +// Set of all possible digital pin names; not all boards have all these +enum { + D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, + D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31, + D32, D33, D34, D35, D36, D37, D38, D39, D40, D41, D42, D43, D44, D45, D46, + D47, D48, D49, D50, D51, D52, D53, D54, D55, D56, D57, D58, D59, D60, D61, + D62, D63, D64, D65, D66, D67, D68, D69, D70, D71, D72, D73, D74, D75, D76, + D77, D78, D79, D80, D81, D82, D83, D84, D85, D86, D87, D88, D89, D90, D91, + D92, D93, D94, D95, D96, D97, D98, D99, D100, D101, D102, D103, D104, D105, + D106, D107, D108, D109, D110, D111, }; + +// Set of all possible analog pin names; not all boards have all these +enum { + ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, ADC10, ADC11, + ADC12, ADC13, ADC14, ADC15, ADC16, ADC17, ADC18, ADC19, ADC20, }; + +#define ADC_INVALID 0xFFFFFFFF +#define TIMER_INVALID (TimerCCR)0xFFFFFFFF + +// Types used for the tables below +typedef struct PinMapping { + GPIO_Port *port; + uint32 pin; + uint32 adc; + TimerCCR timer_channel; +} PinMapping; + +typedef struct ExtiInfo { + uint8 channel; + uint8 port; +} ExtiInfo; + +// LeafLabs Maple rev3, rev4 +#ifdef BOARD_maple + + #define CYCLES_PER_MICROSECOND 72 + + static PinMapping PIN_MAP[NR_GPIO_PINS] = { + {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR}, // D0/PA3 + {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR}, // D1/PA2 + {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR}, // D2/PA0 + {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR}, // D3/PA1 + {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID}, // D4/PB5 + {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR}, // D5/PB6 + {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR}, // D6/PA8 + {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR}, // D7/PA9 + {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR}, // D8/PA10 + {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR}, // D9/PB7 + {GPIOA_BASE, 4, ADC4, TIMER_INVALID}, // D10/PA4 + {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR}, // D11/PA7 + {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR}, // D12/PA6 + {GPIOA_BASE, 5, ADC5, TIMER_INVALID}, // D13/PA5 + {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR}, // D14/PB8 + /* Little header */ + {GPIOC_BASE, 0, ADC10, TIMER_INVALID}, // D15/PC0 + {GPIOC_BASE, 1, ADC11, TIMER_INVALID}, // D16/PC1 + {GPIOC_BASE, 2, ADC12, TIMER_INVALID}, // D17/PC2 + {GPIOC_BASE, 3, ADC13, TIMER_INVALID}, // D18/PC3 + {GPIOC_BASE, 4, ADC14, TIMER_INVALID}, // D19/PC4 + {GPIOC_BASE, 5, ADC15, TIMER_INVALID}, // D20/PC5 + /* External header */ + {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D21/PC13 + {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D22/PC14 + {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D23/PC15 + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR}, // D24/PB9 + {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID}, // D25/PD2 + {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D26/PC10 + {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR}, // D27/PB0 + {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR}, // D28/PB1 + {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D29/PB10 + {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID}, // D30/PB11 + {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID}, // D31/PB12 + {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D32/PB13 + {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D33/PB14 + {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D34/PB15 + {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID}, // D35/PC6 + {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID}, // D36/PC7 + {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID}, // D37/PC8 + {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID} // D38/PC9 (BUT) + }; + + static ExtiInfo PIN_TO_EXTI_CHANNEL[NR_GPIO_PINS] = { + {EXTI3, EXTI_CONFIG_PORTA}, // D0/PA3 + {EXTI2, EXTI_CONFIG_PORTA}, // D1/PA2 + {EXTI0, EXTI_CONFIG_PORTA}, // D2/PA0 + {EXTI1, EXTI_CONFIG_PORTA}, // D3/PA1 + {EXTI5, EXTI_CONFIG_PORTB}, // D4/PB5 + {EXTI6, EXTI_CONFIG_PORTB}, // D5/PB6 + {EXTI8, EXTI_CONFIG_PORTA}, // D6/PA8 + {EXTI9, EXTI_CONFIG_PORTA}, // D7/PA9 + {EXTI10, EXTI_CONFIG_PORTA}, // D8/PA10 + {EXTI7, EXTI_CONFIG_PORTB}, // D9/PB7 + {EXTI4, EXTI_CONFIG_PORTA}, // D10/PA4 + {EXTI7, EXTI_CONFIG_PORTA}, // D11/PA7 + {EXTI6, EXTI_CONFIG_PORTA}, // D12/PA6 + {EXTI5, EXTI_CONFIG_PORTA}, // D13/PA5 + }; + +#endif + +// LeafLabs Maple Native (prototype) +#ifdef BOARD_maple_native + + #define CYCLES_PER_MICROSECOND 72 + + // TODO: + static PinMapping PIN_MAP[NR_GPIO_PINS] = { + {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR}, // D0/PA3 + {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR}, // D1/PA2 + {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR}, // D2/PA0 + {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR}, // D3/PA1 + {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID}, // D4/PB5 + {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR}, // D5/PB6 + {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR}, // D6/PA8 + {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR}, // D7/PA9 + {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR}, // D8/PA10 + {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR}, // D9/PB7 + {GPIOA_BASE, 4, ADC4, TIMER_INVALID}, // D10/PA4 + {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR}, // D11/PA7 + {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR}, // D12/PA6 + {GPIOA_BASE, 5, ADC5, TIMER_INVALID}, // D13/PA5 + {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR}, // D14/PB8 + /* Little header */ + {GPIOC_BASE, 0, ADC10, TIMER_INVALID}, // D15/PC0 + {GPIOC_BASE, 1, ADC11, TIMER_INVALID}, // D16/PC1 + {GPIOC_BASE, 2, ADC12, TIMER_INVALID}, // D17/PC2 + {GPIOC_BASE, 3, ADC13, TIMER_INVALID}, // D18/PC3 + {GPIOC_BASE, 4, ADC14, TIMER_INVALID}, // D19/PC4 + {GPIOC_BASE, 5, ADC15, TIMER_INVALID}, // D20/PC5 + /* External header */ + {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D21/PC13 + {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D22/PC14 + {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D23/PC15 + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR}, // D24/PB9 + {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID}, // D25/PD2 + {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D26/PC10 + {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR}, // D27/PB0 + {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR}, // D28/PB1 + {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D29/PB10 + {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID}, // D30/PB11 + {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID}, // D31/PB12 + {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D32/PB13 + {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D33/PB14 + {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D34/PB15 + {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID}, // D35/PC6 + {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID}, // D36/PC7 + {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID}, // D37/PC8 + {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID} // D38/PC9 (BUT) + }; + + static ExtiInfo PIN_TO_EXTI_CHANNEL[NR_GPIO_PINS] = { + {EXTI3, EXTI_CONFIG_PORTA}, // D0/PA3 + {EXTI2, EXTI_CONFIG_PORTA}, // D1/PA2 + {EXTI0, EXTI_CONFIG_PORTA}, // D2/PA0 + {EXTI1, EXTI_CONFIG_PORTA}, // D3/PA1 + {EXTI5, EXTI_CONFIG_PORTB}, // D4/PB5 + {EXTI6, EXTI_CONFIG_PORTB}, // D5/PB6 + {EXTI8, EXTI_CONFIG_PORTA}, // D6/PA8 + {EXTI9, EXTI_CONFIG_PORTA}, // D7/PA9 + {EXTI10, EXTI_CONFIG_PORTA}, // D8/PA10 + {EXTI7, EXTI_CONFIG_PORTB}, // D9/PB7 + {EXTI4, EXTI_CONFIG_PORTA}, // D10/PA4 + {EXTI7, EXTI_CONFIG_PORTA}, // D11/PA7 + {EXTI6, EXTI_CONFIG_PORTA}, // D12/PA6 + {EXTI5, EXTI_CONFIG_PORTA}, // D13/PA5 + }; +#endif + +#ifndef CYCLES_PER_MICROSECOND +#error Board type has not been selected correctly. +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif + diff --git a/wirish/comm/HardwareSerial.cpp b/wirish/comm/HardwareSerial.cpp index 7157e74..6399ad5 100644 --- a/wirish/comm/HardwareSerial.cpp +++ b/wirish/comm/HardwareSerial.cpp @@ -34,77 +34,60 @@ #include "gpio.h" #include "timers.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 usartNum) { - ASSERT(usartNum == 1 || - usartNum == 2 || - usartNum == 3); - this->usartNum = usartNum; +HardwareSerial Serial1(USART1, 4500000UL, GPIOA_BASE, 9, 10, 1, 2); +HardwareSerial Serial2(USART2, 2250000UL, GPIOA_BASE, 2, 3, 2, 3); +HardwareSerial Serial3(USART3, 2250000UL, GPIOB_BASE, 10, 11, 0, 0); +// TODO: High density device ports + +HardwareSerial::HardwareSerial(uint8 usart_num, + uint32 max_baud, + GPIO_Port *gpio_port, + uint8 tx_pin, + uint8 rx_pin, + uint8 timer_num, + uint8 compare_num) { + this->usart_num = usart_num; + this->max_baud = max_baud; + this->gpio_port = gpio_port; + this->tx_pin = tx_pin; + this->rx_pin = rx_pin; + this->timer_num = timer_num; + this->compare_num = compare_num; } uint8 HardwareSerial::read(void) { - return usart_getc(usartNum); + return usart_getc(usart_num); } uint32 HardwareSerial::available(void) { - - return usart_data_available(usartNum); + return usart_data_available(usart_num); } void HardwareSerial::write(unsigned char ch) { - usart_putc(usartNum, ch); + usart_putc(usart_num, ch); } void HardwareSerial::begin(uint32 baud) { - ASSERT(!(baud > USART_MAX_BAUD)); + if (baud > max_baud) { + return; + } + + gpio_set_mode(gpio_port, tx_pin, GPIO_MODE_AF_OUTPUT_PP); + gpio_set_mode(gpio_port, rx_pin, GPIO_MODE_INPUT_FLOATING); - /* 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); - /* Turn off any pwm */ - timer_set_mode(1, 2, TIMER_DISABLED); - 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); - /* Turn off any pwm */ - timer_set_mode(2, 3, TIMER_DISABLED); - 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); - } + if ((usart_num == USART1) || + (usart_num == USART2)) { + /* turn off any pwm if there's a conflict on this usart */ + timer_set_mode(timer_num, compare_num, TIMER_DISABLED); + } - usart_init(usartNum, baud); + usart_init(usart_num, baud); } void HardwareSerial::end(void) { - usart_disable(usartNum); + usart_disable(usart_num); } void HardwareSerial::flush(void) { - usart_clear_buffer(usartNum); + usart_reset_rx(usart_num); } - -HardwareSerial Serial1(1); -HardwareSerial Serial2(2); -HardwareSerial Serial3(3); diff --git a/wirish/comm/HardwareSerial.h b/wirish/comm/HardwareSerial.h index 5ed81cd..df8d7bf 100644 --- a/wirish/comm/HardwareSerial.h +++ b/wirish/comm/HardwareSerial.h @@ -35,9 +35,21 @@ class HardwareSerial : public Print { private: - uint8 usartNum; + uint8 usart_num; + uint32 max_baud; + GPIO_Port *gpio_port; + uint8 tx_pin; + uint8 rx_pin; + uint8 timer_num; + uint8 compare_num; public: - HardwareSerial(uint8); + HardwareSerial(uint8 usart_num, + uint32 max_baud, + GPIO_Port *gpio_port, + uint8 tx_pin, + uint8 rx_pin, + uint8 timer_num, + uint8 compare_num); void begin(uint32); void end(void); uint32 available(void); @@ -46,9 +58,9 @@ class HardwareSerial : public Print { virtual void write(unsigned char); using Print::write; }; - extern HardwareSerial Serial1; extern HardwareSerial Serial2; extern HardwareSerial Serial3; +// TODO: high density device ports #endif diff --git a/wirish/ext_interrupts.c b/wirish/ext_interrupts.c index 54b8be9..6ba1d05 100644 --- a/wirish/ext_interrupts.c +++ b/wirish/ext_interrupts.c @@ -32,29 +32,6 @@ #include "exti.h" #include "ext_interrupts.h" -typedef struct ExtiInfo { - uint8 channel; - uint8 port; -} ExtiInfo; - -static ExtiInfo PIN_TO_EXTI_CHANNEL[NR_MAPLE_PINS] = { - {EXTI3, EXTI_CONFIG_PORTA}, // D0/PA3 - {EXTI2, EXTI_CONFIG_PORTA}, // D1/PA2 - {EXTI0, EXTI_CONFIG_PORTA}, // D2/PA0 - {EXTI1, EXTI_CONFIG_PORTA}, // D3/PA1 - {EXTI5, EXTI_CONFIG_PORTB}, // D4/PB5 - {EXTI6, EXTI_CONFIG_PORTB}, // D5/PB6 - {EXTI8, EXTI_CONFIG_PORTA}, // D6/PA8 - {EXTI9, EXTI_CONFIG_PORTA}, // D7/PA9 - {EXTI10, EXTI_CONFIG_PORTA}, // D8/PA10 - {EXTI7, EXTI_CONFIG_PORTB}, // D9/PB7 - {EXTI4, EXTI_CONFIG_PORTA}, // D10/PA4 - {EXTI7, EXTI_CONFIG_PORTA}, // D11/PA7 - {EXTI6, EXTI_CONFIG_PORTA}, // D12/PA6 - {EXTI5, EXTI_CONFIG_PORTA}, // D13/PA5 -}; - - /** * @brief Attach an interrupt handler to be triggered on a given * transition on the pin. Runs in interrupt context @@ -65,10 +42,10 @@ static ExtiInfo PIN_TO_EXTI_CHANNEL[NR_MAPLE_PINS] = { * * @sideeffect Registers a handler */ -int attachInterrupt(uint8 pin, voidFuncPtr handler, ExtInterruptTriggerMode mode) { +int attachInterrupt(uint8 pin, voidFuncPtr handler, uint32 mode) { uint8 outMode; /* Parameter checking */ - if (pin >= NR_MAPLE_PINS) { + if (pin >= NR_GPIO_PINS) { return EXT_INTERRUPT_INVALID_PIN; } @@ -100,7 +77,7 @@ int attachInterrupt(uint8 pin, voidFuncPtr handler, ExtInterruptTriggerMode mode } int detachInterrupt(uint8 pin) { - if (!(pin < NR_MAPLE_PINS)) { + if (!(pin < NR_GPIO_PINS)) { return EXT_INTERRUPT_INVALID_PIN; } diff --git a/wirish/ext_interrupts.h b/wirish/ext_interrupts.h index fc69a15..7449685 100644 --- a/wirish/ext_interrupts.h +++ b/wirish/ext_interrupts.h @@ -31,14 +31,14 @@ #ifndef _EXT_INTERRUPTS_H_ #define _EXT_INTERRUPTS_H_ -typedef enum ExtInterruptTriggerMode { +enum { RISING, FALLING, CHANGE -} ExtInterruptTriggerMode; +}; -enum ExtInterruptError { +enum { EXT_INTERRUPT_INVALID_PIN = (-1), EXT_INTERRUPT_INVALID_FUNCTION = (-2), EXT_INTERRUPT_INVALID_MODE = (-3), @@ -48,7 +48,7 @@ enum ExtInterruptError { extern "C"{ #endif -int attachInterrupt(uint8 pin, voidFuncPtr, ExtInterruptTriggerMode mode); +int attachInterrupt(uint8 pin, voidFuncPtr, uint32 mode); int detachInterrupt(uint8 pin); #ifdef __cplusplus diff --git a/wirish/io.h b/wirish/io.h index fff551c..e779604 100644 --- a/wirish/io.h +++ b/wirish/io.h @@ -38,48 +38,6 @@ extern "C"{ #endif -/* stash these here for now */ -#define D0 0 -#define D1 1 -#define D2 2 -#define D3 3 -#define D4 4 -#define D5 5 -#define D6 6 -#define D7 7 -#define D8 8 -#define D9 9 -#define D10 10 -#define D11 11 -#define D12 12 -#define D13 13 -#define D14 14 -#define D15 15 -#define D16 16 -#define D16 16 -#define D17 17 -#define D18 18 -#define D19 19 -#define D20 20 -#define D21 21 -#define D22 22 -#define D23 23 -#define D24 24 -#define D25 25 -#define D26 26 -#define D27 27 -#define D28 28 -#define D29 29 -#define D30 30 -#define D31 31 -#define D32 32 -#define D33 33 -#define D34 34 -#define D35 35 -#define D36 36 -#define D37 37 -#define D38 38 -#define D39 39 typedef enum WiringPinMode { OUTPUT, @@ -92,15 +50,6 @@ typedef enum WiringPinMode { PWM } WiringPinMode; -typedef struct PinMapping { - GPIO_Port *port; - uint32 pin; - uint32 adc; - TimerCCR timer_channel; -} PinMapping; - -#define ADC_INVALID 0xFFFFFFFF -#define TIMER_INVALID (TimerCCR)0xFFFFFFFF /* Set pin to mode * pinMode(pin, mode): diff --git a/wirish/pwm.c b/wirish/pwm.c index 40715b5..995e2c7 100644 --- a/wirish/pwm.c +++ b/wirish/pwm.c @@ -31,12 +31,10 @@ #include "io.h" #include "pwm.h" -extern const PinMapping PIN_MAP[NR_MAPLE_PINS]; - void pwmWrite(uint8 pin, uint16 duty_cycle) { TimerCCR ccr; - if (pin >= NR_MAPLE_PINS) { + if (pin >= NR_GPIO_PINS) { return; } diff --git a/wirish/time.c b/wirish/time.c index 69e962c..ea8ebe1 100644 --- a/wirish/time.c +++ b/wirish/time.c @@ -23,8 +23,6 @@ * ****************************************************************************/ /** - * @file time.c - * * @brief */ @@ -32,46 +30,24 @@ #include "systick.h" #include "time.h" -#define CYCLES_PER_MICROSECOND 72 -#define FUDGE 42 - -extern volatile uint32 systick_timer_millis; - -uint32 millis() { - unsigned long m; - m = systick_timer_millis; - return m; -} - void delay(unsigned long ms) { - unsigned long start = millis(); - - while (millis() - start <= ms) - ; + uint32 i; + for (i = 0; i < ms; i++) { + delayMicroseconds(1000); + } } - - -#if 1 void delayMicroseconds(uint32 us) { - uint32 target; - uint32 last, cur, count; - /* fudge factor hacky hack hack for function overhead */ - target = us * CYCLES_PER_MICROSECOND - FUDGE; - - /* Get current count */ - last = systick_get_count(); - cur = systick_get_count(); - count = last; - while ((count-cur) <= target) { - cur = systick_get_count(); - - /* check for overflow */ - if (cur > last) { - count += MAPLE_RELOAD_VAL; - } - last = cur; - } + // So (2^32)/12 micros max, or less than 6 minutes + us *= 12; + + /* fudge for function call overhead */ + us--; + asm volatile(" mov r0, %[us] \n\t" + "1: subs r0, #1 \n\t" + " bhi 1b \n\t" + : + : [us] "r" (us) + : "r0"); } -#endif diff --git a/wirish/time.h b/wirish/time.h index 9e5536b..33c04b4 100644 --- a/wirish/time.h +++ b/wirish/time.h @@ -23,8 +23,6 @@ * ****************************************************************************/ /** - * @file time.h - * * @brief */ @@ -34,32 +32,42 @@ #ifdef __cplusplus extern "C"{ #endif -/* Returns time since boot in milliseconds */ -uint32 millis(void); + +#include "nvic.h" +#include "systick.h" +#include "boards.h" + +#define US_PER_MS 1000 +#define MAPLE_RELOAD_VAL (CYCLES_PER_MICROSECOND * US_PER_MS) + +extern volatile uint32 systick_timer_millis; + +/* time in milliseconds since boot */ +static inline uint32 millis(void) { + return systick_timer_millis; +} /* Time in microseconds since boot */ -uint32 micros(void); +static inline uint32 micros(void) { + uint32 ms; + uint32 cycle_cnt; + uint32 res; -/* Delay for ms milliseconds */ -void delay(unsigned long ms); + nvic_globalirq_disable(); -/* Delay for us microseconds */ -void delayMicroseconds(uint32 us); + cycle_cnt = systick_get_count(); + ms = millis(); + + nvic_globalirq_enable(); -#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"); + res = (ms * US_PER_MS) + (MAPLE_RELOAD_VAL - cycle_cnt)/CYCLES_PER_MICROSECOND; + return res; } -#endif + +void delay(unsigned long ms); +void delayMicroseconds(uint32 us); + #ifdef __cplusplus } // extern "C" #endif diff --git a/wirish/wirish.c b/wirish/wirish.c index 28e7130..41f5db4 100644 --- a/wirish/wirish.c +++ b/wirish/wirish.c @@ -23,7 +23,14 @@ * ****************************************************************************/ /** - * @brief Maple board bring up + * @brief generic maple board bring up: + * + * By default, we bring up all maple boards running on the stm32 to 72mhz, + * clocked off the PLL, driven by the 8MHz external crystal. + * + * AHB and APB2 are clocked at 72MHz + * APB1 is clocked at 36MHz + * */ #include "wirish.h" @@ -32,35 +39,40 @@ #include "nvic.h" #include "usb.h" #include "rcc.h" +#include "fsmc.h" +#include "dac.h" #include "flash.h" -static void inline maple_flash_init(void) { +void init(void) { + /* make sure the flash is ready before spinning the high speed clock up */ flash_enable_prefetch(); flash_set_latency(FLASH_WAIT_STATE_2); -} -static void inline maple_rcc_init(void) { - struct rcc_device maple_rcc_dev = { - .apb1_prescale = RCC_APB1_HCLK_DIV_2, - .apb2_prescale = RCC_APB2_HCLK_DIV_1, - .ahb_prescale = RCC_AHB_SYSCLK_DIV_1, - .sysclk_src = RCC_CLKSRC_PLL, - .pll_src = RCC_PLLSRC_HSE, - .pll_mul = RCC_PLLMUL_9 - }; + #if HAS_FSMC + fsmc_native_sram_init(); + #endif + + #if NR_DAC_PINS > 0 + dac_init(); + #endif + + /* initialize clocks */ + rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9); + rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); + rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2); + rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1); - rcc_init(&maple_rcc_dev); -} -void init(void) { - maple_flash_init(); - maple_rcc_init(); nvic_init(); - systick_init(); + systick_init(MAPLE_RELOAD_VAL); gpio_init(); -// adc_init(); -// timer_init(1, 1); -// timer_init(2, 1); -// timer_init(3, 1); -// timer_init(4, 1); -// setupUSB(); + adc_init(); + timer_init(1, 1); + timer_init(2, 1); + timer_init(3, 1); + timer_init(4, 1); + #if NR_TIMERS >= 8 + timer_init(5, 1); + timer_init(8, 1); + #endif + setupUSB(); } diff --git a/wirish/wirish.h b/wirish/wirish.h index 13ff313..7ede77c 100644 --- a/wirish/wirish.h +++ b/wirish/wirish.h @@ -32,10 +32,11 @@ #define _WIRISH_H_ #include "libmaple.h" +#include "boards.h" +#include "time.h" #include "timers.h" #include "io.h" #include "bits.h" -#include "time.h" #include "pwm.h" #include "ext_interrupts.h" #include "wirish_math.h" @@ -51,9 +52,6 @@ extern "C"{ #endif -#define MAPLE 1 -#define NR_MAPLE_PINS 39 // temporary - /* Arduino wiring macros and bit defines */ #define HIGH 0x1 #define LOW 0x0 @@ -64,9 +62,6 @@ extern "C"{ #define LSBFIRST 0 #define MSBFIRST 1 -#define USER_ADDR_ROM 0x08005000 -#define USER_ADDR_RAM 0x20000C00 - #define lowByte(w) ((w) & 0xff) #define highByte(w) ((w) >> 8) #define bitRead(value, bit) (((value) >> (bit)) & 0x01) @@ -86,8 +81,5 @@ void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, byte val); } // extern "C" #endif - - - #endif diff --git a/wirish/wirish_analog.c b/wirish/wirish_analog.c index f4c1204..1b911bc 100644 --- a/wirish/wirish_analog.c +++ b/wirish/wirish_analog.c @@ -30,13 +30,12 @@ #include "wirish.h" #include "io.h" -extern const PinMapping PIN_MAP[NR_MAPLE_PINS]; - /* Assumes that the ADC has been initialized and * that the pin is set to ANALOG_INPUT */ uint32 analogRead(uint8 pin) { - if (pin >= NR_ANALOG_PINS) + if(PIN_MAP[pin].adc == ADC_INVALID) { return 0; + } return adc_read(PIN_MAP[pin].adc); } diff --git a/wirish/wirish_digital.c b/wirish/wirish_digital.c index 33217b6..c93c786 100644 --- a/wirish/wirish_digital.c +++ b/wirish/wirish_digital.c @@ -29,72 +29,10 @@ #include "wirish.h" #include "io.h" -#define ADC0 0 -#define ADC1 1 -#define ADC2 2 -#define ADC3 3 -#define ADC4 4 -#define ADC5 5 -#define ADC6 6 -#define ADC7 7 -#define ADC8 8 -#define ADC9 9 -#define ADC10 10 -#define ADC11 11 -#define ADC12 12 -#define ADC13 13 -#define ADC14 14 -#define ADC15 15 -#define ADC16 16 - -const PinMapping PIN_MAP[NR_MAPLE_PINS] = { - {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR}, // D0/PA3 - {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR}, // D1/PA2 - {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR}, // D2/PA0 - {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR}, // D3/PA1 - {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID}, // D4/PB5 - {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR}, // D5/PB6 - {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR}, // D6/PA8 - {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR}, // D7/PA9 - {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR}, // D8/PA10 - {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR}, // D9/PB7 - {GPIOA_BASE, 4, ADC4, TIMER_INVALID}, // D10/PA4 - {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR}, // D11/PA7 - {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR}, // D12/PA6 - {GPIOA_BASE, 5, ADC5, TIMER_INVALID}, // D13/PA5 - {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR}, // D14/PB8 - /* Little header */ - {GPIOC_BASE, 0, ADC10, TIMER_INVALID}, // D15/PC0 - {GPIOC_BASE, 1, ADC11, TIMER_INVALID}, // D16/PC1 - {GPIOC_BASE, 2, ADC12, TIMER_INVALID}, // D17/PC2 - {GPIOC_BASE, 3, ADC13, TIMER_INVALID}, // D18/PC3 - {GPIOC_BASE, 4, ADC14, TIMER_INVALID}, // D19/PC4 - {GPIOC_BASE, 5, ADC15, TIMER_INVALID}, // D20/PC5 - /* External header */ - {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D21/PC13 - {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D22/PC14 - {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D23/PC15 - {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR}, // D24/PB9 - {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID}, // D25/PD2 - {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D26/PC10 - {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR}, // D27/PB0 - {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR}, // D28/PB1 - {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D29/PB10 - {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID}, // D30/PB11 - {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID}, // D31/PB12 - {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D32/PB13 - {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D33/PB14 - {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D34/PB15 - {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID}, // D35/PC6 - {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID}, // D36/PC7 - {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID}, // D37/PC8 - {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID} // D38/PC9 -}; - void pinMode(uint8 pin, WiringPinMode mode) { uint8 outputMode; - if (pin >= NR_MAPLE_PINS) + if (pin >= NR_GPIO_PINS) return; switch(mode) { @@ -130,13 +68,13 @@ void pinMode(uint8 pin, WiringPinMode mode) { uint32 digitalRead(uint8 pin) { - if (pin >= NR_MAPLE_PINS) + if (pin >= NR_GPIO_PINS) return 0; return gpio_read_bit(PIN_MAP[pin].port, PIN_MAP[pin].pin); } void digitalWrite(uint8 pin, uint8 val) { - if (pin >= NR_MAPLE_PINS) + if (pin >= NR_GPIO_PINS) return; gpio_write_bit(PIN_MAP[pin].port, PIN_MAP[pin].pin, val); |