Esempio n. 1
0
/**
 * @brief   Writes one or more blocks.
 *
 * @param[in] sdcp      pointer to the @p SDCDriver object
 * @param[in] startblk  first block to write
 * @param[out] buf      pointer to the write buffer
 * @param[in] blocks    number of blocks to write
 *
 * @return              The operation status.
 * @retval HAL_SUCCESS operation succeeded.
 * @retval HAL_FAILED   operation failed.
 *
 * @notapi
 */
bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
                   const uint8_t *buf, uint32_t blocks) {

#if STM32_SDC_SDIO_UNALIGNED_SUPPORT
    if (((unsigned)buf & 3) != 0) {
        uint32_t i;
        for (i = 0; i < blocks; i++) {
            memcpy(u.buf, buf, MMCSD_BLOCK_SIZE);
            buf += MMCSD_BLOCK_SIZE;
            if (sdc_lld_write_aligned(sdcp, startblk, u.buf, 1))
                return HAL_FAILED;
            startblk++;
        }
        return HAL_SUCCESS;
    }
#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
    osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
    return sdc_lld_write_aligned(sdcp, startblk, buf, blocks);
}
Esempio n. 2
0
/**
 * @brief   Deactivates the CAN peripheral.
 *
 * @param[in] canp      pointer to the @p CANDriver object
 *
 * @api
 */
void canStop(CANDriver *canp) {

  osalDbgCheck(canp != NULL);

  osalSysLock();
  osalDbgAssert((canp->state == CAN_STOP) || (canp->state == CAN_READY),
                "invalid state");

  /* The low level driver is stopped.*/
  can_lld_stop(canp);
  canp->config = NULL;
  canp->state  = CAN_STOP;

  /* Threads waiting on CAN APIs are notified that the driver has been
     stopped in order to not have stuck threads.*/
  osalThreadDequeueAllI(&canp->rxqueue, MSG_RESET);
  osalThreadDequeueAllI(&canp->txqueue, MSG_RESET);
  osalOsRescheduleS();
  osalSysUnlock();
}
Esempio n. 3
0
/**
 * @brief   Can frame transmission attempt.
 * @details The specified frame is queued for transmission, if the hardware
 *          queue is full then the function fails.
 *
 * @param[in] canp      pointer to the @p CANDriver object
 * @param[in] mailbox   mailbox number, @p CAN_ANY_MAILBOX for any mailbox
 * @param[in] ctfp      pointer to the CAN frame to be transmitted
 * @return              The operation result.
 * @retval false        Frame transmitted.
 * @retval true         Mailbox full.
 *
 * @iclass
 */
bool canTryTransmitI(CANDriver *canp,
                     canmbx_t mailbox,
                     const CANTxFrame *ctfp) {

  osalDbgCheckClassI();
  osalDbgCheck((canp != NULL) && (ctfp != NULL) &&
               (mailbox <= (canmbx_t)CAN_TX_MAILBOXES));
  osalDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
                "invalid state");

  /* If the RX mailbox is full then the function fails.*/
  if (!can_lld_is_tx_empty(canp, mailbox)) {
    return true;
  }

  /* Transmitting frame.*/
  can_lld_transmit(canp, mailbox, ctfp);

  return false;
}
Esempio n. 4
0
/**
 * @brief   Stops, reconfigures and restarts an ADC/SDADC.
 *
 * @param[in] adcp      pointer to the @p ADCDriver object
 */
static void adc_lld_reconfig(ADCDriver *adcp) {

#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
  if (adcp->adc != NULL)
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_ADC
  {
    /* ADC initial setup, starting the analog part here in order to reduce
       the latency when starting a conversion.*/
    uint32_t cr2 = adcp->adc->CR2 & ADC_CR2_TSVREFE;
    adcp->adc->CR2 = cr2;
    adcp->adc->CR1 = 0;
    adcp->adc->CR2 = cr2 | ADC_CR2_ADON;

  }
#endif /* STM32_ADC_USE_ADC */
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
  else if (adcp->sdadc != NULL)
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_SDADC
  {
    /* SDADC initial setup, starting the analog part here in order to reduce
       the latency when starting a conversion.*/
    adcp->sdadc->CR2    = 0;
    adcp->sdadc->CR1    = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
                          ~SDADC_FORBIDDEN_CR1_FLAGS;
    adcp->sdadc->CONF0R = (adcp->sdadc->CONF0R & SDADC_CONFR_OFFSET_MASK) |
                          adcp->config->confxr[0];
    adcp->sdadc->CONF1R = (adcp->sdadc->CONF1R & SDADC_CONFR_OFFSET_MASK) |
                          adcp->config->confxr[1];
    adcp->sdadc->CONF2R = (adcp->sdadc->CONF2R & SDADC_CONFR_OFFSET_MASK) |
                          adcp->config->confxr[2];
    adcp->sdadc->CR2    = SDADC_CR2_ADON;
  }
#endif /* STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
else {
    osalDbgAssert(FALSE, "invalid state");
  }
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
}
Esempio n. 5
0
/** Start an AXI DMA direction driver.
 *
 * \param ddp     Pointer to the axi_dma_dir_driver_t object.
 */
static void axi_dma_dir_start(axi_dma_dir_driver_t *ddp)
{
  axi_dma_dir_t *axi_dma_dir = (axi_dma_dir_t *)ddp->axi_dma_dir;
  osalDbgAssert(axi_dma_dir != 0, "DMA dir not present");

  /* Clear COMPLETE and ERROR interrupt status */
  axi_dma_dir->SR = AXI_DMA_INT_COMPLETE_Msk |
                    AXI_DMA_INT_ERROR_Msk;

  /* Enable COMPLETE and ERROR interrupts */
  axi_dma_dir->CR |= AXI_DMA_INT_COMPLETE_Msk |
                     AXI_DMA_INT_ERROR_Msk;

  /* Set ENABLE bit */
  axi_dma_dir->CR |= AXI_DMA_CR_RUN_Msk;

  /* Wait for HALTED bit to clear */
  while(axi_dma_dir->SR & AXI_DMA_SR_HALTED_Msk);

  gic_irq_enable(ddp->irq_id);
}
Esempio n. 6
0
File* Fs::open(const char *name){
  toc_item_t ti;
  int id = -1;

  osalDbgAssert(this->files_opened > 0, "FS not mounted");

  id = find(name, &ti);

  if (-1 == id)
    return nullptr; /* not found */

  if (&mtd == fat[id].mtd)
    return nullptr; /* already opened */

  fat[id].size = ti.size;
  fat[id].start = ti.start;
  fat[id].mtd = &mtd;
  this->files_opened++;

  return &fat[id];
}
Esempio n. 7
0
/**
 * @brief   Configures and activates the WDG peripheral.
 *
 * @note    Once started there is no way out.
 *
 * @param[in] wdgp      pointer to the @p WDGDriver object
 *
 * @notapi
 */
void wdg_lld_start(WDGDriver *wdgp) {
#if WDG_USE_TIMEOUT_CALLBACK == TRUE
  wdgp->wdt->INTENSET = WDT_INTENSET_TIMEOUT_Msk;
#endif
  
  /* When to pause? (halt, sleep) */
  wdgp->wdt->CONFIG      =
      (wdgp->config->flags.pause_on_sleep * WDT_CONFIG_SLEEP_Msk) |
      (wdgp->config->flags.pause_on_halt  * WDT_CONFIG_HALT_Msk );
  
  /* Timeout in milli-seconds */
  uint64_t tout = (NRF51_LFCLK_FREQUENCY * wdgp->config->timeout_ms / 1000) - 1;
  osalDbgAssert(tout <= 0xFFFFFFFF, "watchdog timout value exceeded");  
  wdgp->wdt->CRV         = (uint32_t)tout;

  /* Reload request (using RR0) */
  wdgp->wdt->RREN        = WDT_RREN_RR0_Msk;

  /* Say your prayers, little one. */
  wdgp->wdt->TASKS_START = 1;
}
Esempio n. 8
0
/**
 * @brief   EDMA channel release.
 *
 * @param[in] channel   the channel number
 *
 * @special
 */
void edmaChannelRelease(edma_channel_t channel) {

  osalDbgCheck((channel >= 0) && (channel < SPC5_EDMA_NCHANNELS));
  osalDbgAssert(channels[channel] != NULL, "not allocated");

  /* Enforcing a stop.*/
  edmaChannelStop(channel);

#if SPC5_EDMA_HAS_MUX
  /* Disabling the MUX slot.*/
  SPC5_DMAMUX.CHCONFIG[channel].R = 0;
#endif

  /* Clearing ISR sources for the channel.*/
  SPC5_EDMA.CIRQR.R = channel;
  SPC5_EDMA.CEEIR.R = channel;
  SPC5_EDMA.CER.R   = channel;

  /* The channels is flagged as available.*/
  channels[channel] = NULL;
}
Esempio n. 9
0
/**
 * @brief   Writes a value into a register.
 * @pre     The SPI interface must be initialized and the driver started.
 *
 * @param[in] spip      pointer to the SPI initerface
 * @param[in] reg       register number
 * @param[in] value     the value to be written
 */
void lis302dlWriteRegister(SPIDriver *spip, uint8_t reg, uint8_t value) {

  switch (reg) {
  default:
    /* Reserved register must not be written, according to the datasheet
       this could permanently damage the device.*/
    osalDbgAssert(FALSE, "reserved register");
  case LIS302DL_WHO_AM_I:
  case LIS302DL_HP_FILTER_RESET:
  case LIS302DL_STATUS_REG:
  case LIS302DL_OUTX:
  case LIS302DL_OUTY:
  case LIS302DL_OUTZ:
  case LIS302DL_FF_WU_SRC1:
  case LIS302DL_FF_WU_SRC2:
  case LIS302DL_CLICK_SRC:
    /* Read only registers cannot be written, the command is ignored.*/
    return;
  case LIS302DL_CTRL_REG1:
  case LIS302DL_CTRL_REG2:
  case LIS302DL_CTRL_REG3:
  case LIS302DL_FF_WU_CFG1:
  case LIS302DL_FF_WU_THS1:
  case LIS302DL_FF_WU_DURATION1:
  case LIS302DL_FF_WU_CFG2:
  case LIS302DL_FF_WU_THS2:
  case LIS302DL_FF_WU_DURATION2:
  case LIS302DL_CLICK_CFG:
  case LIS302DL_CLICK_THSY_X:
  case LIS302DL_CLICK_THSZ:
  case LIS302DL_CLICK_TIMELIMIT:
  case LIS302DL_CLICK_LATENCY:
  case LIS302DL_CLICK_WINDOW:
    spiSelect(spip);
    txbuf[0] = reg;
    txbuf[1] = value;
    spiSend(spip, 2, txbuf);
    spiUnselect(spip);
  }
}
Esempio n. 10
0
/**
 * @brief     Read some bites from slave device.
 *
 * @param[in] owp       pointer to the @p onewireDriver object
 * @param[out] rxbuf    pointer to the buffer for read data
 * @param[in] rxbytes   amount of data to be received
 */
void onewireRead(onewireDriver *owp, uint8_t *rxbuf, size_t rxbytes) {
  PWMDriver *pwmd;
  PWMConfig *pwmcfg;
  size_t mch, sch;

  osalDbgCheck((NULL != owp) && (NULL != rxbuf));
  osalDbgCheck((rxbytes > 0) && (rxbytes <= ONEWIRE_MAX_TRANSACTION_LEN));
  osalDbgAssert(owp->reg.state == ONEWIRE_READY, "Invalid state");

  /* Buffer zeroing. This is important because of driver collects
     bits using |= operation.*/
  memset(rxbuf, 0, rxbytes);

  pwmd = owp->config->pwmd;
  pwmcfg = owp->config->pwmcfg;
  mch = owp->config->master_channel;
  sch = owp->config->sample_channel;

  owp->reg.bit = 0;
  owp->reg.final_timeslot = false;
  owp->buf = rxbuf;
  owp->reg.bytes = rxbytes;

  pwmcfg->period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH;
  pwmcfg->callback = NULL;
  pwmcfg->channels[mch].callback = NULL;
  pwmcfg->channels[mch].mode = owp->config->pwmmode;
  pwmcfg->channels[sch].callback = pwm_read_bit_cb;
  pwmcfg->channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW;

  ow_bus_active(owp);
  osalSysLock();
  pwmEnableChannelI(pwmd, mch, ONEWIRE_ONE_WIDTH);
  pwmEnableChannelI(pwmd, sch, ONEWIRE_SAMPLE_WIDTH);
  pwmEnableChannelNotificationI(pwmd, sch);
  osalThreadSuspendS(&owp->thread);
  osalSysUnlock();

  ow_bus_idle(owp);
}
Esempio n. 11
0
/**
 * @brief     Generate reset pulse on bus.
 *
 * @param[in] owp       pointer to the @p onewireDriver object
 *
 * @return              Bool flag denoting device presence.
 * @retval true         There is at least one device on bus.
 */
bool onewireReset(onewireDriver *owp) {
  PWMDriver *pwmd;
  PWMConfig *pwmcfg;
  size_t mch, sch;

  osalDbgCheck(NULL != owp);
  osalDbgAssert(owp->reg.state == ONEWIRE_READY, "Invalid state");

  /* short circuit on bus or any other device transmit data */
  if (PAL_LOW == ow_read_bit(owp))
    return false;

  pwmd = owp->config->pwmd;
  pwmcfg = owp->config->pwmcfg;
  mch = owp->config->master_channel;
  sch = owp->config->sample_channel;


  pwmcfg->period = ONEWIRE_RESET_LOW_WIDTH + ONEWIRE_RESET_SAMPLE_WIDTH;
  pwmcfg->callback = NULL;
  pwmcfg->channels[mch].callback = NULL;
  pwmcfg->channels[mch].mode = owp->config->pwmmode;
  pwmcfg->channels[sch].callback = pwm_reset_cb;
  pwmcfg->channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW;

  ow_bus_active(owp);

  osalSysLock();
  pwmEnableChannelI(pwmd, mch, ONEWIRE_RESET_LOW_WIDTH);
  pwmEnableChannelI(pwmd, sch, ONEWIRE_RESET_SAMPLE_WIDTH);
  pwmEnableChannelNotificationI(pwmd, sch);
  osalThreadSuspendS(&owp->thread);
  osalSysUnlock();

  ow_bus_idle(owp);

  /* wait until slave release bus to discriminate short circuit condition */
  osalThreadSleepMicroseconds(500);
  return (PAL_HIGH == ow_read_bit(owp)) && (true == owp->reg.slave_present);
}
Esempio n. 12
0
/**
 * @brief   Stops the driver.
 * @details Any thread waiting on the driver's queues will be awakened with
 *          the message @p Q_RESET.
 *
 * @param[in] sdup      pointer to a @p SerialUSBDriver object
 *
 * @api
 */
void sduStop(SerialUSBDriver *sdup) {
  USBDriver *usbp = sdup->config->usbp;

  osalDbgCheck(sdup != NULL);

  osalSysLock();
  osalDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY),
                "invalid state");

  /* Driver in stopped state.*/
  usbp->in_params[sdup->config->bulk_in - 1U]   = NULL;
  usbp->out_params[sdup->config->bulk_out - 1U] = NULL;
  if (sdup->config->int_in > 0U) {
    usbp->in_params[sdup->config->int_in - 1U]  = NULL;
  }
  sdup->state = SDU_STOP;

  /* Enforces a disconnection.*/
  sduDisconnectI(sdup);
  osalOsRescheduleS();
  osalSysUnlock();
}
Esempio n. 13
0
/**
 * @brief   Changes the operation mode of a channel.
 * @note    This function attempts to write over the current configuration
 *          structure that must have been not declared constant. This
 *          violates the @p const qualifier in @p extStart() but it is
 *          intentional.
 * @note    This function cannot be used if the configuration structure is
 *          declared @p const.
 * @note    The effect of this function on constant configuration structures
 *          is not defined.
 *
 * @param[in] extp      pointer to the @p EXTDriver object
 * @param[in] channel   channel to be changed
 * @param[in] extcp     new configuration for the channel
 *
 * @iclass
 */
void extSetChannelModeI(EXTDriver *extp,
                        expchannel_t channel,
                        const EXTChannelConfig *extcp) {
  EXTChannelConfig *oldcp;

  osalDbgCheck((extp != NULL) &&
               (channel < (expchannel_t)EXT_MAX_CHANNELS) &&
               (extcp != NULL));

  osalDbgAssert(extp->state == EXT_ACTIVE, "invalid state");

  /* Note that here the access is enforced as non-const, known access
     violation.*/
  /*lint -save -e9005 [11.8] Known issue, the driver needs rework here.*/
  oldcp = (EXTChannelConfig *)&extp->config->channels[channel];
  /*lint -restore*/

  /* Overwriting the old channels configuration then the channel is
     reconfigured by the low level driver.*/
  *oldcp = *extcp;
  ext_lld_channel_enable(extp, channel);
}
Esempio n. 14
0
/**
 * @brief   Configures and activates the GPT peripheral.
 *
 * @param[in] gptp      pointer to the @p GPTDriver object
 *
 * @notapi
 */
void gpt_lld_start(GPTDriver *gptp) {
  uint16_t psc;

  if (gptp->state == GPT_STOP) {
    /* Clock activation.*/
    SIM->SCGC6 |= SIM_SCGC6_PIT;
    gptp->clock = KINETIS_SYSCLK_FREQUENCY;

#if KINETIS_GPT_USE_PIT0
    if (&GPTD1 == gptp) {
      nvicEnableVector(PITChannel0_IRQn, KINETIS_GPT_PIT0_IRQ_PRIORITY);
    }
#endif
#if KINETIS_GPT_USE_PIT1
    if (&GPTD2 == gptp) {
      nvicEnableVector(PITChannel1_IRQn, KINETIS_GPT_PIT1_IRQ_PRIORITY);
    }
#endif
#if KINETIS_GPT_USE_PIT2
    if (&GPTD3 == gptp) {
      nvicEnableVector(PITChannel2_IRQn, KINETIS_GPT_PIT2_IRQ_PRIORITY);
    }
#endif
#if KINETIS_GPT_USE_PIT3
    if (&GPTD4 == gptp) {
      nvicEnableVector(PITChannel3_IRQn, KINETIS_GPT_PIT3_IRQ_PRIORITY);
    }
#endif

  }

  /* Prescaler value calculation.*/
  psc = (uint16_t)((gptp->clock / gptp->config->frequency) - 1);
  osalDbgAssert(((uint32_t)(psc + 1) * gptp->config->frequency) == gptp->clock,
                "invalid frequency");

  /* Enable the PIT */
  PIT->MCR = 0;
}
Esempio n. 15
0
/**
 * @brief   Can frame receive.
 * @details The function waits until a frame is received.
 * @note    Trying to receive while in sleep mode simply enqueues the thread.
 *
 * @param[in] canp      pointer to the @p CANDriver object
 * @param[in] mailbox   mailbox number, @p CAN_ANY_MAILBOX for any mailbox
 * @param[out] crfp     pointer to the buffer where the CAN frame is copied
 * @param[in] timeout   the number of ticks before the operation timeouts,
 *                      the following special values are allowed:
 *                      - @a TIME_IMMEDIATE immediate timeout (useful in an
 *                        event driven scenario where a thread never blocks
 *                        for I/O).
 *                      - @a TIME_INFINITE no timeout.
 *                      .
 * @return              The operation result.
 * @retval MSG_OK       a frame has been received and placed in the buffer.
 * @retval MSG_TIMEOUT  The operation has timed out.
 * @retval MSG_RESET    The driver has been stopped while waiting.
 *
 * @api
 */
msg_t canReceive(CANDriver *canp,
                 canmbx_t mailbox,
                 CANRxFrame *crfp,
                 systime_t timeout) {

  osalDbgCheck((canp != NULL) && (crfp != NULL) &&
               (mailbox < CAN_RX_MAILBOXES));

  osalSysLock();
  osalDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
                "invalid state");
  while ((canp->state == CAN_SLEEP) || !can_lld_is_rx_nonempty(canp, mailbox)) {
    msg_t msg = osalThreadEnqueueTimeoutS(&canp->rxqueue, timeout);
    if (msg != MSG_OK) {
      osalSysUnlock();
      return msg;
    }
  }
  can_lld_receive(canp, mailbox, crfp);
  osalSysUnlock();
  return MSG_OK;
}
Esempio n. 16
0
/**
 * @brief   Releases a DMA stream.
 * @details The stream is freed and, if required, the DMA clock disabled.
 *          Trying to release a unallocated stream is an illegal operation
 *          and is trapped if assertions are enabled.
 * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 * @post    The stream is again available.
 * @note    This function can be invoked in both ISR or thread context.
 *
 * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
 *
 * @special
 */
void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {

  osalDbgCheck(dmastp != NULL);

  /* Check if the streams is not taken.*/
  osalDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0,
                "not allocated");

  /* Disables the associated IRQ vector.*/
  nvicDisableVector(dmastp->vector);

  /* Marks the stream as not allocated.*/
  dma_streams_mask &= ~(1 << dmastp->selfindex);

  /* Shutting down clocks that are no more required, if any.*/
  if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0)
    rccDisableDMA1(false);
#if STM32_HAS_DMA2
  if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0)
    rccDisableDMA2(false);
#endif
}
Esempio n. 17
0
/**
 * @brief   Can frame transmission.
 * @details The specified frame is queued for transmission, if the hardware
 *          queue is full then the invoking thread is queued.
 * @note    Trying to transmit while in sleep mode simply enqueues the thread.
 *
 * @param[in] canp      pointer to the @p CANDriver object
 * @param[in] mailbox   mailbox number, @p CAN_ANY_MAILBOX for any mailbox
 * @param[in] ctfp      pointer to the CAN frame to be transmitted
 * @param[in] timeout   the number of ticks before the operation timeouts,
 *                      the following special values are allowed:
 *                      - @a TIME_IMMEDIATE immediate timeout.
 *                      - @a TIME_INFINITE no timeout.
 *                      .
 * @return              The operation result.
 * @retval MSG_OK       the frame has been queued for transmission.
 * @retval MSG_TIMEOUT  The operation has timed out.
 * @retval MSG_RESET    The driver has been stopped while waiting.
 *
 * @api
 */
msg_t canTransmit(CANDriver *canp,
                  canmbx_t mailbox,
                  const CANTxFrame *ctfp,
                  systime_t timeout) {

  osalDbgCheck((canp != NULL) && (ctfp != NULL) &&
               (mailbox <= CAN_TX_MAILBOXES));

  osalSysLock();
  osalDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
                "invalid state");
  while ((canp->state == CAN_SLEEP) || !can_lld_is_tx_empty(canp, mailbox)) {
    msg_t msg = osalThreadEnqueueTimeoutS(&canp->txqueue, timeout);
    if (msg != MSG_OK) {
      osalSysUnlock();
      return msg;
    }
  }
  can_lld_transmit(canp, mailbox, ctfp);
  osalSysUnlock();
  return MSG_OK;
}
Esempio n. 18
0
/**
 * @brief   Brings the driver in a state safe for card removal.
 *
 * @param[in] mmcp      pointer to the @p MMCDriver object
 * @return              The operation status.
 *
 * @retval CH_SUCCESS   the operation succeeded and the driver is now
 *                      in the @p MMC_INSERTED state.
 * @retval CH_FAILED    the operation failed.
 *
 * @api
 */
bool mmcDisconnect(MMCDriver *mmcp) {

  osalDbgCheck(mmcp != NULL);

  osalSysLock();
  osalDbgAssert((mmcp->state == BLK_ACTIVE) || (mmcp->state == BLK_READY),
                "invalid state");
  if (mmcp->state == BLK_ACTIVE) {
    osalSysUnlock();
    return CH_SUCCESS;
  }
  mmcp->state = BLK_DISCONNECTING;
  osalSysUnlock();

  /* Wait for the pending write operations to complete.*/
  spiStart(mmcp->config->spip, mmcp->config->hscfg);
  sync(mmcp);

  spiStop(mmcp->config->spip);
  mmcp->state = BLK_ACTIVE;
  return CH_SUCCESS;
}
Esempio n. 19
0
/**
 * @brief   Stops the driver.
 * @details Any thread waiting on the driver's queues will be awakened with
 *          the message @p Q_RESET.
 *
 * @param[in] hiddp      pointer to a @p HIDDebugDriver object
 *
 * @api
 */
void hidDebugStop(HIDDebugDriver *hiddp) {
  USBDriver *usbp = hiddp->config->usbp;

  osalDbgCheck(hiddp != NULL);

  osalSysLock();
  osalDbgAssert((hiddp->state == HIDDEBUG_STOP) || (hiddp->state == HIDDEBUG_READY),
                "invalid state");

  /* Driver in stopped state.*/
  usbp->in_params[hiddp->config->ep_in - 1U] = NULL;
  hiddp->state = HIDDEBUG_STOP;

  /* Stop the flush timer */
  chVTResetI(&hid_debug_flush_timer);

  /* Queues reset in order to signal the driver stop to the application.*/
  chnAddFlagsI(hiddp, CHN_DISCONNECTED);
  iqResetI(&hiddp->oqueue);
  osalOsRescheduleS();
  osalSysUnlock();
}
Esempio n. 20
0
/**
 * @brief   Configures and activates the SDC peripheral.
 *
 * @param[in] sdcp      pointer to the @p SDCDriver object
 *
 * @notapi
 */
void sdc_lld_start(SDCDriver *sdcp) {

  /* Checking configuration, using a default if NULL has been passed.*/
  if (sdcp->config == NULL) {
    sdcp->config = &sdc_default_cfg;
  }

  sdcp->dmamode = STM32_DMA_CR_CHSEL(DMA_CHANNEL) |
                  STM32_DMA_CR_PL(STM32_SDC_SDMMC1_DMA_PRIORITY) |
                  STM32_DMA_CR_PSIZE_WORD |
                  STM32_DMA_CR_MSIZE_WORD |
                  STM32_DMA_CR_MINC;

#if 1
  sdcp->dmamode |= STM32_DMA_CR_PFCTRL |
                   STM32_DMA_CR_PBURST_INCR4 |
                   STM32_DMA_CR_MBURST_INCR4;
#endif

  if (sdcp->state == BLK_STOP) {
    /* Note, the DMA must be enabled before the IRQs.*/
    bool b;
    b = dmaStreamAllocate(sdcp->dma, STM32_SDC_SDMMC1_IRQ_PRIORITY, NULL, NULL);
    osalDbgAssert(!b, "stream already allocated");
    dmaStreamSetPeripheral(sdcp->dma, &sdcp->sdmmc->FIFO);
#if 1
    dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS | STM32_DMA_FCR_FTH_FULL);
#endif
    nvicEnableVector(STM32_SDMMC1_NUMBER, STM32_SDC_SDMMC1_IRQ_PRIORITY);
    rccEnableSDMMC1(FALSE);
  }

  /* Configuration, card clock is initially stopped.*/
  sdcp->sdmmc->POWER  = 0;
  sdcp->sdmmc->CLKCR  = 0;
  sdcp->sdmmc->DCTRL  = 0;
  sdcp->sdmmc->DTIMER = 0;
}
Esempio n. 21
0
bool Fs::mkfs(void) {
  checksum_t sum = 0xFF; /* initial CRC vector */
  size_t written;

  osalDbgCheck((this->files_opened == 0) && (nullptr == super.mtd));
  open_super();
  osalDbgAssert((super.start + super.size) < mtd.capacity(), "Overflow");

  /* write magic and zero file count */
  memcpy(toc_buf, magic, sizeof(magic));
  toc_buf[sizeof(magic)] = 0; /* existing files count */
  if (FILE_OK != super.setPosition(0))
    goto FAILED;
  if (FAT_OFFSET != super.write(toc_buf, FAT_OFFSET))
    goto FAILED;
  sum = nvramcrc(toc_buf, FAT_OFFSET, sum);

  /* write empty FAT */
  memset(toc_buf, 0, sizeof(toc_buf));
  for (size_t i=0; i<NVRAM_FS_MAX_FILE_CNT; i++){
    written = super.write(toc_buf, sizeof(toc_buf));
    if (sizeof(toc_buf) != written)
      goto FAILED;
    sum = nvramcrc(toc_buf, sizeof(toc_buf), sum);
  }

  /* seal superblock */
  memcpy(toc_buf, &sum, sizeof(checksum_t));
  if (sizeof(checksum_t) != super.write(toc_buf, sizeof(checksum_t)))
    goto FAILED;

  super.close();
  return OSAL_SUCCESS;

FAILED:
  super.close();
  return OSAL_FAILED;
}
Esempio n. 22
0
static msg_t sens_get_temperature(void *ip, float* tempp) {
  int16_t temp;
#if LSM6DS0_USE_I2C
  osalDbgAssert((((LSM6DS0Driver *)ip)->config->i2cp->state == I2C_READY),
                "gyro_read_raw(), channel not ready");
#if LSM6DS0_SHARED_I2C
  i2cAcquireBus(((LSM6DS0Driver *)ip)->config->i2cp);
  i2cStart(((LSM6DS0Driver *)ip)->config->i2cp,
           ((LSM6DS0Driver *)ip)->config->i2ccfg);
#endif /* LSM6DS0_SHARED_I2C */
  temp = lsm6ds0I2CReadRegister(((LSM6DS0Driver *)ip)->config->i2cp,
                                ((LSM6DS0Driver *)ip)->config->slaveaddress,
                                  LSM6DS0_AD_OUT_TEMP_L, NULL);
  temp += lsm6ds0I2CReadRegister(((LSM6DS0Driver *)ip)->config->i2cp,
                                 ((LSM6DS0Driver *)ip)->config->slaveaddress,
                                   LSM6DS0_AD_OUT_TEMP_H, NULL) << 8;
#if LSM6DS0_SHARED_I2C
  i2cReleaseBus(((LSM6DS0Driver *)ip)->config->i2cp);
#endif /* LSM6DS0_SHARED_I2C */
#endif /* LSM6DS0_USE_I2C */
  *tempp = ((float)temp / LSM6DS0_TEMP_SENS) + LSM6DS0_TEMP_SENS_OFF;
  return MSG_OK;
}
Esempio n. 23
0
/**
 * @brief   Starts a sequential write.
 *
 * @param[in] mmcp      pointer to the @p MMCDriver object
 * @param[in] startblk  first block to write
 *
 * @return              The operation status.
 * @retval CH_SUCCESS   the operation succeeded.
 * @retval CH_FAILED    the operation failed.
 *
 * @api
 */
bool mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) {

  osalDbgCheck(mmcp != NULL);
  osalDbgAssert(mmcp->state == BLK_READY, "invalid state");

  /* Write operation in progress.*/
  mmcp->state = BLK_WRITING;

  spiStart(mmcp->config->spip, mmcp->config->hscfg);
  spiSelect(mmcp->config->spip);
  if (mmcp->block_addresses)
    send_hdr(mmcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK, startblk);
  else
    send_hdr(mmcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
             startblk * MMCSD_BLOCK_SIZE);

  if (recvr1(mmcp) != 0x00) {
    spiStop(mmcp->config->spip);
    mmcp->state = BLK_READY;
    return CH_FAILED;
  }
  return CH_SUCCESS;
}
Esempio n. 24
0
static void blink_cycle(const int16_t *seq, blinker_named_color_t color){
  uint32_t i = 0;
  uint32_t sum = 0;

  /* check for probable overflow */
  i = 0;
  while (0 != seq[i]){
    sum += abs(seq[i]);
    i++;
  }
  osalDbgAssert((sum <= 1000), "Blinker sequence too long");

  /* main blinker */
  i = 0;
  while (0 != seq[i]){
    if (seq[i] > 0)
      led_on(color);
    else
      led_off(color);
    chThdSleepMilliseconds(abs(seq[i]));
    i++;
  }
}
Esempio n. 25
0
/**
 * @brief   Configures and activates the SDRAM peripheral.
 *
 * @param[in] sdramp        pointer to the @p SDRAMDriver object
 * @param[in] cfgp          pointer to the @p SDRAMConfig object
 */
void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp) {

  if (FSMCD1.state == FSMC_STOP)
    fsmc_start(&FSMCD1);

  osalDbgAssert((sdramp->state == SDRAM_STOP) || (sdramp->state == SDRAM_READY),
              "SDRAM. Invalid state.");

  if (sdramp->state == SDRAM_STOP) {

    /* Even if you need only bank2 you must properly set up SDCR and SDTR
       regitsters for bank1 too. Both banks will be tuned equally assuming
       connected memory ICs are equal.*/
    sdramp->sdram->SDCR1 = cfgp->sdcr;
    sdramp->sdram->SDTR1 = cfgp->sdtr;
    sdramp->sdram->SDCR2 = cfgp->sdcr;
    sdramp->sdram->SDTR2 = cfgp->sdtr;

    _sdram_init_sequence(cfgp);

    sdramp->state = SDRAM_READY;
  }
}
Esempio n. 26
0
static msg_t acc_read_cooked(void *ip, float axes[]) {
  uint32_t i;
  int32_t raw[LSM6DS0_ACC_NUMBER_OF_AXES];
  msg_t msg;

  osalDbgCheck(((ip != NULL) && (axes != NULL)) &&
              (((LSM6DS0Driver *)ip)->config->acccfg != NULL));

  osalDbgAssert((((LSM6DS0Driver *)ip)->state == LSM6DS0_READY),
              "acc_read_cooked(), invalid state");

  msg = acc_read_raw(ip, raw);
  for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES ; i++){
    axes[i] = raw[i] * ((LSM6DS0Driver *)ip)->accsensitivity[i];
    if(((LSM6DS0Driver *)ip)->config->acccfg->unit == LSM6DS0_ACC_UNIT_G){
      axes[i] *= TO_G;
    }
    else if(((LSM6DS0Driver *)ip)->config->acccfg->unit == LSM6DS0_ACC_UNIT_SI){
      axes[i] *= TO_SI;
    }
  }
  return msg;
}
Esempio n. 27
0
/**
 * @brief   Deactivates the N25Q128 driver.
 *
 * @param[in] devp       pointer to the @p M25QDriver object
 *
 * @api
 */
void m25qStop(M25QDriver *devp) {

  osalDbgCheck(devp != NULL);
  osalDbgAssert(devp->state != FLASH_UNINIT, "invalid state");

  if (devp->state != FLASH_STOP) {

    /* Bus acquisition.*/
    flash_bus_acquire(devp);

#if M25Q_BUS_MODE == M25Q_BUS_MODE_SPI
    spiStop(devp->config->spip);
#else
    qspiStop(devp->config->qspip);
#endif

    devp->config = NULL;
    devp->state = FLASH_STOP;

    /* Bus release.*/
    flash_bus_release(devp);
  }
}
Esempio n. 28
0
/**
 * @brief   Configures and activates the ADC peripheral.
 *
 * @param[in] adcp      pointer to the @p ADCDriver object
 *
 * @notapi
 */
void adc_lld_start(ADCDriver *adcp) {

  /* If in stopped state then enables the ADC and DMA clocks.*/
  if (adcp->state == ADC_STOP) {
#if STM32_ADC_USE_ADC1
    if (&ADCD1 == adcp) {
      bool b;
      b = dmaStreamAllocate(adcp->dmastp,
                            STM32_ADC_ADC1_IRQ_PRIORITY,
                            (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
                            (void *)adcp);
      osalDbgAssert(!b, "stream already allocated");
      dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
      rccEnableADC1(FALSE);
    }
#endif

    /* ADC setup, the calibration procedure has already been performed
       during initialization.*/
    adcp->adc->CR1 = 0;
    adcp->adc->CR2 = 0;
  }
}
Esempio n. 29
0
/**
 * @brief   Waits for a received frame.
 * @details Stops until a frame is received and buffered. If a frame is
 *          not immediately available then the invoking thread is queued
 *          until one is received.
 *
 * @param[in] macp      pointer to the @p MACDriver object
 * @param[out] rdp      pointer to a @p MACReceiveDescriptor structure
 * @param[in] time      the number of ticks before the operation timeouts,
 *                      the following special values are allowed:
 *                      - @a TIME_IMMEDIATE immediate timeout.
 *                      - @a TIME_INFINITE no timeout.
 *                      .
 * @return              The operation status.
 * @retval RDY_OK       the descriptor was obtained.
 * @retval RDY_TIMEOUT  the operation timed out, descriptor not initialized.
 *
 * @api
 */
msg_t macWaitReceiveDescriptor(MACDriver *macp,
                               MACReceiveDescriptor *rdp,
                               systime_t time) {
  msg_t msg;
  systime_t now;

  osalDbgCheck((macp != NULL) && (rdp != NULL));
  osalDbgAssert(macp->state == MAC_ACTIVE, "not active");

  while (((msg = mac_lld_get_receive_descriptor(macp, rdp)) != MSG_OK) &&
         (time > 0)) {
    osalSysLock();
    now = osalOsGetSystemTimeX();
    if ((msg = chSemWaitTimeoutS(&macp->rdsem, time)) == MSG_TIMEOUT) {
      osalSysUnlock();
      break;
    }
    if (time != TIME_INFINITE)
      time -= (osalOsGetSystemTimeX() - now);
    osalSysUnlock();
  }
  return msg;
}
Esempio n. 30
0
/**
 * @brief   Initialize the Data Link Layer object.
 * @details The function starts the DataLinkLayer serial driver
 *          - Check the actual state of the driver
 *          - Configure and start the sdSerial driver
 *          - Init the mutex variable used by the 'DLLSendSingleFrameSerial' function
 *          - Init the mailboxes which are work like a buffer
 *          - Creates a SyncFrame
 *          - Starts the 'SDReceiving' and 'SDSending' threads which are provide
 *            the whole DLL functionality
 *          - Set the DLL state to ACTIVE
 *
 * @param[in] dllp    DataLinkLayer driver structure
 * @param[in] config  The config contains the speed and the ID of the serial driver
 */
void DLLStart(DLLDriver *dllp, DLLSerialConfig *config){
  osalDbgCheck((dllp != NULL) && (config != NULL));

  osalDbgAssert((dllp->state == DLL_UNINIT) || (dllp->state == DLL_ACTIVE),
              "DLLInit(), invalid state");

  dllp->config = config;
  SerialDCfg.speed = dllp->config->baudrate;       //Set the data rate to the given rate
  sdStart(dllp->config->SDriver, &SerialDCfg);     //Start the serial driver for the ESP8266


  chMtxObjectInit(&dllp->DLLSerialSendMutex);


  chMBObjectInit(&dllp->DLLBuffers.DLLFilledOutputBuffer,
                 dllp->DLLBuffers.DLLFilledOutputBufferQueue, OUTPUT_FRAME_BUFFER);

  chMBObjectInit(&dllp->DLLBuffers.DLLFreeOutputBuffer,
                 dllp->DLLBuffers.DLLFreeOutputBufferQueue, OUTPUT_FRAME_BUFFER);

  int i;
  for (i = 0; i < OUTPUT_FRAME_BUFFER; i++)
    (void)chMBPost(&dllp->DLLBuffers.DLLFreeOutputBuffer,
                   (msg_t)&dllp->DLLBuffers.DLLOutputBuffer[i], TIME_INFINITE);

  DLLCreateSyncFrame(dllp);

  dllp->SendingThread = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(128), NORMALPRIO+1, SDSending, (void *)dllp);
  if (dllp->SendingThread == NULL)
    chSysHalt("DualFramework: Starting 'SendingThread' failed - out of memory");

  dllp->ReceivingThread = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(128), NORMALPRIO+1, SDReceiving, (void *)dllp);
  if (dllp->ReceivingThread == NULL)
    chSysHalt("DualFramework: Starting 'ReceivingThread' failed - out of memory");

  dllp->state = DLL_ACTIVE;
}