Quantum Leaps / Mbed 2 deprecated qp_lwip

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bsp.cpp Source File

bsp.cpp

00001 //////////////////////////////////////////////////////////////////////////////
00002 // Product: BSP for lwIP example, mbed-LPC1768 board, QK kernel
00003 // Last Updated for Version: 4.1.06
00004 // Date of the Last Update:  Feb 18, 2011
00005 //
00006 //                    Q u a n t u m     L e a P s
00007 //                    ---------------------------
00008 //                    innovating embedded systems
00009 //
00010 // Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved.
00011 //
00012 // This software may be distributed and modified under the terms of the GNU
00013 // General Public License version 2 (GPL) as published by the Free Software
00014 // Foundation and appearing in the file GPL.TXT included in the packaging of
00015 // this file. Please note that GPL Section 2[b] requires that all works based
00016 // on this software must also be made publicly available under the terms of
00017 // the GPL ("Copyleft").
00018 //
00019 // Alternatively, this software may be distributed and modified under the
00020 // terms of Quantum Leaps commercial licenses, which expressly supersede
00021 // the GPL and are specifically designed for licensees interested in
00022 // retaining the proprietary status of their code.
00023 //
00024 // Contact information:
00025 // Quantum Leaps Web site:  http://www.quantum-leaps.com
00026 // e-mail:                  info@quantum-leaps.com
00027 //////////////////////////////////////////////////////////////////////////////
00028 #include "qp_port.h"                                    // QP port header file
00029 #include "dpp.h"                      // application events and active objects
00030 #include "bsp.h"                          // Board Support Package header file
00031 
00032 #include "LPC17xx.h"
00033 
00034 Q_DEFINE_THIS_FILE
00035 
00036 static uint32_t l_nTicks;
00037 
00038 enum ISR_Priorities {      // ISR priorities starting from the highest urgency
00039     SYSTICK_PRIO,
00040     ENET_PRIO,
00041     // ...
00042 };
00043 
00044 #ifdef Q_SPY
00045     #include "mbed.h"             // mbed is used only for the built-in serial
00046 
00047     QSTimeCtr l_tickTime;
00048     QSTimeCtr l_tickPeriod;
00049 
00050     #define QSPY_BAUD_RATE          115200
00051 
00052     Serial l_qspy(USBTX, USBRX);
00053 #endif
00054 
00055 //............................................................................
00056 extern "C" void SysTick_Handler(void) {
00057     QK_ISR_ENTRY();                // inform the QK kernel of entering the ISR
00058 
00059 #ifdef Q_SPY
00060     uint32_t volatile dummy = SysTick->CTRL; // clear the COUNTFLAG in SysTick
00061     l_tickTime += l_tickPeriod;              // account for the clock rollover
00062 #endif
00063 
00064     QF::tick();                               // process all armed time events
00065 
00066     QK_ISR_EXIT();                  // inform the QK kernel of exiting the ISR
00067 }
00068 
00069 //............................................................................
00070 void BSP_init(void) {
00071     SystemInit();                            // initialize the clocking system
00072 
00073                                                      // set LED port to output
00074     LED_PORT->FIODIR |= (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
00075     
00076                                                              // clear the LEDs
00077     LED_PORT->FIOCLR  = (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
00078 
00079     if (QS_INIT((void *)0) == 0) {       // initialize the QS software tracing
00080         Q_ERROR();
00081     }
00082 }
00083 //............................................................................
00084 void BSP_displyPhilStat(uint8_t n, char const *stat) {
00085                             // represent LEDs in a const array for convenience
00086     static uint32_t const led[] = { LED1_BIT, LED2_BIT, LED3_BIT, LED4_BIT };
00087     if (n < 2) {
00088         if (stat[0] == 'e') {
00089             LED_PORT->FIOSET = led[n];
00090         }
00091         else {
00092             LED_PORT->FIOCLR = led[n];
00093         }
00094     }
00095     
00096     QS_BEGIN(PHILO_STAT, AO_Philo[n])     // application-specific record begin
00097         QS_U8(1, n);                                     // Philosopher number
00098         QS_STR(stat);                                    // Philosopher status
00099     QS_END()
00100 }
00101 //............................................................................
00102 void QF::onStartup(void) {
00103                  // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate
00104     SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC);
00105 
00106                           // set priorities of all interrupts in the system...
00107     NVIC_SetPriority(SysTick_IRQn, SYSTICK_PRIO);
00108     NVIC_SetPriority(ENET_IRQn,    ENET_PRIO);
00109 
00110     NVIC_EnableIRQ(ENET_IRQn);                // enable the Ethernet Interrupt
00111 }
00112 //............................................................................
00113 void QF::onCleanup(void) {
00114 }
00115 //............................................................................
00116 void QK::onIdle(void) {
00117 
00118     QF_INT_LOCK(dummy);
00119     LED_PORT->FIOSET = LED4_BIT;                           // turn the LED4 on
00120     __NOP();                        // delay a bit to see some light intensity
00121     __NOP();
00122     __NOP();
00123     __NOP();
00124     LED_PORT->FIOCLR = LED4_BIT;                          // turn the LED4 off
00125     QF_INT_UNLOCK(dummy);
00126 
00127 #ifdef Q_SPY
00128     if (l_qspy.writeable()) {
00129         QF_INT_LOCK(dummy);
00130         uint16_t b = QS::getByte();
00131         QF_INT_UNLOCK(dummy);
00132         if (b != QS_EOD) {
00133             l_qspy.putc((uint8_t)b);
00134         }
00135     }
00136 #else    
00137     // Put the CPU and peripherals to the low-power mode. You might need to
00138     // customize the clock management for your application, see the datasheet
00139     // for your particular Cortex-M3 MCU.
00140     //
00141     // Specifially for the mbed board, see the articles:
00142     // * "Power Management" http://mbed.org/cookbook/Power-Management; and
00143     // * "Interface Powerdown" at 
00144     //   http://mbed.org/users/simon/notebook/interface-powerdown/
00145     // 
00146     __WFI();
00147 #endif
00148 }
00149 
00150 //............................................................................
00151 void Q_onAssert(char const Q_ROM * const Q_ROM_VAR file, int line) {
00152     (void)file;                                      // avoid compiler warning
00153     (void)line;                                      // avoid compiler warning
00154     QF_INT_LOCK(dummy);          // make sure that all interrupts are disabled
00155                                                           // light up all LEDs
00156     LED_PORT->FIOSET = (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
00157 
00158     for (;;) {          // NOTE: replace the loop with reset for final version
00159     }
00160 }
00161 //............................................................................
00162 // sys_now() is used in the lwIP stack
00163 extern "C" uint32_t sys_now(void) {
00164     return l_nTicks * (1000 / BSP_TICKS_PER_SEC);
00165 }
00166 
00167 //----------------------------------------------------------------------------
00168 #ifdef Q_SPY
00169 //............................................................................
00170 uint8_t QS::onStartup(void const *arg) {
00171     static uint8_t qsBuf[6*256];                     // buffer for Quantum Spy
00172     initBuf(qsBuf, sizeof(qsBuf));
00173     
00174     l_qspy.baud(QSPY_BAUD_RATE);
00175     
00176     l_tickPeriod = SystemCoreClock / BSP_TICKS_PER_SEC;
00177     l_tickTime   = l_tickPeriod;             // to start the timestamp at zero
00178 
00179                                                     // setup the QS filters...
00180     QS_FILTER_ON(QS_ALL_RECORDS);
00181 
00182     QS_FILTER_OFF(QS_QEP_STATE_EMPTY);
00183     QS_FILTER_OFF(QS_QEP_STATE_ENTRY);
00184     QS_FILTER_OFF(QS_QEP_STATE_EXIT);
00185     QS_FILTER_OFF(QS_QEP_STATE_INIT);
00186     QS_FILTER_OFF(QS_QEP_INIT_TRAN);
00187     QS_FILTER_OFF(QS_QEP_INTERN_TRAN);
00188     QS_FILTER_OFF(QS_QEP_TRAN);
00189     QS_FILTER_OFF(QS_QEP_IGNORED);
00190     QS_FILTER_OFF(QS_QEP_DISPATCH);
00191 
00192     QS_FILTER_OFF(QS_QF_ACTIVE_ADD);
00193     QS_FILTER_OFF(QS_QF_ACTIVE_REMOVE);
00194     QS_FILTER_OFF(QS_QF_ACTIVE_SUBSCRIBE);
00195     QS_FILTER_OFF(QS_QF_ACTIVE_UNSUBSCRIBE);
00196     QS_FILTER_OFF(QS_QF_ACTIVE_POST_FIFO);
00197     QS_FILTER_OFF(QS_QF_ACTIVE_POST_LIFO);
00198     QS_FILTER_OFF(QS_QF_ACTIVE_GET);
00199     QS_FILTER_OFF(QS_QF_ACTIVE_GET_LAST);
00200     QS_FILTER_OFF(QS_QF_EQUEUE_INIT);
00201     QS_FILTER_OFF(QS_QF_EQUEUE_POST_FIFO);
00202     QS_FILTER_OFF(QS_QF_EQUEUE_POST_LIFO);
00203     QS_FILTER_OFF(QS_QF_EQUEUE_GET);
00204     QS_FILTER_OFF(QS_QF_EQUEUE_GET_LAST);
00205     QS_FILTER_OFF(QS_QF_MPOOL_INIT);
00206     QS_FILTER_OFF(QS_QF_MPOOL_GET);
00207     QS_FILTER_OFF(QS_QF_MPOOL_PUT);
00208     QS_FILTER_OFF(QS_QF_PUBLISH);
00209     QS_FILTER_OFF(QS_QF_NEW);
00210     QS_FILTER_OFF(QS_QF_GC_ATTEMPT);
00211     QS_FILTER_OFF(QS_QF_GC);
00212     QS_FILTER_OFF(QS_QF_TICK);
00213     QS_FILTER_OFF(QS_QF_TIMEEVT_ARM);
00214     QS_FILTER_OFF(QS_QF_TIMEEVT_AUTO_DISARM);
00215     QS_FILTER_OFF(QS_QF_TIMEEVT_DISARM_ATTEMPT);
00216     QS_FILTER_OFF(QS_QF_TIMEEVT_DISARM);
00217     QS_FILTER_OFF(QS_QF_TIMEEVT_REARM);
00218     QS_FILTER_OFF(QS_QF_TIMEEVT_POST);
00219     QS_FILTER_OFF(QS_QF_INT_LOCK);
00220     QS_FILTER_OFF(QS_QF_INT_UNLOCK);
00221     QS_FILTER_OFF(QS_QF_ISR_ENTRY);
00222     QS_FILTER_OFF(QS_QF_ISR_EXIT);
00223 
00224     QS_FILTER_OFF(QS_QK_MUTEX_LOCK);
00225     QS_FILTER_OFF(QS_QK_MUTEX_UNLOCK);
00226     QS_FILTER_OFF(QS_QK_SCHEDULE);
00227     
00228     QS_FILTER_AO_OBJ(AO_LwIPMgr);
00229     QS_FILTER_AP_OBJ(AO_LwIPMgr);
00230 
00231     return (uint8_t)1;                                       // return success
00232 }
00233 //............................................................................
00234 void QS::onCleanup(void) {
00235 }
00236 //............................................................................
00237 QSTimeCtr QS::onGetTime(void) {              // invoked with interrupts locked
00238     if ((SysTick->CTRL & 0x00000100) == 0) {              // COUNTFLAG no set?
00239         return l_tickTime - (QSTimeCtr)SysTick->VAL;
00240     }
00241     else {        // the rollover occured, but the SysTick_ISR did not run yet
00242         return l_tickTime + l_tickPeriod - (QSTimeCtr)SysTick->VAL;
00243     }
00244 }
00245 //............................................................................
00246 void QS::onFlush(void) {
00247     uint16_t b;
00248     QF_INT_LOCK(dummy);
00249     while ((b = QS::getByte()) != QS_EOD) {
00250         while (!l_qspy.writeable()) {    // wait until serial port is writable
00251         }
00252         l_qspy.putc((uint8_t)b);
00253     }
00254     QF_INT_UNLOCK(dummy);
00255 }
00256 #endif                                                                // Q_SPY
00257 //----------------------------------------------------------------------------
00258 
00259 //////////////////////////////////////////////////////////////////////////////
00260 // NOTE01:
00261 // The User LED is used to visualize the idle loop activity. The brightness
00262 // of the LED is proportional to the frequency of invcations of the idle loop.
00263 // Please note that the LED is toggled with interrupts locked, so no interrupt
00264 // execution time contributes to the brightness of the User LED.
00265 //