////////////////////////////////////////////////////////////////////////////// // Product: BSP for DPP example, QK, TMS320C5515 eZdsp USB stick // Last Updated for Version: 4.5.00 // Date of the Last Update: May 20, 2012 // // Q u a n t u m L e a P s // --------------------------- // innovating embedded systems // // Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved. // // This program is open source software: you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation, either version 2 of the License, or // (at your option) any later version. // // Alternatively, this program may be distributed and modified under the // terms of Quantum Leaps commercial licenses, which expressly supersede // the GNU General Public License and are specifically designed for // licensees interested in retaining the proprietary status of their code. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // Contact information: // Quantum Leaps Web sites: http://www.quantum-leaps.com // http://www.state-machine.com // e-mail: info@quantum-leaps.com ////////////////////////////////////////////////////////////////////////////// #include "qp_port.h" #include "dpp.h" #include "bsp.h" extern "C" { #include "csl_intc.h" #include "csl_pll.h" #include "csl_gpio.h" #include "cslr_tim.h" #include "cslr_sysctrl.h" } Q_DEFINE_THIS_FILE // CPU clock speed (100MHz) #define CPU_CLOCK_HZ 100000000U static uint16_t const l_userLED[] = { CSL_GPIO_PIN17, CSL_GPIO_PIN16, CSL_GPIO_PIN15, CSL_GPIO_PIN14 }; #define ULED(n_) ((CSL_GpioPinNum)l_userLED[n_]) #define ULED_ON 0U #define ULED_OFF 1U static CSL_GpioObj l_gpioObj; // User LEDs static void ULED_init(void); static inline void ULED_set(uint16_t n, uint16_t state) { GPIO_write(&l_gpioObj, (CSL_GpioPinNum)l_userLED[n], state); } // System LED #define SLED_ON() asm(" bit(ST1, ST1_XF) = #1") #define SLED_OFF() asm(" bit(ST1, ST1_XF) = #0") extern "C" void VECSTART(void); #ifdef Q_SPY #include "csl_uart.h" #define UART_BAUD_RATE 115200U #define UART_FIFO_DEPTH 16U static CSL_UartObj l_uartObj; uint8_t const l_TINT_isr = 0U; enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER }; #endif //............................................................................ extern "C" interrupt void TINT_isr(void) { CSL_SYSCTRL_REGS->TIAFR |= 0x0001U; // clear Timer0 bit QK_ISR_ENTRY(); // inform the QK kernel about ISR entry QF::TICK(&l_TINT_isr); // handle the QF time events QK_ISR_EXIT(); // inform the QK kernel about ISR exit } //............................................................................ extern "C" interrupt void RTC_isr(void) { static QEvt const testEvt = { MAX_SIG, 0U, 0U }; //CSL_RTC_REGS->RTCINTFL = 0x01U; // clear the interrupt source QK_ISR_ENTRY(); // inform the QK kernel about ISR entry AO_Table->POST(&testEvt, 0); // post a test event to Table QK_ISR_EXIT(); // inform the QK kernel about ISR exit } //............................................................................ // Illegal operation TRAP extern "C" interrupt void illegal_isr(void) { Q_ERROR(); // assert an error } //............................................................................ void BSP_init(void) { PLL_Config pllCfg_100MHz = { 0x8BE8U, 0x8000U, 0x0806U, 0x0000U }; PLL_Obj pllObj; uint16_t i; PLL_init(&pllObj, CSL_PLL_INST_0); PLL_reset(&pllObj); PLL_config(&pllObj, &pllCfg_100MHz); CSL_SYSCTRL_REGS->PCGCR1 = 0U; // enable clocks to all peripherals CSL_SYSCTRL_REGS->PCGCR2 = 0U; CSL_SYSCTRL_REGS->EBSR = 0x1800U; // configure I/O muxing CSL_SYSCTRL_REGS->PSRCR = 0x0020U; // reset all peripherals CSL_SYSCTRL_REGS->PRCR = 0x00BFU; ULED_init(); // configure the User LEDs... IRQ_globalDisable(); IRQ_disableAll(); // disable all the interrupts IRQ_clearAll(); // clear any pending interrupts IRQ_setVecs((uint32_t)&VECSTART); // set the vector table for (i = 1U; i < 32U; ++i) { // pre-fill the Vector table IRQ_plug(i, &illegal_isr); // with illegal ISR } // plug in all ISRs into the vector table... IRQ_plug(TINT_EVENT, &TINT_isr); IRQ_plug(RTC_EVENT, &RTC_isr); // ... QF_zero(); // clear the QF variables, see NOTE01 if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing Q_ERROR(); } QS_OBJ_DICTIONARY(&l_TINT_isr); } //............................................................................ void QF::onStartup(void) { // configuration of Timer0 as the system clock tick... CSL_TIM_0_REGS->TCR = 0x802EU; // autoReload | prescaler = 4096 (1011) CSL_TIM_0_REGS->TIMPRD1 = (CPU_CLOCK_HZ / 4096U) / BSP_TICKS_PER_SEC; CSL_TIM_0_REGS->TIMPRD2 = 0U; CSL_TIM_0_REGS->TIMCNT1 = 0U; CSL_TIM_0_REGS->TIMCNT2 = 0U; CSL_SYSCTRL_REGS->TIAFR = 0x0007U; // clear timer aggregation reg. CSL_TIM_0_REGS->TCR |= 0x0001U; // start Timer0 IRQ_enable(TINT_EVENT); // enable the TINT interrupt // setup the RTC interrupt for testing CSL_RTC_REGS->RTCINTEN = 1U; // enable RTC interrupts CSL_RTC_REGS->RTCINTREG = 1U; // enable millisecond periodic interrupt IRQ_enable(RTC_EVENT); } //............................................................................ void QF::onCleanup(void) { GPIO_close(&l_gpioObj); } //............................................................................ void QK::onIdle(void) { QF_INT_DISABLE(); SLED_ON(); // switch the System LED on and off asm(" nop"); asm(" nop"); asm(" nop"); asm(" nop"); SLED_OFF(); QF_INT_ENABLE(); #ifdef Q_SPY if (CSL_FEXT(l_uartObj.uartRegs->LSR, UART_LSR_THRE)) { QF_INT_DISABLE(); uint16_t b = QS::getByte(); QF_INT_ENABLE(); if (b != QS_EOD) { // not End-Of-Data? CSL_FSET(l_uartObj.uartRegs->THR, 7U, 0U, b); } } #elif defined NDEBUG // Put the CPU and peripherals to the low-power mode. // you might need to customize the clock management for your application, // see the datasheet for your particular TMS320C5500 device. // asm(" IDLE"); #endif } //............................................................................ void BSP_displyPhilStat(uint8_t n, char const *stat) { if (n < Q_DIM(l_userLED)) { ULED_set(n, (stat[0] == 'e') ? ULED_ON : ULED_OFF); } QS_BEGIN(PHILO_STAT, AO_Philo[n]) // application-specific record begin QS_U8(1, n); // Philosopher number QS_STR(stat); // Philosopher status QS_END() } //............................................................................ void BSP_busyDelay(void) { // implement some busy-waiting dealy to stress-test the DPP application } //---------------------------------------------------------------------------- void Q_onAssert(char const Q_ROM * const Q_ROM_VAR file, int line) { // Next two lines are for debug only to halt the processor here. // YOU need to change this policy for the production release! // QF_INT_DISABLE(); for(;;) { } } //............................................................................ static void ULED_init(void) { CSL_Status status; CSL_GpioPinConfig config; // configure the User LEDs... CSL_FINST(CSL_SYSCTRL_REGS->EBSR, SYS_EBSR_SP0MODE, MODE2); GPIO_open(&l_gpioObj, &status); GPIO_reset(&l_gpioObj); config.direction = CSL_GPIO_DIR_OUTPUT; config.trigger = CSL_GPIO_TRIG_CLEAR_EDGE; config.pinNum = (CSL_GpioPinNum)l_userLED[0]; GPIO_configBit(&l_gpioObj, &config); GPIO_write(&l_gpioObj, (CSL_GpioPinNum)l_userLED[0], ULED_OFF); config.pinNum = (CSL_GpioPinNum)l_userLED[1]; GPIO_configBit(&l_gpioObj, &config); GPIO_write(&l_gpioObj, (CSL_GpioPinNum)l_userLED[1], ULED_OFF); config.pinNum = (CSL_GpioPinNum)l_userLED[2]; GPIO_configBit(&l_gpioObj, &config); GPIO_write(&l_gpioObj, (CSL_GpioPinNum)l_userLED[2], ULED_OFF); config.pinNum = (CSL_GpioPinNum)l_userLED[3]; GPIO_configBit(&l_gpioObj, &config); GPIO_write(&l_gpioObj, (CSL_GpioPinNum)l_userLED[3], ULED_OFF); } //--------------------------------------------------------------------------- #ifdef Q_SPY //............................................................................ uint8_t QS::onStartup(void const *arg) { static uint8_t qsBuf[2*256]; // buffer for Quantum Spy CSL_UartSetup uartSetup; initBuf(qsBuf, sizeof(qsBuf)); uartSetup.clkInput = CPU_CLOCK_HZ; // input clock freq in Hz uartSetup.baud = UART_BAUD_RATE; // baud rate uartSetup.wordLength = CSL_UART_WORD8; // word length of 8 uartSetup.stopBits = 0; // to generate 1 stop bit uartSetup.parity = CSL_UART_DISABLE_PARITY; // disable parity uartSetup.fifoControl = CSL_UART_FIFO_DMA1_DISABLE_TRIG01; //enable FIFO uartSetup.loopBackEnable = CSL_UART_NO_LOOPBACK; // no loopback uartSetup.afeEnable = CSL_UART_NO_AFE; // no auto flow control uartSetup.rtsEnable = CSL_UART_NO_RTS; // no RTS UART_init(&l_uartObj, CSL_UART_INST_0, UART_POLLED); // init. UART oject CSL_SYSCTRL_REGS->EBSR = 0x1800U; // re-configure I/O muxing UART_setup(&l_uartObj, &uartSetup); // configure UART registers // initialize the CPU Timer 1 used for QS timestamp CSL_TIM_1_REGS->TCR = 0U; // stop Timer1 CSL_TIM_1_REGS->TIMPRD1 = ~0U; CSL_TIM_1_REGS->TIMPRD2 = ~0U; CSL_TIM_1_REGS->TIMCNT1 = ~0U; CSL_TIM_1_REGS->TIMCNT2 = ~0U; CSL_TIM_1_REGS->TCR = 0x801BU; // autoReload | prescaler = 128 // setup the QS filters... QS_FILTER_ON(QS_SIG_DICTIONARY); QS_FILTER_ON(QS_OBJ_DICTIONARY); QS_FILTER_ON(QS_FUN_DICTIONARY); QS_FILTER_ON(QS_QEP_STATE_EMPTY); QS_FILTER_ON(QS_QEP_STATE_ENTRY); QS_FILTER_ON(QS_QEP_STATE_EXIT); QS_FILTER_ON(QS_QEP_STATE_INIT); QS_FILTER_ON(QS_QEP_INIT_TRAN); QS_FILTER_ON(QS_QEP_INTERN_TRAN); QS_FILTER_ON(QS_QEP_TRAN); QS_FILTER_ON(QS_QEP_IGNORED); // QS_FILTER_ON(QS_QF_ACTIVE_ADD); // QS_FILTER_ON(QS_QF_ACTIVE_REMOVE); // QS_FILTER_ON(QS_QF_ACTIVE_SUBSCRIBE); // QS_FILTER_ON(QS_QF_ACTIVE_UNSUBSCRIBE); // QS_FILTER_ON(QS_QF_ACTIVE_POST_FIFO); // QS_FILTER_ON(QS_QF_ACTIVE_POST_LIFO); // QS_FILTER_ON(QS_QF_ACTIVE_GET); // QS_FILTER_ON(QS_QF_ACTIVE_GET_LAST); // QS_FILTER_ON(QS_QF_EQUEUE_INIT); // QS_FILTER_ON(QS_QF_EQUEUE_POST_FIFO); // QS_FILTER_ON(QS_QF_EQUEUE_POST_LIFO); // QS_FILTER_ON(QS_QF_EQUEUE_GET); // QS_FILTER_ON(QS_QF_EQUEUE_GET_LAST); // QS_FILTER_ON(QS_QF_MPOOL_INIT); // QS_FILTER_ON(QS_QF_MPOOL_GET); // QS_FILTER_ON(QS_QF_MPOOL_PUT); // QS_FILTER_ON(QS_QF_PUBLISH); // QS_FILTER_ON(QS_QF_NEW); // QS_FILTER_ON(QS_QF_GC_ATTEMPT); // QS_FILTER_ON(QS_QF_GC); // QS_FILTER_ON(QS_QF_TICK); // QS_FILTER_ON(QS_QF_TIMEEVT_ARM); // QS_FILTER_ON(QS_QF_TIMEEVT_AUTO_DISARM); // QS_FILTER_ON(QS_QF_TIMEEVT_DISARM_ATTEMPT); // QS_FILTER_ON(QS_QF_TIMEEVT_DISARM); // QS_FILTER_ON(QS_QF_TIMEEVT_REARM); // QS_FILTER_ON(QS_QF_TIMEEVT_POST); // QS_FILTER_ON(QS_QF_CRIT_ENTRY); // QS_FILTER_ON(QS_QF_CRIT_EXIT); // QS_FILTER_ON(QS_QF_ISR_ENTRY); // QS_FILTER_ON(QS_QF_ISR_EXIT); QS_FILTER_ON(PHILO_STAT); return (uint8_t)1; // return success } //............................................................................ void QS::onCleanup(void) { } //............................................................................ QSTimeCtr QS::onGetTime(void) { // invoked with interrupts disabled uint32_t tmr32; tmr32 = (uint32_t)CSL_TIM_1_REGS->TIMCNT2 << 16; tmr32 |= (uint32_t)CSL_TIM_1_REGS->TIMCNT1; return (QSTimeCtr)(0xFFFFFFFFUL - tmr32); } //............................................................................ void QS::onFlush(void) { uint16_t b; while ((b = getByte()) != QS_EOD) { // while not End-Of-Data... while (!CSL_FEXT(l_uartObj.uartRegs->LSR, UART_LSR_THRE)) { } CSL_FSET(l_uartObj.uartRegs->THR, 7U, 0U, b); // output the byte } } #endif // Q_SPY ////////////////////////////////////////////////////////////////////////////// // NOTE01: // The standard TI startup code (c_int00) does NOT zero the uninitialized // variables, as required by the C-standard. Since QP relies on the clearing // of the static uninitialized variables, the critical QP objects are cleared // explicitly in this BSP. //