From 7d15cbd7200ccf33dc3a769f75c1ef04aa3c44e8 Mon Sep 17 00:00:00 2001 From: Oleg Semyonov Date: Sat, 21 Jan 2012 00:55:08 +0200 Subject: [PATCH 1/3] gcscontrol: new joystick image with active stick area --- .../plugins/gcscontrol/images/joystick.svg | 2764 ++++++----------- .../plugins/gcscontrol/joystickcontrol.cpp | 32 +- .../src/plugins/gcscontrol/joystickcontrol.h | 1 + 3 files changed, 904 insertions(+), 1893 deletions(-) diff --git a/ground/openpilotgcs/src/plugins/gcscontrol/images/joystick.svg b/ground/openpilotgcs/src/plugins/gcscontrol/images/joystick.svg index 386881587..29d5c8762 100644 --- a/ground/openpilotgcs/src/plugins/gcscontrol/images/joystick.svg +++ b/ground/openpilotgcs/src/plugins/gcscontrol/images/joystick.svg @@ -1,5 +1,5 @@ - + image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 50 % - - 75 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 75 % - - 50 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + inkscape:version="0.48.1 " + sodipodi:docname="joystick.svg"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.cpp b/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.cpp index d738da556..3e8e111df 100644 --- a/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.cpp +++ b/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.cpp @@ -60,13 +60,24 @@ JoystickControl::JoystickControl(QWidget *parent) : m_joystickEnd = new QGraphicsSvgItem(); m_joystickEnd->setSharedRenderer(m_renderer); m_joystickEnd->setElementId(QString("joystickEnd")); - m_joystickEnd->setPos(0,0); + + m_joystickArea = new QGraphicsSvgItem(); + m_joystickArea->setSharedRenderer(m_renderer); + m_joystickArea->setElementId(QString("joystickArea")); + m_joystickArea->setPos( + (m_background->boundingRect().width() - m_joystickArea->boundingRect().width()) * 0.5, + (m_background->boundingRect().height() - m_joystickArea->boundingRect().height()) * 0.5 + ); + m_joystickArea->setVisible(false); QGraphicsScene *l_scene = scene(); l_scene->clear(); // This also deletes all items contained in the scene. l_scene->addItem(m_background); + l_scene->addItem(m_joystickArea); l_scene->addItem(m_joystickEnd); l_scene->setSceneRect(m_background->boundingRect()); + + changePosition(0.0, 0.0); } JoystickControl::~JoystickControl() @@ -90,11 +101,12 @@ void JoystickControl::enableOpenGL(bool flag) */ void JoystickControl::changePosition(double x, double y) { - QRectF sceneSize = scene()->sceneRect(); - - m_joystickEnd->setPos( - (x+1) / 2*sceneSize.width() - m_joystickEnd->boundingRect().width() / 2, - (-y+1) / 2*sceneSize.height() - m_joystickEnd->boundingRect().height() / 2); + QRectF areaSize = m_joystickArea->boundingRect(); + QPointF point( + ((1 + x) * areaSize.width() - m_joystickEnd->boundingRect().width()) * 0.5, + ((1 - y) * areaSize.height() - m_joystickEnd->boundingRect().height()) * 0.5 + ); + m_joystickEnd->setPos(m_joystickArea->mapToScene(point)); } /** @@ -102,11 +114,11 @@ void JoystickControl::changePosition(double x, double y) */ void JoystickControl::mouseMoveEvent(QMouseEvent *event) { - QPointF point = mapToScene(event->pos()); - QRectF sceneSize = scene()->sceneRect(); + QPointF point = m_joystickArea->mapFromScene(mapToScene(event->pos())); + QSizeF areaSize = m_joystickArea->boundingRect().size(); - double Y = - (point.y() / sceneSize.height() - .5) * 2; - double X = (point.x() / sceneSize.width() - .5) * 2; + double Y = - (point.y() / areaSize.height() - .5) * 2; + double X = (point.x() / areaSize.width() - .5) * 2; if (Y<-1) Y = -1; if (Y> 1) Y = 1; if (X<-1) X = -1; diff --git a/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.h b/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.h index 8492474e6..bd0871761 100644 --- a/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.h +++ b/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.h @@ -64,6 +64,7 @@ signals: private: QSvgRenderer *m_renderer; QGraphicsSvgItem *m_background; + QGraphicsSvgItem *m_joystickArea; QGraphicsSvgItem *m_joystickEnd; }; From 9006dd558f97dce5da4677be57f3cded0fb3cb4d Mon Sep 17 00:00:00 2001 From: Oleg Semyonov Date: Sat, 21 Jan 2012 00:52:35 +0200 Subject: [PATCH 2/3] gcscontrol: code style formatting and cleanup --- .../plugins/gcscontrol/joystickcontrol.cpp | 60 ++++++++----------- .../src/plugins/gcscontrol/joystickcontrol.h | 21 ++++--- 2 files changed, 36 insertions(+), 45 deletions(-) diff --git a/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.cpp b/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.cpp index 3e8e111df..0596b22c1 100644 --- a/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.cpp +++ b/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.cpp @@ -7,7 +7,7 @@ * @{ * @addtogroup GCSControlGadgetPlugin GCSControl Gadget Plugin * @{ - * @brief A that mimics a transmitter joystick and updates the MCC + * @brief The plugin that mimics a transmitter joystick and updates the MCC *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -28,30 +28,24 @@ #include "joystickcontrol.h" #include "extensionsystem/pluginmanager.h" #include -#include #include -#include -#include -#include -#include -#include #include -#include +#include /** * @brief Constructor for JoystickControl widget. Sets up the image of a joystick */ -JoystickControl::JoystickControl(QWidget *parent) : - QGraphicsView(parent) +JoystickControl::JoystickControl(QWidget *parent) : QGraphicsView(parent) { - setMinimumSize(64,64); + setMinimumSize(64, 64); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setScene(new QGraphicsScene(this)); setRenderHints(QPainter::Antialiasing); m_renderer = new QSvgRenderer(); bool test = m_renderer->load(QString(":/gcscontrol/images/joystick.svg")); - Q_ASSERT( test ); + Q_UNUSED(test); + Q_ASSERT(test); m_background = new QGraphicsSvgItem(); m_background->setSharedRenderer(m_renderer); @@ -82,18 +76,18 @@ JoystickControl::JoystickControl(QWidget *parent) : JoystickControl::~JoystickControl() { - + // Do nothing } -/*! - \brief Enables/Disables OpenGL +/** + * @brief Enables/Disables OpenGL */ void JoystickControl::enableOpenGL(bool flag) { - if (flag) - setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); - else - setViewport(new QWidget); + if (flag) + setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + else + setViewport(new QWidget); } /** @@ -103,8 +97,8 @@ void JoystickControl::changePosition(double x, double y) { QRectF areaSize = m_joystickArea->boundingRect(); QPointF point( - ((1 + x) * areaSize.width() - m_joystickEnd->boundingRect().width()) * 0.5, - ((1 - y) * areaSize.height() - m_joystickEnd->boundingRect().height()) * 0.5 + ((1.0 + x) * areaSize.width() - m_joystickEnd->boundingRect().width()) * 0.5, + ((1.0 - y) * areaSize.height() - m_joystickEnd->boundingRect().height()) * 0.5 ); m_joystickEnd->setPos(m_joystickArea->mapToScene(point)); } @@ -117,14 +111,14 @@ void JoystickControl::mouseMoveEvent(QMouseEvent *event) QPointF point = m_joystickArea->mapFromScene(mapToScene(event->pos())); QSizeF areaSize = m_joystickArea->boundingRect().size(); - double Y = - (point.y() / areaSize.height() - .5) * 2; - double X = (point.x() / areaSize.width() - .5) * 2; - if (Y<-1) Y = -1; - if (Y> 1) Y = 1; - if (X<-1) X = -1; - if (X> 1) X = 1; + double y = - (point.y() / areaSize.height() - 0.5) * 2.0; + double x = (point.x() / areaSize.width() - 0.5) * 2.0; + if (y < -1.0) y = -1.0; + if (y > 1.0) y = 1.0; + if (x < -1.0) x = -1.0; + if (x > 1.0) x = 1.0; - emit positionClicked(X, Y); + emit positionClicked(x, y); } /** @@ -132,12 +126,11 @@ void JoystickControl::mouseMoveEvent(QMouseEvent *event) */ void JoystickControl::mousePressEvent(QMouseEvent *event) { - if( event->button() == Qt::LeftButton ) { + if (event->button() == Qt::LeftButton) { mouseMoveEvent(event); } } - void JoystickControl::paint() { update(); @@ -145,9 +138,9 @@ void JoystickControl::paint() void JoystickControl::paintEvent(QPaintEvent *event) { - // Skip painting until the dial file is loaded - if (! m_renderer->isValid()) { - qDebug()<<"Image file not loaded, not rendering"; + // Skip painting until the image file is loaded + if (!m_renderer->isValid()) { + qDebug() << "Image file not loaded, not rendering"; } QGraphicsView::paintEvent(event); @@ -159,7 +152,6 @@ void JoystickControl::resizeEvent(QResizeEvent *event) fitInView(m_background, Qt::IgnoreAspectRatio ); } - /** * @} * @} diff --git a/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.h b/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.h index bd0871761..9c6ac59d0 100644 --- a/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.h +++ b/ground/openpilotgcs/src/plugins/gcscontrol/joystickcontrol.h @@ -7,7 +7,7 @@ * @{ * @addtogroup GCSControlGadgetPlugin GCSControl Gadget Plugin * @{ - * @brief A that mimics a transmitter joystick and updates the MCC + * @brief The plugin that mimics a transmitter joystick and updates the MCC *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -25,7 +25,6 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef JOYSTICKCONTROL_H #define JOYSTICKCONTROL_H @@ -46,27 +45,27 @@ class JoystickControl : public QGraphicsView public: explicit JoystickControl(QWidget *parent = 0); ~JoystickControl(); - void enableOpenGL(bool flag); - void paint(); + void enableOpenGL(bool flag); + void paint(); protected: - void mouseMoveEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent *event); - void paintEvent(QPaintEvent *event); - void resizeEvent(QResizeEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *event); + void resizeEvent(QResizeEvent *event); public slots: - void changePosition (double X, double Y); + void changePosition(double x, double y); signals: - void positionClicked(double X, double Y); + void positionClicked(double x, double y); private: QSvgRenderer *m_renderer; QGraphicsSvgItem *m_background; QGraphicsSvgItem *m_joystickArea; QGraphicsSvgItem *m_joystickEnd; - }; +}; #endif // JOYSTICKCONTROL_H From bfe6676eed6fe40e4b9a6271fd3b8c30f4e21845 Mon Sep 17 00:00:00 2001 From: Stacey Sheldon Date: Sun, 22 Jan 2012 23:23:41 -0500 Subject: [PATCH 3/3] exti: rewrite exti layer to improve portability The exti layer now allows drivers to register interrupt callbacks during board initialization. All details of the driver using a particular EXTI pin have been removed from the EXTI layer so it can now be used on any board without board-specific modification. This includes some nice refinements provided by Mike Smith during initial review. His original commits have been squashed into this one. --- flight/PiOS.posix/posix/pios_debug.c | 2 +- flight/PiOS/Boards/STM32103CB_CC_Rev1.h | 2 - flight/PiOS/Boards/STM3210E_OP.h | 2 - flight/PiOS/Common/pios_bmp085.c | 96 +++++--- flight/PiOS/Common/pios_hmc5843.c | 66 +++--- .../inc/stm32f10x_exti.h | 2 +- .../src/stm32f10x_exti.c | 2 +- flight/PiOS/STM32F10x/pios_exti.c | 222 ++++++++++++++---- flight/PiOS/inc/pios_exti.h | 15 ++ flight/PiOS/inc/pios_stm32.h | 4 + 10 files changed, 299 insertions(+), 114 deletions(-) diff --git a/flight/PiOS.posix/posix/pios_debug.c b/flight/PiOS.posix/posix/pios_debug.c index 5956a9d04..7f3dc99da 100644 --- a/flight/PiOS.posix/posix/pios_debug.c +++ b/flight/PiOS.posix/posix/pios_debug.c @@ -72,7 +72,7 @@ void PIOS_DEBUG_PinValue4BitL(uint8_t value) /** * Report a serious error and halt */ -void PIOS_DEBUG_Panic(const char *msg) +void PIOS_DEBUG_Panic(const char *msg) __attribute__ ((noreturn)) { #ifdef PIOS_COM_DEBUG register int *lr asm("lr"); // Link-register holds the PC of the caller diff --git a/flight/PiOS/Boards/STM32103CB_CC_Rev1.h b/flight/PiOS/Boards/STM32103CB_CC_Rev1.h index 7773b9092..aebd322cb 100644 --- a/flight/PiOS/Boards/STM32103CB_CC_Rev1.h +++ b/flight/PiOS/Boards/STM32103CB_CC_Rev1.h @@ -284,6 +284,4 @@ extern uint32_t pios_com_telem_usb_id; #define PIOS_USB_DETECT_GPIO_PORT GPIOC #define PIOS_USB_MAX_DEVS 1 #define PIOS_USB_DETECT_GPIO_PIN GPIO_Pin_15 -#define PIOS_USB_DETECT_EXTI_LINE EXTI_Line15 -#define PIOS_IRQ_USB_PRIORITY PIOS_IRQ_PRIO_MID #endif /* STM32103CB_AHRS_H_ */ diff --git a/flight/PiOS/Boards/STM3210E_OP.h b/flight/PiOS/Boards/STM3210E_OP.h index 7099234c6..6a166d0fd 100644 --- a/flight/PiOS/Boards/STM3210E_OP.h +++ b/flight/PiOS/Boards/STM3210E_OP.h @@ -316,8 +316,6 @@ extern uint32_t pios_com_aux_id; #define PIOS_USB_MAX_DEVS 1 #define PIOS_USB_HID_MAX_DEVS 1 #define PIOS_USB_DETECT_GPIO_PIN GPIO_Pin_4 -#define PIOS_USB_DETECT_EXTI_LINE EXTI_Line4 -#define PIOS_IRQ_USB_PRIORITY PIOS_IRQ_PRIO_MID /** * glue macros for file IO diff --git a/flight/PiOS/Common/pios_bmp085.c b/flight/PiOS/Common/pios_bmp085.c index 5a4b0cd94..cd294230b 100644 --- a/flight/PiOS/Common/pios_bmp085.c +++ b/flight/PiOS/Common/pios_bmp085.c @@ -36,19 +36,11 @@ #error PIOS_EXTI Must be included in the project! #endif /* PIOS_INCLUDE_EXTI */ +#include + /* Glocal Variables */ ConversionTypeTypeDef CurrentRead; -#ifdef PIOS_BMP085_HAS_GPIOS - -#if defined(PIOS_INCLUDE_FREERTOS) -xSemaphoreHandle PIOS_BMP085_EOC; -#else -int32_t PIOS_BMP085_EOC; -#endif - -#endif /* PIOS_BMP085_HAS_GPIOS */ - /* Local Variables */ static BMP085CalibDataTypeDef CalibData; @@ -60,18 +52,69 @@ static volatile uint32_t RawPressure; static volatile uint32_t Pressure; static volatile uint16_t Temperature; +#ifdef PIOS_BMP085_HAS_GPIOS + +#if defined(PIOS_INCLUDE_FREERTOS) +xSemaphoreHandle PIOS_BMP085_EOC; +#else +int32_t PIOS_BMP085_EOC; +#endif + +void PIOS_BMP085_EndOfConversion (void) +{ +#if defined(PIOS_INCLUDE_FREERTOS) + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; +#endif + + /* Read the ADC Value */ +#if defined(PIOS_INCLUDE_FREERTOS) + xSemaphoreGiveFromISR(PIOS_BMP085_EOC, &xHigherPriorityTaskWoken); +#else + PIOS_BMP085_EOC=1; +#endif + +#if defined(PIOS_INCLUDE_FREERTOS) + /* Yield From ISR if needed */ + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); +#endif +} + +static const struct pios_exti_cfg pios_exti_bmp085_cfg __exti_config = { + .vector = PIOS_BMP085_EndOfConversion, + .line = PIOS_BMP085_EOC_EXTI_LINE, + .pin = { + .gpio = PIOS_BMP085_EOC_GPIO_PORT, + .init = { + .GPIO_Pin = PIOS_BMP085_EOC_GPIO_PIN, + .GPIO_Mode = GPIO_Mode_IN_FLOATING, + }, + }, + .irq = { + .init = { + .NVIC_IRQChannel = PIOS_BMP085_EOC_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_BMP085_EOC_PRIO, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .exti = { + .init = { + .EXTI_Line = PIOS_BMP085_EOC_EXTI_LINE, + .EXTI_Mode = EXTI_Mode_Interrupt, + .EXTI_Trigger = EXTI_Trigger_Rising, + .EXTI_LineCmd = ENABLE, + }, + }, +}; + +#endif /* PIOS_BMP085_HAS_GPIOS */ /** * Initialise the BMP085 sensor */ void PIOS_BMP085_Init(void) { - #ifdef PIOS_BMP085_HAS_GPIOS - GPIO_InitTypeDef GPIO_InitStructure; - EXTI_InitTypeDef EXTI_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; - #if defined(PIOS_INCLUDE_FREERTOS) /* Semaphore used by ISR to signal End-Of-Conversion */ vSemaphoreCreateBinary(PIOS_BMP085_EOC); @@ -84,27 +127,12 @@ void PIOS_BMP085_Init(void) /* Enable EOC GPIO clock */ RCC_APB2PeriphClockCmd(PIOS_BMP085_EOC_CLK | RCC_APB2Periph_AFIO, ENABLE); - /* Configure EOC pin as input floating */ - GPIO_InitStructure.GPIO_Pin = PIOS_BMP085_EOC_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; - GPIO_Init(PIOS_BMP085_EOC_GPIO_PORT, &GPIO_InitStructure); - - /* Configure the End Of Conversion (EOC) interrupt */ - GPIO_EXTILineConfig(PIOS_BMP085_EOC_PORT_SOURCE, PIOS_BMP085_EOC_PIN_SOURCE); - EXTI_InitStructure.EXTI_Line = PIOS_BMP085_EOC_EXTI_LINE; - EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; - EXTI_InitStructure.EXTI_LineCmd = ENABLE; - EXTI_Init(&EXTI_InitStructure); - - /* Enable and set EOC EXTI Interrupt to the lowest priority */ - NVIC_InitStructure.NVIC_IRQChannel = PIOS_BMP085_EOC_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PIOS_BMP085_EOC_PRIO; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + if (PIOS_EXTI_Init(&pios_exti_bmp085_cfg)) { + PIOS_Assert(0); + } /* Configure XCLR pin as push/pull alternate funtion output */ + GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = PIOS_BMP085_XCLR_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(PIOS_BMP085_XCLR_GPIO_PORT, &GPIO_InitStructure); diff --git a/flight/PiOS/Common/pios_hmc5843.c b/flight/PiOS/Common/pios_hmc5843.c index b62499d71..688d2e90f 100644 --- a/flight/PiOS/Common/pios_hmc5843.c +++ b/flight/PiOS/Common/pios_hmc5843.c @@ -34,6 +34,8 @@ #if defined(PIOS_INCLUDE_HMC5843) +#include + /* HMC5843 Addresses */ #define PIOS_HMC5843_I2C_ADDR 0x1E #define PIOS_HMC5843_CONFIG_REG_A (uint8_t)0x00 @@ -107,37 +109,48 @@ static void PIOS_HMC5843_Config(PIOS_HMC5843_ConfigTypeDef * HMC5843_Config_Stru static bool PIOS_HMC5843_Read(uint8_t address, uint8_t * buffer, uint8_t len); static bool PIOS_HMC5843_Write(uint8_t address, uint8_t buffer); +void PIOS_HMC5843_EndOfConversion (void) +{ + pios_hmc5843_data_ready = true; +} + +static const struct pios_exti_cfg pios_exti_hmc5843_cfg __exti_config = { + .vector = PIOS_HMC5843_EndOfConversion, + .line = PIOS_HMC5843_DRDY_EXTI_LINE, + .pin = { + .gpio = PIOS_HMC5843_DRDY_GPIO_PORT, + .init = { + .GPIO_Pin = PIOS_HMC5843_DRDY_GPIO_PIN, + .GPIO_Mode = GPIO_Mode_IN_FLOATING, + }, + }, + .irq = { + .init = { + .NVIC_IRQChannel = PIOS_HMC5843_DRDY_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_HMC5843_DRDY_PRIO, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .exti = { + .init = { + .EXTI_Line = PIOS_HMC5843_DRDY_EXTI_LINE, + .EXTI_Mode = EXTI_Mode_Interrupt, + .EXTI_Trigger = EXTI_Trigger_Rising, + .EXTI_LineCmd = ENABLE, + }, + }, +}; + /** - * @brieft Initialise the HMC5843 sensor + * @brief Initialise the HMC5843 sensor */ void PIOS_HMC5843_Init(void) { - GPIO_InitTypeDef GPIO_InitStructure; - EXTI_InitTypeDef EXTI_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; - /* Enable DRDY GPIO clock */ RCC_APB2PeriphClockCmd(PIOS_HMC5843_DRDY_CLK | RCC_APB2Periph_AFIO, ENABLE); - /* Configure EOC pin as input floating */ - GPIO_InitStructure.GPIO_Pin = PIOS_HMC5843_DRDY_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; - GPIO_Init(PIOS_HMC5843_DRDY_GPIO_PORT, &GPIO_InitStructure); - - /* Configure the End Of Conversion (EOC) interrupt */ - GPIO_EXTILineConfig(PIOS_HMC5843_DRDY_PORT_SOURCE, PIOS_HMC5843_DRDY_PIN_SOURCE); - EXTI_InitStructure.EXTI_Line = PIOS_HMC5843_DRDY_EXTI_LINE; - EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; - EXTI_InitStructure.EXTI_LineCmd = ENABLE; - EXTI_Init(&EXTI_InitStructure); - - /* Enable and set EOC EXTI Interrupt to the lowest priority */ - NVIC_InitStructure.NVIC_IRQChannel = PIOS_HMC5843_DRDY_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PIOS_HMC5843_DRDY_PRIO; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + PIOS_EXTI_Init(&pios_exti_hmc5843_cfg); /* Configure the HMC5843 Sensor */ PIOS_HMC5843_ConfigTypeDef HMC5843_InitStructure; @@ -362,11 +375,6 @@ static bool PIOS_HMC5843_Write(uint8_t address, uint8_t buffer) return PIOS_I2C_Transfer(PIOS_I2C_MAIN_ADAPTER, txn_list, NELEMENTS(txn_list)); } -void PIOS_HMC5843_IRQHandler(void) -{ - pios_hmc5843_data_ready = true; -} - #endif /** diff --git a/flight/PiOS/STM32F10x/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h b/flight/PiOS/STM32F10x/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h index 29bed11cf..99084e3f3 100644 --- a/flight/PiOS/STM32F10x/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h +++ b/flight/PiOS/STM32F10x/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h @@ -155,7 +155,7 @@ typedef struct */ void EXTI_DeInit(void); -void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); +void EXTI_Init(const EXTI_InitTypeDef* EXTI_InitStruct); void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct); void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line); FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line); diff --git a/flight/PiOS/STM32F10x/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c b/flight/PiOS/STM32F10x/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c index f9467d0dc..73de195cb 100755 --- a/flight/PiOS/STM32F10x/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c +++ b/flight/PiOS/STM32F10x/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c @@ -97,7 +97,7 @@ void EXTI_DeInit(void) * that contains the configuration information for the EXTI peripheral. * @retval None */ -void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) +void EXTI_Init(const EXTI_InitTypeDef* EXTI_InitStruct) { uint32_t tmp = 0; diff --git a/flight/PiOS/STM32F10x/pios_exti.c b/flight/PiOS/STM32F10x/pios_exti.c index 0b4a9a1ae..8b1d2dc32 100644 --- a/flight/PiOS/STM32F10x/pios_exti.c +++ b/flight/PiOS/STM32F10x/pios_exti.c @@ -5,7 +5,6 @@ * @{ * @addtogroup PIOS_EXTI External Interrupt Handlers * @brief External interrupt handler functions - * @note Currently deals with BMP085 readings * @{ * * @file pios_exti.c @@ -35,61 +34,196 @@ #if defined(PIOS_INCLUDE_EXTI) -/** -* Handle external lines 15 to 10 interrupt requests -*/ -void EXTI15_10_IRQHandler(void) +/* Map EXTI line to full config */ +#define EXTI_MAX_LINES 16 +#define PIOS_EXTI_INVALID 0xFF +static uint8_t pios_exti_line_to_cfg_map[EXTI_MAX_LINES] = { + [0 ... EXTI_MAX_LINES-1] = PIOS_EXTI_INVALID, +}; + +/* Table of exti configs registered at compile time */ +extern struct pios_exti_cfg __start__exti __attribute__((weak)); +extern struct pios_exti_cfg __stop__exti __attribute__((weak)); + +static uint8_t PIOS_EXTI_line_to_index (uint32_t line) { -#if defined(PIOS_INCLUDE_FREERTOS) - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; -#endif - -#if defined(PIOS_INCLUDE_BMP085) && defined(PIOS_BMP085_HAS_GPIOS) - if (EXTI_GetITStatus(PIOS_BMP085_EOC_EXTI_LINE) != RESET) { - /* Read the ADC Value */ -#if defined(PIOS_INCLUDE_FREERTOS) - xSemaphoreGiveFromISR(PIOS_BMP085_EOC, &xHigherPriorityTaskWoken); -#else - PIOS_BMP085_EOC=1; -#endif - - /* Clear the EXTI line pending bit */ - EXTI_ClearITPendingBit(PIOS_BMP085_EOC_EXTI_LINE); + switch (line) { + case EXTI_Line0: return 0; + case EXTI_Line1: return 1; + case EXTI_Line2: return 2; + case EXTI_Line3: return 3; + case EXTI_Line4: return 4; + case EXTI_Line5: return 5; + case EXTI_Line6: return 6; + case EXTI_Line7: return 7; + case EXTI_Line8: return 8; + case EXTI_Line9: return 9; + case EXTI_Line10: return 10; + case EXTI_Line11: return 11; + case EXTI_Line12: return 12; + case EXTI_Line13: return 13; + case EXTI_Line14: return 14; + case EXTI_Line15: return 15; } -#endif -#if defined(PIOS_INCLUDE_FREERTOS) - /* Yield From ISR if needed */ - portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); -#endif + PIOS_Assert(0); + return 0xFF; } -/** -* Handle external lines 9 to 5 interrupt requests -*/ -extern void PIOS_HMC5843_IRQHandler(void); -void EXTI9_5_IRQHandler(void) +uint8_t PIOS_EXTI_gpio_port_to_exti_source_port(GPIO_TypeDef * gpio_port) { -#if defined(PIOS_INCLUDE_HMC5843) - if (EXTI_GetITStatus(PIOS_HMC5843_DRDY_EXTI_LINE) != RESET) { - PIOS_HMC5843_IRQHandler(); - EXTI_ClearITPendingBit(PIOS_HMC5843_DRDY_EXTI_LINE); + switch((uint32_t)gpio_port) { + case (uint32_t)GPIOA: return (GPIO_PortSourceGPIOA); + case (uint32_t)GPIOB: return (GPIO_PortSourceGPIOB); + case (uint32_t)GPIOC: return (GPIO_PortSourceGPIOC); + case (uint32_t)GPIOD: return (GPIO_PortSourceGPIOD); + case (uint32_t)GPIOE: return (GPIO_PortSourceGPIOE); + case (uint32_t)GPIOF: return (GPIO_PortSourceGPIOF); + case (uint32_t)GPIOG: return (GPIO_PortSourceGPIOG); } -#endif + + PIOS_Assert(0); + return 0xFF; } -/** -* Handle external line 4 interrupt requests -*/ -#if defined(PIOS_INCLUDE_USB) -void EXTI4_IRQHandler(void) +uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin) { - if (EXTI_GetITStatus(PIOS_USB_DETECT_EXTI_LINE) != RESET) { - /* Clear the EXTI line pending bit */ - EXTI_ClearITPendingBit(PIOS_USB_DETECT_EXTI_LINE); + switch((uint32_t)gpio_pin) { + case GPIO_Pin_0: return (GPIO_PinSource0); + case GPIO_Pin_1: return (GPIO_PinSource1); + case GPIO_Pin_2: return (GPIO_PinSource2); + case GPIO_Pin_3: return (GPIO_PinSource3); + case GPIO_Pin_4: return (GPIO_PinSource4); + case GPIO_Pin_5: return (GPIO_PinSource5); + case GPIO_Pin_6: return (GPIO_PinSource6); + case GPIO_Pin_7: return (GPIO_PinSource7); + case GPIO_Pin_8: return (GPIO_PinSource8); + case GPIO_Pin_9: return (GPIO_PinSource9); + case GPIO_Pin_10: return (GPIO_PinSource10); + case GPIO_Pin_11: return (GPIO_PinSource11); + case GPIO_Pin_12: return (GPIO_PinSource12); + case GPIO_Pin_13: return (GPIO_PinSource13); + case GPIO_Pin_14: return (GPIO_PinSource14); + case GPIO_Pin_15: return (GPIO_PinSource15); } + + PIOS_Assert(0); + return 0xFF; } -#endif + +int32_t PIOS_EXTI_Init(const struct pios_exti_cfg * cfg) +{ + PIOS_Assert(cfg); + PIOS_Assert(&__start__exti); + PIOS_Assert(cfg >= &__start__exti); + PIOS_Assert(cfg < &__stop__exti); + + uint8_t cfg_index = cfg - &__start__exti; + + /* Connect this config to the requested vector */ + uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line); + + if (pios_exti_line_to_cfg_map[line_index] != PIOS_EXTI_INVALID) { + /* Someone else already has this mapped */ + goto out_fail; + } + + /* Bind the config to the exti line */ + pios_exti_line_to_cfg_map[line_index] = cfg_index; + + /* Initialize the GPIO pin */ + GPIO_Init(cfg->pin.gpio, &cfg->pin.init); + + /* Set up the EXTI interrupt source */ + uint8_t exti_source_port = PIOS_EXTI_gpio_port_to_exti_source_port(cfg->pin.gpio); + uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin); + GPIO_EXTILineConfig(exti_source_port, exti_source_pin); + EXTI_Init(&cfg->exti.init); + + /* Enable the interrupt channel */ + NVIC_Init(&cfg->irq.init); + + return 0; + +out_fail: + return -1; +} + +static void PIOS_EXTI_generic_irq_handler(uint8_t line_index) +{ + uint8_t cfg_index = pios_exti_line_to_cfg_map[line_index]; + + PIOS_Assert(&__start__exti); + + if (cfg_index > NELEMENTS(pios_exti_line_to_cfg_map) || + cfg_index == PIOS_EXTI_INVALID) { + /* Unconfigured interrupt just fired! */ + return; + } + + struct pios_exti_cfg * cfg = &__start__exti + cfg_index; + cfg->vector(); +} + +/* Bind Interrupt Handlers */ + +#define PIOS_EXTI_HANDLE_LINE(line) \ + if (EXTI_GetITStatus(EXTI_Line##line) != RESET) { \ + EXTI_ClearITPendingBit(EXTI_Line##line); \ + PIOS_EXTI_generic_irq_handler(line); \ + } + +static void PIOS_EXTI_0_irq_handler (void) +{ + PIOS_EXTI_HANDLE_LINE(0); +} +void EXTI0_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_0_irq_handler"))); + +static void PIOS_EXTI_1_irq_handler (void) +{ + PIOS_EXTI_HANDLE_LINE(1); +} +void EXTI1_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_1_irq_handler"))); + +static void PIOS_EXTI_2_irq_handler (void) +{ + PIOS_EXTI_HANDLE_LINE(2); +} +void EXTI2_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_2_irq_handler"))); + +static void PIOS_EXTI_3_irq_handler (void) +{ + PIOS_EXTI_HANDLE_LINE(3); +} +void EXTI3_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_3_irq_handler"))); + +static void PIOS_EXTI_4_irq_handler (void) +{ + PIOS_EXTI_HANDLE_LINE(4); +} +void EXTI4_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_4_irq_handler"))); + +static void PIOS_EXTI_9_5_irq_handler (void) +{ + PIOS_EXTI_HANDLE_LINE(5); + PIOS_EXTI_HANDLE_LINE(6); + PIOS_EXTI_HANDLE_LINE(7); + PIOS_EXTI_HANDLE_LINE(8); + PIOS_EXTI_HANDLE_LINE(9); +} +void EXTI9_5_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_9_5_irq_handler"))); + +static void PIOS_EXTI_15_10_irq_handler (void) +{ + PIOS_EXTI_HANDLE_LINE(10); + PIOS_EXTI_HANDLE_LINE(11); + PIOS_EXTI_HANDLE_LINE(12); + PIOS_EXTI_HANDLE_LINE(13); + PIOS_EXTI_HANDLE_LINE(14); + PIOS_EXTI_HANDLE_LINE(15); +} +void EXTI15_10_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_15_10_irq_handler"))); + #endif /** diff --git a/flight/PiOS/inc/pios_exti.h b/flight/PiOS/inc/pios_exti.h index fdccc6bf2..73a3bb556 100644 --- a/flight/PiOS/inc/pios_exti.h +++ b/flight/PiOS/inc/pios_exti.h @@ -33,6 +33,21 @@ /* Public Functions */ +#include + +struct pios_exti_cfg { + void (* vector)(void); + uint32_t line; /* use EXTI_LineN macros */ + struct stm32_gpio pin; + struct stm32_irq irq; + struct stm32_exti exti; +}; + +/* must be added to any pios_exti_cfg definition for it to be valid */ +#define __exti_config __attribute__((section("_exti"))) + +extern int32_t PIOS_EXTI_Init(const struct pios_exti_cfg * cfg); + #endif /* PIOS_EXTI_H */ /** diff --git a/flight/PiOS/inc/pios_stm32.h b/flight/PiOS/inc/pios_stm32.h index fb9163208..4e63d6937 100644 --- a/flight/PiOS/inc/pios_stm32.h +++ b/flight/PiOS/inc/pios_stm32.h @@ -36,6 +36,10 @@ struct stm32_irq { NVIC_InitTypeDef init; }; +struct stm32_exti { + EXTI_InitTypeDef init; +}; + struct stm32_dma_chan { DMA_Channel_TypeDef *channel; DMA_InitTypeDef init;