Ejemplo n.º 1
0
/**
 * @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;
}
Ejemplo n.º 2
0
/**
 * @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;
}
Ejemplo n.º 3
0
/**
 * @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;
}
Ejemplo n.º 4
0
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();
	}
}
Ejemplo n.º 5
0
Archivo: main.cpp Proyecto: Kreyl/nute
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();
}
Ejemplo n.º 6
0
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();
  }
}
Ejemplo n.º 7
0
/**
 * @brief Starts the timer
 * @details If the timer was already running then the function has no effect.
 *
 * @param etp pointer to an initialized @p EvTimer structure.
 */
void evtStart(EvTimer *etp) {

  chSysLock();

  if (!chVTIsArmedI(&etp->et_vt))
    chVTSetI(&etp->et_vt, etp->et_interval, tmrcb, etp);

  chSysUnlock();
}
Ejemplo n.º 8
0
/**
 * @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();
}
Ejemplo n.º 9
0
/*
 * 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();
}
Ejemplo n.º 10
0
/*
 * 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();
}
Ejemplo n.º 11
0
/* Triggered when the button is pressed or released. The LED is set to ON.*/
static void extcb1(EXTDriver *extp, expchannel_t channel) {

  (void)extp;
  (void)channel;
  palClearPad(GPIOC, GPIOC_LED);
  chSysLockFromIsr();
  if (!chVTIsArmedI(&vt))
    chVTSetI(&vt, MS2ST(200), ledoff, NULL);
  chSysUnlockFromIsr();
}
Ejemplo n.º 12
0
/**
 * @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) {
  LPC_I2C_TypeDef *dp = i2cp->i2c;
  VirtualTimer vt;

  i2cp->addr = addr << 1;
  /* 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 */
  i2cp->errors = 0;
  i2cp->txbuf = txbuf;
  i2cp->txbytes = txbytes;
  i2cp->rxbuf = rxbuf;
  i2cp->rxbytes = rxbytes;

  /* 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->CONSET = I2C_CONSET_STA;

  /* 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;
}
Ejemplo n.º 13
0
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()
		;
	}
}
Ejemplo n.º 14
0
/*
 * 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();
}
Ejemplo n.º 15
0
/* 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();
}
Ejemplo n.º 16
0
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();
}
Ejemplo n.º 17
0
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
}
Ejemplo n.º 18
0
/**
 * @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;
}
Ejemplo n.º 19
0
/*
 * Note that this packet is stored and sent in another thread after a delay. The delay is done
 * in case that this packet is a request from the (Qt) client, which means that more requests
 * can come within a short time. We want to give the additional requests a chance to arrive
 * before blocking the RF channel by sending the response.
 */
void comm_cc2520_send_packet(uint8_t *data, uint8_t len) {
	memcpy(tx_buffer[tx_slot_write], data, len);
	tx_slot_len[tx_slot_write] = len;

	tx_slot_write++;
	if (tx_slot_write >= TX_BUFFER_SLOTS) {
		tx_slot_write = 0;
	}

	chSysLock();
	if (!chVTIsArmedI(&vt)) {
		chVTSetI(&vt, US2ST(TX_DELAY_US), wakeup_tx, NULL);
	}
	chSysUnlock();
}
Ejemplo n.º 20
0
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();
	}
}
Ejemplo n.º 21
0
/**
 * @brief Plays a tone asynchronously.
 *
 * @param[in] freq approximated tone frequency
 * @param[in] duration tone duration in systicks
 */
void buzzPlay(uint32_t freq, systime_t duration) {
  static VirtualTimer bvt;
  TC *tc = T1Base;

  chSysLock();

  if (chVTIsArmedI(&bvt)) {             /* If a sound is already being  */
    chVTResetI(&bvt);                   /* played then aborts it.       */
    StopCounter(tc);
  }

  tc->TC_MR0 = tc->TC_MR1 = (PCLK / (freq * 2));
  StartCounter(tc);
  chVTSetI(&bvt, duration, stop, tc);

  chSysUnlock();
}
Ejemplo n.º 22
0
/*! Triggered when the WKUP button is pressed or released. The LED is set to ON.
 *
 * Challenge: Add de-bouncing
 */
void extdetail_wkup_btn(EXTDriver *extp, expchannel_t channel) {
	static VirtualTimer vt4;

	(void)extp;
	(void)channel;

	palClearPad(GPIOC, GPIOC_LED);
	chSysLockFromIsr();
	chEvtBroadcastI(&extdetail_wkup_event);

	if (chVTIsArmedI(&vt4))
		chVTResetI(&vt4);

	/* LED4 set to OFF after 500mS.*/
	chVTSetI(&vt4, MS2ST(500), green_led_off, NULL);
	chSysUnlockFromIsr();
}
Ejemplo n.º 23
0
/**
 * @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 MSG_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 MSG_TIMEOUT  if a timeout occurs.
 *
 * @sclass
 */
msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {

  chDbgCheckClassS();

  if (TIME_INFINITE != time) {
    virtual_timer_t vt;

    chVTDoSetI(&vt, time, wakeup, currp);
    chSchGoSleepS(newstate);
    if (chVTIsArmedI(&vt))
      chVTDoResetI(&vt);
  }
  else {
    chSchGoSleepS(newstate);
  }

  return currp->p_u.rdymsg;
}
Ejemplo n.º 24
0
void scheduleTask(const char *prefix, scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param) {
	int delaySt = delayUs * CH_FREQUENCY / 1000000;
	if (delaySt == 0) {
		/**
		 * in case of zero delay, we should invoke the callback
		 */
		callback(param);
		return;
	}

	lockAnyContext();
	int isArmed = chVTIsArmedI(&scheduling->timer);
	if (isArmed)
		chVTResetI(&scheduling->timer);

	chVTSetI(&scheduling->timer, delaySt, (vtfunc_t)callback, param);
	unlockAnyContext();
}
Ejemplo n.º 25
0
/**
 * @brief   Master receive.
 *
 * @param[in] i2cp      pointer to the @p I2CDriver object
 * @param[in] addr      slave device address (7 bits) without R/W bit
 * @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_receive_timeout(I2CDriver *i2cp, i2caddr_t addr, 
				     uint8_t *rxbuf, size_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 = NULL;
  i2cp->txbytes = 0;
  i2cp->txidx = 0;
  i2cp->rxbuf = rxbuf;
  i2cp->rxbytes = rxbytes;
  i2cp->rxidx = 0;

  /* Setup device.*/
  bscdevice_t *device = i2cp->device;
  device->slaveAddress = addr;
  device->dataLength = rxbytes;
  device->status = CLEAR_STATUS;

  /* Enable Interrupts and start transfer.*/
  device->control = (BSC_INTR | BSC_INTD | START_READ);

  // needed? there is an outer lock already
  chSysLock();
  i2cp->thread = chThdSelf();
  chSchGoSleepS(THD_STATE_SUSPENDED);
  if ((timeout != TIME_INFINITE) && chVTIsArmedI(&vt))
    chVTResetI(&vt);
  chSysUnlock();

  return chThdSelf()->p_u.rdymsg;
}
Ejemplo n.º 26
0
void App_t::SaveSettings() {
    chSysLock();
    if(chVTIsArmedI(&ITmrSaving)) chVTResetI(&ITmrSaving);  // Reset timer
    chVTSetEvtI(&ITmrSaving, S2ST(4), EVTMSK_SAVE);
    chSysUnlock();
}
Ejemplo n.º 27
0
bool Timer::isArmedI(void) {

    return (bool)chVTIsArmedI(&timer_ref);
}
Ejemplo n.º 28
0
void Timer::resetI() {

    if (chVTIsArmedI(&timer_ref))
        chVTResetI(&timer_ref);
}
Ejemplo n.º 29
0
Archivo: main.cpp Proyecto: Kreyl/nute
void App_t::ITask() {
    while(true) {
        uint32_t EvtMsk = chEvtWaitAny(ALL_EVENTS);
        // ==== Card ====
        if(EvtMsk & EVTMSK_CARD_APPEARS) ProcessCardAppearance();

#if 1 // ==== Door ====
        if(EvtMsk & EVTMSK_DOOR_OPEN) {
            DoorState = dsOpen;
            Led.StartSequence(lsqDoorOpen); // Set color
            SndList.PlayRandomFileFromDir(DIRNAME_GOOD_KEY);
            Uart.Printf("\rDoor is open");
            chSysLock();
            if(chVTIsArmedI(&IDoorTmr)) chVTResetI(&IDoorTmr);
            chVTSetI(&IDoorTmr, MS2ST(DOOR_CLOSE_TIMEOUT), TmrGeneralCallback, (void*)EVTMSK_DOOR_SHUT);
            chSysUnlock();
        }
        if(EvtMsk & EVTMSK_DOOR_SHUT) {
            DoorState = dsClosed;
            Led.StartSequence(lsqDoorClose);    // Set color
            SndList.PlayRandomFileFromDir(DIRNAME_DOOR_CLOSING);
            Uart.Printf("\rDoor is closing");
        }

        if(EvtMsk & EVTMSK_BAD_KEY) {
            Led.StartSequence(lsqDoorWrongKey);
            SndList.PlayRandomFileFromDir(DIRNAME_BAD_KEY);
            Uart.Printf("\rBadKey");
        }
#endif

#if 1 // ==== Secret key ====
        if(EvtMsk & EVTMSK_SECRET_KEY) {
            Led.StartSequence(lsqDoorSecretKey);
            SndList.PlayRandomFileFromDir(DIRNAME_SECRET);
            Uart.Printf("\rSecretKey");
        }
#endif

#if 1 // ==== Keys ====
        if(EvtMsk & EVTMSK_KEYS) {
            KeyEvtInfo_t EInfo;
            while(Keys.EvtBuf.Get(&EInfo) == OK) {
//                Uart.Printf("\rEinfo: %u, %u, %u", EInfo.Type, EInfo.KeysCnt, EInfo.KeyID[0]);
                if(EInfo.Type == kePress) {
                    switch(EInfo.KeyID[0]) {
                        // Iterate AccessAdd / AccessRemove / Idle
                        case keyA:
                            switch(State) {
                                case asAddingAccess:   EnterState(asRemovingAccess); break;
                                case asRemovingAccess: EnterState(asIdle); break;
                                default:               EnterState(asAddingAccess); break;
                            } // switch State
                            break;
                        // Iterate AdderAdd / AdderRemove / Idle
                        case keyB:
                            switch(State) {
                                case asAddingAdder:   EnterState(asRemovingAdder); break;
                                case asRemovingAdder: EnterState(asIdle); break;
                                default:              EnterState(asAddingAdder); break;
                            } // switch State
                            break;

                        // Iterate RemoverAdd / RemoverRemove / Idle
                        case keyC:
                            switch(State) {
                                case asAddingRemover:   EnterState(asRemovingRemover); break;
                                case asRemovingRemover: EnterState(asIdle); break;
                                default:                EnterState(asAddingRemover); break;
                            } // switch State
                            break;
                    } // switch
                } // if keypress
                else if(EInfo.Type == keCombo and EInfo.KeyID[0] == keyA and EInfo.KeyID[1] == keyB) {
                    LedService.StartSequence(lsqEraseAll);
                    IDStore.EraseAll();
                    chThdSleepMilliseconds(1530);   // Allow LED to complete blinking
                    EnterState(asIdle);
                }
            } // while
        } // if keys
#endif

#if USB_ENABLED // ==== USB connection ====
        if(EvtMsk & EVTMSK_USB_CONNECTED) {
            chSysLock();
            Clk.SetFreq48Mhz();
            Clk.InitSysTick();
            chSysUnlock();
            Usb.Init();
            chThdSleepMilliseconds(540);
            Usb.Connect();
            Uart.Printf("\rUsb connected, AHB freq=%uMHz", Clk.AHBFreqHz/1000000);
        }
        if(EvtMsk & EVTMSK_USB_DISCONNECTED) {
            Usb.Shutdown();
            MassStorage.Reset();
            chSysLock();
            Clk.SetFreq12Mhz();
            Clk.InitSysTick();
            chSysUnlock();
            Uart.Printf("\rUsb disconnected, AHB freq=%uMHz", Clk.AHBFreqHz/1000000);
        }
#endif

        // ==== State timeout ====
        if(EvtMsk & EVTMSK_STATE_TIMEOUT) EnterState(asIdle);
    } // while true
}
Ejemplo n.º 30
0
  bool Timer::IsArmed(void) {

    return chVTIsArmedI(&timer);
  }