Simple "Blinky" example for the QP active object framework

Dependencies:   mbed qp

Fork of qp_dpp by Quantum Leaps

Committer:
QL
Date:
Sun Oct 12 18:56:53 2014 +0000
Revision:
7:80bbc7a6c78c
Parent:
4:6189d844a1a2
Simple "Blinky" example for the QP active object framework

Who changed what in which revision?

UserRevisionLine numberNew contents of line
QL 4:6189d844a1a2 1 #include "qp_port.h"
QL 7:80bbc7a6c78c 2 #include "blinky.h"
QL 4:6189d844a1a2 3 #include "bsp.h"
QL 4:6189d844a1a2 4 #include "LPC17xx.h"
QL 4:6189d844a1a2 5 #ifdef Q_SPY
QL 4:6189d844a1a2 6 #include "mbed.h" // mbed is used only for the built-in serial
QL 4:6189d844a1a2 7 #endif
QL 4:6189d844a1a2 8
QL 4:6189d844a1a2 9 //////////////////////////////////////////////////////////////////////////////
QL 4:6189d844a1a2 10 Q_DEFINE_THIS_FILE
QL 4:6189d844a1a2 11
QL 4:6189d844a1a2 12 enum ISR_Priorities { // ISR priorities starting from the highest urgency
QL 4:6189d844a1a2 13 GPIOPORTA_PRIO,
QL 4:6189d844a1a2 14 SYSTICK_PRIO
QL 4:6189d844a1a2 15 // ...
QL 4:6189d844a1a2 16 };
QL 4:6189d844a1a2 17
QL 4:6189d844a1a2 18 // Local-scope objects -------------------------------------------------------
QL 4:6189d844a1a2 19 #define LED_PORT LPC_GPIO1
QL 4:6189d844a1a2 20 #define LED1_BIT (1U << 18)
QL 4:6189d844a1a2 21 #define LED2_BIT (1U << 20)
QL 4:6189d844a1a2 22 #define LED3_BIT (1U << 21)
QL 4:6189d844a1a2 23 #define LED4_BIT (1U << 23)
QL 4:6189d844a1a2 24
QL 4:6189d844a1a2 25 #ifdef Q_SPY
QL 4:6189d844a1a2 26 QP::QSTimeCtr l_tickTime;
QL 4:6189d844a1a2 27 QP::QSTimeCtr l_tickPeriod;
QL 4:6189d844a1a2 28 static uint8_t l_SysTick_Handler;
QL 4:6189d844a1a2 29
QL 4:6189d844a1a2 30 #define QSPY_BAUD_RATE 115200U
QL 4:6189d844a1a2 31
QL 4:6189d844a1a2 32 Serial l_qspy(USBTX, USBRX);
QL 4:6189d844a1a2 33 #endif
QL 4:6189d844a1a2 34
QL 4:6189d844a1a2 35 //............................................................................
QL 4:6189d844a1a2 36 extern "C" void SysTick_Handler(void) {
QL 4:6189d844a1a2 37 QK_ISR_ENTRY(); // inform the QK kernel of entering the ISR
QL 4:6189d844a1a2 38
QL 4:6189d844a1a2 39 #ifdef Q_SPY
QL 4:6189d844a1a2 40 uint32_t volatile dummy = SysTick->CTRL; // clear the COUNTFLAG in SysTick
QL 4:6189d844a1a2 41 l_tickTime += l_tickPeriod; // account for the clock rollover
QL 4:6189d844a1a2 42 #endif
QL 4:6189d844a1a2 43
QL 4:6189d844a1a2 44 QP::QF::TICK(&l_SysTick_Handler); // process all armed time events
QL 4:6189d844a1a2 45
QL 4:6189d844a1a2 46 QK_ISR_EXIT(); // inform the QK kernel of exiting the ISR
QL 4:6189d844a1a2 47 }
QL 4:6189d844a1a2 48
QL 4:6189d844a1a2 49 //............................................................................
QL 4:6189d844a1a2 50 void BSP_init(void) {
QL 4:6189d844a1a2 51 // set the system clock as specified in lm3s_config.h (20MHz from PLL)
QL 4:6189d844a1a2 52 SystemInit();
QL 4:6189d844a1a2 53
QL 4:6189d844a1a2 54 // set LED port to output
QL 4:6189d844a1a2 55 LED_PORT->FIODIR |= (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
QL 4:6189d844a1a2 56
QL 4:6189d844a1a2 57 // clear the LEDs
QL 4:6189d844a1a2 58 LED_PORT->FIOCLR = (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
QL 7:80bbc7a6c78c 59
QL 4:6189d844a1a2 60 // initialize the QS software tracing...
QL 4:6189d844a1a2 61 Q_ALLEGE(QS_INIT(static_cast<void *>(0)));
QL 4:6189d844a1a2 62 QS_RESET();
QL 4:6189d844a1a2 63 QS_OBJ_DICTIONARY(&l_SysTick_Handler);
QL 4:6189d844a1a2 64 }
QL 4:6189d844a1a2 65 //............................................................................
QL 4:6189d844a1a2 66 void BSP_terminate(int16_t const result) {
QL 4:6189d844a1a2 67 (void)result;
QL 4:6189d844a1a2 68 }
QL 4:6189d844a1a2 69 //............................................................................
QL 7:80bbc7a6c78c 70 void BSP_ledOn(void) {
QL 7:80bbc7a6c78c 71 LED_PORT->FIOSET = LED1_BIT;
QL 4:6189d844a1a2 72 }
QL 4:6189d844a1a2 73 //............................................................................
QL 7:80bbc7a6c78c 74 void BSP_ledOff(void) {
QL 7:80bbc7a6c78c 75 LED_PORT->FIOCLR = LED1_BIT;
QL 4:6189d844a1a2 76 }
QL 4:6189d844a1a2 77
QL 4:6189d844a1a2 78 //............................................................................
QL 4:6189d844a1a2 79 extern "C" void Q_onAssert(char_t const * const file, int_t const line) {
QL 4:6189d844a1a2 80 (void)file; // avoid compiler warning
QL 4:6189d844a1a2 81 (void)line; // avoid compiler warning
QL 4:6189d844a1a2 82 QF_INT_DISABLE(); // make sure that all interrupts are disabled
QL 4:6189d844a1a2 83 // light up all LEDs
QL 4:6189d844a1a2 84 LED_PORT->FIOSET = (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
QL 4:6189d844a1a2 85
QL 4:6189d844a1a2 86 for (;;) { // NOTE: replace the loop with reset for final version
QL 4:6189d844a1a2 87 }
QL 4:6189d844a1a2 88 }
QL 4:6189d844a1a2 89
QL 4:6189d844a1a2 90 //////////////////////////////////////////////////////////////////////////////
QL 4:6189d844a1a2 91 namespace QP {
QL 4:6189d844a1a2 92
QL 4:6189d844a1a2 93 //............................................................................
QL 4:6189d844a1a2 94 void QF::onStartup(void) {
QL 4:6189d844a1a2 95 // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate
QL 7:80bbc7a6c78c 96 (void)SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC);
QL 4:6189d844a1a2 97
QL 4:6189d844a1a2 98 // set priorities of all interrupts in the system...
QL 7:80bbc7a6c78c 99 NVIC_SetPriority(SysTick_IRQn, SYSTICK_PRIO);
QL 7:80bbc7a6c78c 100 NVIC_SetPriority(EINT0_IRQn, GPIOPORTA_PRIO);
QL 4:6189d844a1a2 101
QL 4:6189d844a1a2 102 NVIC_EnableIRQ(EINT0_IRQn);
QL 4:6189d844a1a2 103 }
QL 4:6189d844a1a2 104 //............................................................................
QL 4:6189d844a1a2 105 void QF::onCleanup(void) {
QL 4:6189d844a1a2 106 }
QL 4:6189d844a1a2 107 //............................................................................
QL 4:6189d844a1a2 108 #ifdef QK_PREEMPTIVE
QL 4:6189d844a1a2 109
QL 4:6189d844a1a2 110 void QK::onIdle(void) {
QL 4:6189d844a1a2 111
QL 4:6189d844a1a2 112 QF_INT_DISABLE();
QL 4:6189d844a1a2 113 LED_PORT->FIOSET = LED4_BIT; // turn the LED4 on
QL 4:6189d844a1a2 114 __NOP(); // delay a bit to see some light intensity
QL 4:6189d844a1a2 115 __NOP();
QL 4:6189d844a1a2 116 __NOP();
QL 4:6189d844a1a2 117 __NOP();
QL 4:6189d844a1a2 118 LED_PORT->FIOCLR = LED4_BIT; // turn the LED4 off
QL 4:6189d844a1a2 119 QF_INT_ENABLE();
QL 4:6189d844a1a2 120
QL 4:6189d844a1a2 121 #ifdef Q_SPY
QL 4:6189d844a1a2 122 if (DPP::l_qspy.writeable()) {
QL 4:6189d844a1a2 123
QL 4:6189d844a1a2 124 QF_INT_DISABLE();
QL 4:6189d844a1a2 125 uint16_t b = QS::getByte();
QL 4:6189d844a1a2 126 QF_INT_ENABLE();
QL 4:6189d844a1a2 127
QL 4:6189d844a1a2 128 if (b != QS_EOD) {
QL 4:6189d844a1a2 129 DPP::l_qspy.putc((uint8_t)b);
QL 4:6189d844a1a2 130 }
QL 4:6189d844a1a2 131 }
QL 4:6189d844a1a2 132 #else
QL 4:6189d844a1a2 133 // Put the CPU and peripherals to the low-power mode. You might need to
QL 4:6189d844a1a2 134 // customize the clock management for your application, see the datasheet
QL 4:6189d844a1a2 135 // for your particular Cortex-M3 MCU.
QL 4:6189d844a1a2 136 //
QL 4:6189d844a1a2 137 // Specifially for the mbed board, see the articles:
QL 4:6189d844a1a2 138 // * "Power Management" http://mbed.org/cookbook/Power-Management; and
QL 4:6189d844a1a2 139 // * "Interface Powerdown" at
QL 7:80bbc7a6c78c 140 // http://mbed.org/users/simon/notebook/interface-powerdown/
QL 4:6189d844a1a2 141 //
QL 4:6189d844a1a2 142 __WFI();
QL 4:6189d844a1a2 143 #endif
QL 4:6189d844a1a2 144 }
QL 4:6189d844a1a2 145
QL 4:6189d844a1a2 146 #else // non-preemptive Vanilla kernel
QL 4:6189d844a1a2 147
QL 4:6189d844a1a2 148 void QF::onIdle(void) { // NOTE: called with interrupts DISABLED
QL 4:6189d844a1a2 149
QL 4:6189d844a1a2 150 LED_PORT->FIOSET = LED4_BIT; // turn the LED4 on
QL 4:6189d844a1a2 151 __NOP(); // delay a bit to see some light intensity
QL 4:6189d844a1a2 152 __NOP();
QL 4:6189d844a1a2 153 __NOP();
QL 4:6189d844a1a2 154 __NOP();
QL 4:6189d844a1a2 155 LED_PORT->FIOCLR = LED4_BIT; // turn the LED4 off
QL 4:6189d844a1a2 156
QL 4:6189d844a1a2 157 #ifdef Q_SPY
QL 4:6189d844a1a2 158 QF_INT_ENABLE();
QL 4:6189d844a1a2 159 if (DPP::l_qspy.writeable()) {
QL 4:6189d844a1a2 160
QL 4:6189d844a1a2 161 QF_INT_DISABLE();
QL 4:6189d844a1a2 162 uint16_t b = QS::getByte();
QL 4:6189d844a1a2 163 QF_INT_ENABLE();
QL 4:6189d844a1a2 164
QL 4:6189d844a1a2 165 if (b != QS_EOD) {
QL 4:6189d844a1a2 166 DPP::l_qspy.putc((uint8_t)b);
QL 4:6189d844a1a2 167 }
QL 4:6189d844a1a2 168 }
QL 4:6189d844a1a2 169 #else
QL 4:6189d844a1a2 170 // Put the CPU and peripherals to the low-power mode. You might need to
QL 4:6189d844a1a2 171 // customize the clock management for your application, see the datasheet
QL 4:6189d844a1a2 172 // for your particular Cortex-M3 MCU.
QL 4:6189d844a1a2 173 //
QL 4:6189d844a1a2 174 // Specifially for the mbed board, see the articles:
QL 4:6189d844a1a2 175 // * "Power Management" http://mbed.org/cookbook/Power-Management; and
QL 4:6189d844a1a2 176 // * "Interface Powerdown" at
QL 7:80bbc7a6c78c 177 // http://mbed.org/users/simon/notebook/interface-powerdown/
QL 4:6189d844a1a2 178 //
QL 4:6189d844a1a2 179 __WFI();
QL 4:6189d844a1a2 180 QF_INT_ENABLE();
QL 4:6189d844a1a2 181 #endif
QL 4:6189d844a1a2 182 }
QL 4:6189d844a1a2 183
QL 4:6189d844a1a2 184 #endif // QK_PREEMPTIVE
QL 4:6189d844a1a2 185
QL 4:6189d844a1a2 186 //----------------------------------------------------------------------------
QL 4:6189d844a1a2 187 #ifdef Q_SPY
QL 4:6189d844a1a2 188 //............................................................................
QL 4:6189d844a1a2 189 bool QS::onStartup(void const *arg) {
QL 4:6189d844a1a2 190 static uint8_t qsBuf[6*256]; // buffer for Quantum Spy
QL 4:6189d844a1a2 191 initBuf(qsBuf, sizeof(qsBuf));
QL 4:6189d844a1a2 192
QL 4:6189d844a1a2 193 DPP::l_qspy.baud(QSPY_BAUD_RATE);
QL 4:6189d844a1a2 194
QL 4:6189d844a1a2 195 DPP::l_tickPeriod = SystemCoreClock / DPP::BSP_TICKS_PER_SEC;
QL 4:6189d844a1a2 196 DPP::l_tickTime = DPP::l_tickPeriod; // to start the timestamp at zero
QL 4:6189d844a1a2 197
QL 4:6189d844a1a2 198 // setup the QS filters...
QL 4:6189d844a1a2 199 QS_FILTER_ON(QS_ALL_RECORDS);
QL 4:6189d844a1a2 200
QL 4:6189d844a1a2 201 // QS_FILTER_OFF(QS_QEP_STATE_EMPTY);
QL 4:6189d844a1a2 202 // QS_FILTER_OFF(QS_QEP_STATE_ENTRY);
QL 4:6189d844a1a2 203 // QS_FILTER_OFF(QS_QEP_STATE_EXIT);
QL 4:6189d844a1a2 204 // QS_FILTER_OFF(QS_QEP_STATE_INIT);
QL 4:6189d844a1a2 205 // QS_FILTER_OFF(QS_QEP_INIT_TRAN);
QL 4:6189d844a1a2 206 // QS_FILTER_OFF(QS_QEP_INTERN_TRAN);
QL 4:6189d844a1a2 207 // QS_FILTER_OFF(QS_QEP_TRAN);
QL 4:6189d844a1a2 208 // QS_FILTER_OFF(QS_QEP_IGNORED);
QL 4:6189d844a1a2 209
QL 4:6189d844a1a2 210 // QS_FILTER_OFF(QS_QF_ACTIVE_ADD);
QL 4:6189d844a1a2 211 // QS_FILTER_OFF(QS_QF_ACTIVE_REMOVE);
QL 4:6189d844a1a2 212 // QS_FILTER_OFF(QS_QF_ACTIVE_SUBSCRIBE);
QL 4:6189d844a1a2 213 // QS_FILTER_OFF(QS_QF_ACTIVE_UNSUBSCRIBE);
QL 4:6189d844a1a2 214 // QS_FILTER_OFF(QS_QF_ACTIVE_POST_FIFO);
QL 4:6189d844a1a2 215 // QS_FILTER_OFF(QS_QF_ACTIVE_POST_LIFO);
QL 4:6189d844a1a2 216 // QS_FILTER_OFF(QS_QF_ACTIVE_GET);
QL 4:6189d844a1a2 217 // QS_FILTER_OFF(QS_QF_ACTIVE_GET_LAST);
QL 4:6189d844a1a2 218 // QS_FILTER_OFF(QS_QF_EQUEUE_INIT);
QL 4:6189d844a1a2 219 // QS_FILTER_OFF(QS_QF_EQUEUE_POST_FIFO);
QL 4:6189d844a1a2 220 // QS_FILTER_OFF(QS_QF_EQUEUE_POST_LIFO);
QL 4:6189d844a1a2 221 // QS_FILTER_OFF(QS_QF_EQUEUE_GET);
QL 4:6189d844a1a2 222 // QS_FILTER_OFF(QS_QF_EQUEUE_GET_LAST);
QL 4:6189d844a1a2 223 // QS_FILTER_OFF(QS_QF_MPOOL_INIT);
QL 4:6189d844a1a2 224 // QS_FILTER_OFF(QS_QF_MPOOL_GET);
QL 4:6189d844a1a2 225 // QS_FILTER_OFF(QS_QF_MPOOL_PUT);
QL 4:6189d844a1a2 226 // QS_FILTER_OFF(QS_QF_PUBLISH);
QL 4:6189d844a1a2 227 // QS_FILTER_OFF(QS_QF_NEW);
QL 4:6189d844a1a2 228 // QS_FILTER_OFF(QS_QF_GC_ATTEMPT);
QL 4:6189d844a1a2 229 // QS_FILTER_OFF(QS_QF_GC);
QL 4:6189d844a1a2 230 // QS_FILTER_OFF(QS_QF_TICK);
QL 4:6189d844a1a2 231 // QS_FILTER_OFF(QS_QF_TIMEEVT_ARM);
QL 4:6189d844a1a2 232 // QS_FILTER_OFF(QS_QF_TIMEEVT_AUTO_DISARM);
QL 4:6189d844a1a2 233 // QS_FILTER_OFF(QS_QF_TIMEEVT_DISARM_ATTEMPT);
QL 4:6189d844a1a2 234 // QS_FILTER_OFF(QS_QF_TIMEEVT_DISARM);
QL 4:6189d844a1a2 235 // QS_FILTER_OFF(QS_QF_TIMEEVT_REARM);
QL 4:6189d844a1a2 236 // QS_FILTER_OFF(QS_QF_TIMEEVT_POST);
QL 4:6189d844a1a2 237 QS_FILTER_OFF(QS_QF_CRIT_ENTRY);
QL 4:6189d844a1a2 238 QS_FILTER_OFF(QS_QF_CRIT_EXIT);
QL 4:6189d844a1a2 239 QS_FILTER_OFF(QS_QF_ISR_ENTRY);
QL 4:6189d844a1a2 240 QS_FILTER_OFF(QS_QF_ISR_EXIT);
QL 4:6189d844a1a2 241
QL 4:6189d844a1a2 242 return true; // return success
QL 4:6189d844a1a2 243 }
QL 4:6189d844a1a2 244 //............................................................................
QL 4:6189d844a1a2 245 void QS::onCleanup(void) {
QL 4:6189d844a1a2 246 }
QL 4:6189d844a1a2 247 //............................................................................
QL 4:6189d844a1a2 248 QSTimeCtr QS::onGetTime(void) { // invoked with interrupts locked
QL 4:6189d844a1a2 249 if ((SysTick->CTRL & 0x00000100U) == 0U) { // COUNTFLAG no set?
QL 4:6189d844a1a2 250 return DPP::l_tickTime - (QSTimeCtr)SysTick->VAL;
QL 4:6189d844a1a2 251 }
QL 4:6189d844a1a2 252 else { // the rollover occured, but the SysTick_ISR did not run yet
QL 4:6189d844a1a2 253 return DPP::l_tickTime + DPP::l_tickPeriod - (QSTimeCtr)SysTick->VAL;
QL 4:6189d844a1a2 254 }
QL 4:6189d844a1a2 255 }
QL 4:6189d844a1a2 256 //............................................................................
QL 4:6189d844a1a2 257 void QS::onFlush(void) {
QL 4:6189d844a1a2 258 uint16_t b;
QL 4:6189d844a1a2 259 QF_INT_DISABLE();
QL 4:6189d844a1a2 260 while ((b = QS::getByte()) != QS_EOD) {
QL 4:6189d844a1a2 261 while (!DPP::l_qspy.writeable()) { // wait until serial is writable
QL 4:6189d844a1a2 262 }
QL 4:6189d844a1a2 263 DPP::l_qspy.putc((uint8_t)b);
QL 4:6189d844a1a2 264 }
QL 4:6189d844a1a2 265 QF_INT_ENABLE();
QL 4:6189d844a1a2 266 }
QL 4:6189d844a1a2 267 #endif // Q_SPY
QL 4:6189d844a1a2 268 //----------------------------------------------------------------------------
QL 4:6189d844a1a2 269
QL 4:6189d844a1a2 270 } // namespace QP