/** * @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); }
/** * @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(); }
/** * @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; }
/** * @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 */ }
/** 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); }
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]; }
/** * @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; }
/** * @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; }
/** * @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); } }
/** * @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); }
/** * @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); }
/** * @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(); }
/** * @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); }
/** * @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; }
/** * @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; }
/** * @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 }
/** * @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; }
/** * @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; }
/** * @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(); }
/** * @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; }
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; }
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; }
/** * @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; }
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++; } }
/** * @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; } }
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; }
/** * @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); } }
/** * @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; } }
/** * @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; }
/** * @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; }