void vMBMasterPortTimersDisable() { palClearPad(GPIOC, GPIOC_PIN9); //palClearPad(GPIOC, GPIOC_PIN10); chSysLockFromISR(); chVTResetI(&vt35); chVTResetI(&vtdelay); chVTResetI(&vtout); chSysUnlockFromISR(); }
/** * @brief Master transmission. * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] addr slave device address (7 bits) without R/W bit * @param[in] txbuf transmit data buffer pointer * @param[in] txbytes number of bytes to be transmitted * @param[out] rxbuf receive data buffer pointer * @param[in] rxbytes number of bytes to be received * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_INFINITE no timeout. * . * * @notapi */ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr, const uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, const uint8_t rxbytes, systime_t timeout) { VirtualTimer vt; /* Global timeout for the whole operation.*/ if (timeout != TIME_INFINITE) chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp); i2cp->addr = addr; i2cp->txbuf = txbuf; i2cp->txbytes = txbytes; i2cp->txidx = 0; i2cp->rxbuf = rxbuf; i2cp->rxbytes = rxbytes; i2cp->rxidx = 0; bscdevice_t *device = i2cp->device; device->slaveAddress = addr; device->dataLength = txbytes; device->status = CLEAR_STATUS; /* Enable Interrupts and start transfer.*/ device->control |= (BSC_INTT | BSC_INTD | START_WRITE); /* Is this really needed? there is an outer lock already */ chSysLock(); i2cp->thread = chThdSelf(); chSchGoSleepS(THD_STATE_SUSPENDED); if ((timeout != TIME_INFINITE) && chVTIsArmedI(&vt)) chVTResetI(&vt); chSysUnlock(); msg_t status = chThdSelf()->p_u.rdymsg; if (status == RDY_OK && rxbytes > 0) { /* The TIMEOUT_INFINITE prevents receive from setting up it's own timer.*/ status = i2c_lld_master_receive_timeout(i2cp, addr, rxbuf, rxbytes, TIME_INFINITE); if ((timeout != TIME_INFINITE) && chVTIsArmedI(&vt)) chVTResetI(&vt); } return status; }
/** * @brief Stops the interrupts and timers so sensors will stop * beeing serviced. The queued sensor reads are lost as * well. * * @param[in] srdp Pointer to the SensorReadDriver object. * * @return The operation status. * @retval MSG_OK The disabling of interrupts and starting of the * virtual timers was successful. * @retval MSG_RESET The driver was not in the correct state. * * @api */ msg_t SensorReadStop(SensorReadDriver *srdp) { size_t i; chDbgCheck(srdp != NULL); if (srdp->state == SRD_STARTED) { osalSysLock(); /* Disable interrupts for interrupt driven sensors */ for (i = 0; i < srdp->interrupt_sensor_cnt; i++) extChannelDisableI(&SRD_EXT_DRIVER, srdp->interrupt_sensor_ptr[i].interrupt_channel); /* Reset timers for polled driven sensors */ for (i = 0; i < srdp->polled_sensor_cnt; i++) chVTResetI(srdp->polled_sensor_ptr[i].polling_vt); osalSysUnlock(); /* Reset the mailbox */ chMBReset(&srdp->srd_mailbox); /* Everything OK, transverse the state */ srdp->state = SRD_STOPPED; return MSG_OK; } else return MSG_RESET; }
void App_t::LedBlink(uint32_t Duration_ms) { PinSet(LED_GPIO, LED_PIN); chSysLock() if(chVTIsArmedI(&TmrLed)) chVTResetI(&TmrLed); chVTSetI(&TmrLed, MS2ST(Duration_ms), LedTmrCallback, nullptr); chSysUnlock(); }
/** * @brief Transmits data via the I2C bus as master. * @details Number of receiving bytes must be 0 or more than 1 on STM32F1x. * This is hardware restriction. * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] addr slave device address * @param[in] txbuf pointer to the transmit buffer * @param[in] txbytes number of bytes to be transmitted * @param[out] rxbuf pointer to the receive buffer * @param[in] rxbytes number of bytes to be received * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval RDY_OK if the function succeeded. * @retval RDY_RESET if one or more I2C errors occurred, the errors can * be retrieved using @p i2cGetErrors(). * @retval RDY_TIMEOUT if a timeout occurred before operation end. <b>After a * timeout the driver must be stopped and restarted * because the bus is in an uncertain state</b>. * * @notapi */ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr, const uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes, systime_t timeout) { I2C_TypeDef *dp = i2cp->i2c; VirtualTimer vt; #if defined(STM32F1XX_I2C) chDbgCheck(((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))), "i2c_lld_master_transmit_timeout"); #endif /* Global timeout for the whole operation.*/ if (timeout != TIME_INFINITE) chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp); /* Releases the lock from high level driver.*/ chSysUnlock(); /* Initializes driver fields, LSB = 0 -> write.*/ i2cp->addr = addr << 1; i2cp->errors = 0; /* TX DMA setup.*/ dmaStreamSetMemory0(i2cp->dmatx, txbuf); dmaStreamSetTransactionSize(i2cp->dmatx, txbytes); /* RX DMA setup.*/ dmaStreamSetMemory0(i2cp->dmarx, rxbuf); dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); /* Waits until BUSY flag is reset and the STOP from the previous operation is completed, alternatively for a timeout condition.*/ while ((dp->SR2 & I2C_SR2_BUSY) || (dp->CR1 & I2C_CR1_STOP)) { chSysLock(); if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt)) return RDY_TIMEOUT; chSysUnlock(); } /* This lock will be released in high level driver.*/ chSysLock(); /* Atomic check on the timer in order to make sure that a timeout didn't happen outside the critical zone.*/ if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt)) return RDY_TIMEOUT; /* Starts the operation.*/ dp->CR2 |= I2C_CR2_ITEVTEN; dp->CR1 |= I2C_CR1_START; /* Waits for the operation completion or a timeout.*/ i2cp->thread = chThdSelf(); chSchGoSleepS(THD_STATE_SUSPENDED); if ((timeout != TIME_INFINITE) && chVTIsArmedI(&vt)) chVTResetI(&vt); return chThdSelf()->p_u.rdymsg; }
static msg_t spi_thread(void *p) { unsigned i; SPIDriver *spip = (SPIDriver *)p; VirtualTimer vt; uint8_t txbuf[256]; uint8_t rxbuf[256]; /* Prepare transmit pattern.*/ for (i = 0; i < sizeof(txbuf); i++) txbuf[i] = (uint8_t)i; /* Continuous transmission.*/ while (TRUE) { /* Starts a VT working as watchdog to catch a malfunction in the SPI driver.*/ chSysLock(); chVTSetI(&vt, MS2ST(10), tmo, NULL); chSysUnlock(); spiExchange(spip, sizeof(txbuf), txbuf, rxbuf); /* Stops the watchdog.*/ chSysLock(); if (chVTIsArmedI(&vt)) chVTResetI(&vt); chSysUnlock(); } }
static void doScheduleForLater(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param) { int delaySt = MY_US2ST(delayUs); if (delaySt <= 0) { /** * in case of zero delay, we should invoke the callback */ callback(param); return; } bool alreadyLocked = lockAnyContext(); scheduling->callback = callback; scheduling->param = param; int isArmed = chVTIsArmedI(&scheduling->timer); if (isArmed) { /** * timer reuse is normal for example in case of sudden RPM increase */ chVTResetI(&scheduling->timer); } #if EFI_SIMULATOR if (callback == (schfunc_t)&seTurnPinLow) { printf("setTime cb=seTurnPinLow p=%d\r\n", (int)param); } else { // printf("setTime cb=%d p=%d\r\n", (int)callback, (int)param); } #endif /* EFI_SIMULATOR */ chVTSetI(&scheduling->timer, delaySt, (vtfunc_t)timerCallback, scheduling); if (!alreadyLocked) { unlockAnyContext(); } }
/** * @brief Stops the timer. * @details If the timer was already stopped then the function has no effect. * * @param etp pointer to an initialized @p EvTimer structure. */ void evtStop(EvTimer *etp) { chSysLock(); if (chVTIsArmedI(&etp->et_vt)) chVTResetI(&etp->et_vt); chSysUnlock(); }
/* * This callback is invoked when a transmission has physically completed. */ static void txend2(UARTDriver *uartp) { (void)uartp; palSetPad(GPIOD, GPIOD_LED5); chSysLockFromISR(); chVTResetI(&vt5); chVTSetI(&vt5, MS2ST(200), led5off, NULL); chSysUnlockFromISR(); }
/* * This callback is invoked when a transmission has physically completed. */ static void txend2(UARTDriver *uartp) { (void)uartp; palClearPad(GPIOB, GPIOB_LED4); chSysLockFromISR(); chVTResetI(&vt1); chVTDoSetI(&vt1, MS2ST(5000), restart, NULL); chSysUnlockFromISR(); }
void vMBMasterPortTimersConvertDelayEnable() { /* Set current timer mode, don't change it.*/ vMBMasterSetCurTimerMode(MB_TMODE_CONVERT_DELAY); chSysLockFromISR(); chVTResetI(&vtdelay); chVTSetI(&vtdelay, MS2ST((uint32_t)MB_MASTER_DELAY_MS_CONVERT), timer_timeout_ind, NULL); chSysUnlockFromISR(); }
void vMBMasterPortTimersRespondTimeoutEnable() { //chprintf((BaseSequentialStream *)&itm_port, "%s\n", "TimeOut Enable"); //palSetPad(GPIOC, GPIOC_PIN10); /* Set current timer mode, don't change it.*/ chSysLockFromISR(); chVTResetI(&vtout); chVTSetI(&vtout, MS2ST((uint32_t)MB_MASTER_TIMEOUT_MS_RESPOND), timer_timeout_ind, NULL); chSysUnlockFromISR(); }
/* * This callback is invoked when a transmission has physically completed. */ static void txend2(UARTDriver *uartp) { (void)uartp; palClearPad(GPIOE, GPIOE_LED3_RED); chSysLockFromIsr(); if (chVTIsArmedI(&vt1)) chVTResetI(&vt1); chVTSetI(&vt1, MS2ST(5000), restart, NULL); chSysUnlockFromIsr(); }
/* * This callback is invoked when a transmission has physically completed. */ static void txend2(UARTDriver *uartp) { (void)uartp; palSetPad(IOPORT3, GPIOC_LED); chSysLockFromIsr(); if (chVTIsArmedI(&vt1)) chVTResetI(&vt1); chVTSetI(&vt1, MS2ST(5000), restart, NULL); chSysUnlockFromIsr(); }
/* * This callback is invoked when a receive buffer has been completely written. */ static void rxend(UARTDriver *uartp) { (void)uartp; /* Flashing the LED each time a character is received.*/ palSetPad(GPIOD, GPIOD_LED3); chSysLockFromISR(); chVTResetI(&vt3); chVTSetI(&vt3, MS2ST(200), led3off, NULL); chSysUnlockFromISR(); }
/* * This callback is invoked when a character is received but the application * was not ready to receive it, the character is passed as parameter. */ static void rxchar(UARTDriver *uartp, uint16_t c) { (void)uartp; (void)c; /* Flashing the LED each time a character is received.*/ palSetPad(GPIOB, GPIOB_LED4); chSysLockFromISR(); chVTResetI(&vt2); chVTDoSetI(&vt2, MS2ST(200), ledoff, NULL); chSysUnlockFromISR(); }
void vMBMasterPortTimersT35Enable() { //chprintf((BaseSequentialStream *)&itm_port, "%s\n", "T35 Enable"); /* Set current timer mode, don't change it.*/ vMBMasterSetCurTimerMode(MB_TMODE_T35); palSetPad(GPIOC, GPIOC_PIN9); chSysLockFromISR(); chVTResetI(&vt35); chVTSetI(&vt35, US2ST((uint32_t)2000), timer_timeout_ind, NULL); chSysUnlockFromISR(); }
void chVTSetAny(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { if (isIsrContext()) { chSysLockFromIsr() ; if (chVTIsArmedI(vtp)) chVTResetI(vtp); chVTSetI(vtp, time, vtfunc, par); chSysUnlockFromIsr() ; } else { chSysLock() ; if (chVTIsArmedI(vtp)) chVTResetI(vtp); chVTSetI(vtp, time, vtfunc, par); chSysUnlock() ; } }
/** * @brief Receives data via the I2C bus as master. * @details Number of receiving bytes must be more than 1 because of stm32 * hardware restrictions. * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] addr slave device address * @param[out] rxbuf pointer to the receive buffer * @param[in] rxbytes number of bytes to be received * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval RDY_OK if the function succeeded. * @retval RDY_RESET if one or more I2C errors occurred, the errors can * be retrieved using @p i2cGetErrors(). * @retval RDY_TIMEOUT if a timeout occurred before operation end. <b>After a * timeout the driver must be stopped and restarted * because the bus is in an uncertain state</b>. * * @notapi */ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr, uint8_t *rxbuf, size_t rxbytes, systime_t timeout) { I2C_TypeDef *dp = i2cp->i2c; VirtualTimer vt; msg_t rdymsg; chDbgCheck((rxbytes > 1), "i2c_lld_master_receive_timeout"); /* Global timeout for the whole operation.*/ chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp); /* Releases the lock from high level driver.*/ chSysUnlock(); /* Initializes driver fields, LSB = 1 -> receive.*/ i2cp->addr = (addr << 1) | 0x01; i2cp->errors = 0; /* RX DMA setup.*/ dmaStreamSetMemory0(i2cp->dmarx, rxbuf); dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); /* Waits until BUSY flag is reset and the STOP from the previous operation is completed, alternatively for a timeout condition.*/ while ((dp->SR2 & I2C_SR2_BUSY) || (dp->CR1 & I2C_CR1_STOP)) { if (!chVTIsArmedI(&vt)) { chSysLock(); return RDY_TIMEOUT; } } /* This lock will be released in high level driver.*/ chSysLock(); /* Atomic check on the timer in order to make sure that a timeout didn't happen outside the critical zone.*/ if (!chVTIsArmedI(&vt)) return RDY_TIMEOUT; /* Starts the operation.*/ dp->CR2 |= I2C_CR2_ITEVTEN; dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK; /* Waits for the operation completion or a timeout.*/ i2cp->thread = chThdSelf(); chSchGoSleepS(THD_STATE_SUSPENDED); rdymsg = chThdSelf()->p_u.rdymsg; if (rdymsg != RDY_TIMEOUT) chVTResetI(&vt); return rdymsg; }
/* * This callback is invoked when a character is received but the application * was not ready to receive it, the character is passed as parameter. */ static void rxchar(UARTDriver *uartp, uint16_t c) { (void)uartp; (void)c; /* Flashing the LED each time a character is received.*/ palSetPad(GPIOE, GPIOE_LED3_RED); chSysLockFromIsr(); if (chVTIsArmedI(&vt2)) chVTResetI(&vt2); chVTSetI(&vt2, MS2ST(200), ledoff, NULL); chSysUnlockFromIsr(); }
/* Triggered when the button is pressed or released. The LED4 is set to ON.*/ static void extcb1(EXTDriver *extp, expchannel_t channel) { static virtual_timer_t vt4; (void)extp; (void)channel; palSetPad(GPIOA, GPIOA_LED_GREEN); chSysLockFromISR(); chVTResetI(&vt4); /* LED4 set to OFF after 200mS.*/ chVTSetI(&vt4, MS2ST(200), led4off, NULL); chSysUnlockFromISR(); }
static void bmk10_execute(void) { static VirtualTimer vt1, vt2; uint32_t n = 0; test_wait_tick(); test_start_timer(1000); do { chSysLock(); chVTSetI(&vt1, 1, tmo, NULL); chVTSetI(&vt2, 10000, tmo, NULL); chVTResetI(&vt1); chVTResetI(&vt2); chSysUnlock(); n++; #if defined(SIMULATOR) ChkIntSources(); #endif } while (!test_timer_done); test_print("--- Score : "); test_printn(n * 2); test_println(" timers/S"); }
void statusLedPulse(int led, systime_t duration) { chSysLock(); switch(led) { case 1: if (chVTIsArmedI(&vt1)) chVTResetI(&vt1); else palSetPad(IOPORT2, GPIOB_LED1); chVTSetI(&vt1, duration, ledoff_1, NULL); break; case 2: if (chVTIsArmedI(&vt2)) chVTResetI(&vt2); else palSetPad(IOPORT2, GPIOB_LED2); chVTSetI(&vt2, duration, ledoff_2, NULL); break; } chSysUnlock(); }
/* Triggered when the button is pressed or released. The LED4 is set to ON.*/ static void extcb1(EXTDriver *extp, expchannel_t channel) { static VirtualTimer vt4; (void)extp; (void)channel; palSetPad(GPIOC, GPIOC_LED4); chSysLockFromIsr(); if (chVTIsArmedI(&vt4)) chVTResetI(&vt4); /* LED4 set to OFF after 200mS.*/ chVTSetI(&vt4, MS2ST(200), led4off, NULL); chSysUnlockFromIsr(); }
void LedRGB_t::IStartSequenceI(const LedChunk_t *PLedChunk) { // Reset timer if(chVTIsArmedI(&ITmr)) chVTResetI(&ITmr); // Process the sequence while(PLedChunk != nullptr) { // Uart.Printf("\rCh %u", PLedChunk->ChunkSort); switch(PLedChunk->ChunkSort) { case csSetColor: if(ICurrColor != PLedChunk->Color) { if(PLedChunk->SmoothVar == 0) { // If smooth time is zero, SetColor(PLedChunk->Color); // set color now, PLedChunk++; // and goto next chunk } else { // Adjust color ICurrColor.Adjust(&PLedChunk->Color); ISetCurrent(); // Check if completed now if(ICurrColor == PLedChunk->Color) PLedChunk++; else { // Not completed // Calculate time to next adjustment uint32_t DelayR = (ICurrColor.Red == PLedChunk->Color.Red )? 0 : ICalcDelay(ICurrColor.Red, PLedChunk->SmoothVar); uint32_t DelayG = (ICurrColor.Green == PLedChunk->Color.Green)? 0 : ICalcDelay(ICurrColor.Green, PLedChunk->SmoothVar); uint32_t DelayB = (ICurrColor.Blue == PLedChunk->Color.Blue )? 0 : ICalcDelay(ICurrColor.Blue, PLedChunk->SmoothVar); uint32_t Delay = DelayR; if(DelayG > Delay) Delay = DelayG; if(DelayB > Delay) Delay = DelayB; chVTSetI(&ITmr, MS2ST(Delay), LedTmrCallback, (void*)PLedChunk); return; } // Not completed } // if time > 256 } // if color is different else PLedChunk++; // Color is the same, goto next chunk break; case csWait: // Start timer, pointing to next chunk chVTSetI(&ITmr, MS2ST(PLedChunk->Time_ms), LedTmrCallback, (void*)(PLedChunk+1)); return; break; case csJump: PLedChunk = IPStartChunk + PLedChunk->ChunkToJumpTo; break; case csEnd: IPStartChunk = nullptr; return; break; } // switch } // while }
/** * @brief Puts the current thread to sleep into the specified state with * timeout specification. * @details The thread goes into a sleeping state, if it is not awakened * explicitly within the specified timeout then it is forcibly * awakened with a @p RDY_TIMEOUT low level message. The possible * @ref thread_states are defined into @p threads.h. * * @param[in] newstate the new thread state * @param[in] time the number of ticks before the operation timeouts, the * special values are handled as follow: * - @a TIME_INFINITE the thread enters an infinite sleep * state, this is equivalent to invoking * @p chSchGoSleepS() but, of course, less efficient. * - @a TIME_IMMEDIATE this value is not allowed. * . * @return The wakeup message. * @retval RDY_TIMEOUT if a timeout occurs. * * @sclass */ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { if (TIME_INFINITE != time) { VirtualTimer vt; chVTSetI(&vt, time, wakeup, currp); chSchGoSleepS(newstate); if (chVTIsArmedI(&vt)) chVTResetI(&vt); } else chSchGoSleepS(newstate); return currp->p_u.rdymsg; }
static void adc_end_cb(ADCDriver *adcp, adcsample_t *buffer, size_t n) { (void)adcp; (void)n; /* * The bandgap value represents the ADC reading for 1.0V */ uint16_t sensor = buffer[0]; uint16_t bandgap = buffer[1]; /* * The v25 value is the voltage reading at 25C, it comes from the ADC * electricals table in the processor manual. V25 is in millivolts. */ int32_t v25 = 716; /* * The m value is slope of the temperature sensor values, again from * the ADC electricals table in the processor manual. * M in microvolts per degree. */ int32_t m = 1620; /* * Divide the temperature sensor reading by the bandgap to get * the voltage for the ambient temperature in millivolts. */ int32_t vamb = (sensor * 1000) / bandgap; /* * This formula comes from the reference manual. * Temperature is in millidegrees C. */ int32_t delta = (((vamb - v25) * 1000000) / m); int32_t temp = 25000 - delta; palSetPad(TEENSY_PIN13_IOPORT, TEENSY_PIN13); chSysLockFromISR(); chVTResetI(&vt); if (temp < 19000) { chVTSetI(&vt, MS2ST(10), ledoff, NULL); } else if (temp > 28000) { chVTSetI(&vt, MS2ST(20), ledoff, NULL); } else { chVTSetI(&vt, MS2ST(40), ledoff, NULL); } chSysUnlockFromISR(); }
void chVTSetAny(virtual_timer_t *vtp, systime_t time, vtfunc_t vtfunc, void *par) { bool wasLocked = lockAnyContext(); /** * todo: this could be simplified once we migrate to ChibiOS 3.0 * See http://www.chibios.org/dokuwiki/doku.php?id=chibios:howtos:porting_from_2_to_3 */ if (chVTIsArmedI(vtp)) { chVTResetI(vtp); } chVTSetI(vtp, time, vtfunc, par); if (!wasLocked) { unlockAnyContext(); } }
/* Triggered when the button is pressed or released. The LED5 is set to ON.*/ static void extcb1(EXTDriver *extp, expchannel_t channel) { static virtual_timer_t vt4; (void)extp; (void)channel; palSetPad(GPIOE, GPIOE_LED10_RED); chSysLockFromISR(); /* Timer reset, if still active.*/ chVTResetI(&vt4); /* LED4 set to OFF after 200mS.*/ chVTSetI(&vt4, MS2ST(200), led5off, NULL); chSysUnlockFromISR(); }
/** * @brief Disables the MMC peripheral. * * @param[in] mmcp pointer to the @p MMCDriver object * * @api */ void mmcStop(MMCDriver *mmcp) { chDbgCheck(mmcp != NULL, "mmcStop"); chSysLock(); chDbgAssert((mmcp->state != MMC_UNINIT) && (mmcp->state != MMC_READING) && (mmcp->state != MMC_WRITING), "mmcStop(), #1", "invalid state"); if (mmcp->state != MMC_STOP) { mmcp->state = MMC_STOP; chVTResetI(&mmcp->vt); } chSysUnlock(); spiStop(mmcp->spip); }