/** * @brief Wait end of data transaction and performs finalizations. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[in] n number of blocks in transaction * @param[in] resp pointer to the response buffer * * @return The operation status. * @retval HAL_SUCCESS operation succeeded. * @retval HAL_FAILED operation failed. */ static bool sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n, uint32_t *resp) { /* Note the mask is checked before going to sleep because the interrupt may have occurred before reaching the critical zone.*/ osalSysLock(); if (sdcp->sdio->MASK != 0) osalThreadSuspendS(&sdcp->thread); if ((sdcp->sdio->STA & SDIO_STA_DATAEND) == 0) { osalSysUnlock(); return HAL_FAILED; } #if (defined(STM32F4XX) || defined(STM32F2XX)) /* Wait until DMA channel enabled to be sure that all data transferred.*/ while (sdcp->dma->stream->CR & STM32_DMA_CR_EN) ; /* DMA event flags must be manually cleared.*/ dmaStreamClearInterrupt(sdcp->dma); sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS; sdcp->sdio->DCTRL = 0; osalSysUnlock(); /* Wait until interrupt flags to be cleared.*/ /*while (((DMA2->LISR) >> (sdcp->dma->ishift)) & STM32_DMA_ISR_TCIF) dmaStreamClearInterrupt(sdcp->dma);*/ #else /* Waits for transfer completion at DMA level, then the stream is disabled and cleared.*/ dmaWaitCompletion(sdcp->dma); sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS; sdcp->sdio->DCTRL = 0; osalSysUnlock(); #endif /* Finalize transaction.*/ if (n > 1) return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp); return HAL_SUCCESS; }
/** * @brief Sets the vehicle name and vehicle type in the system * information structure. * * @param[in] name New name array. * @param[in] type New type array. */ void SetSystemNameType(const char name[VEHICLE_NAME_SIZE], const char type[VEHICLE_TYPE_SIZE]) { osalSysLock(); strncpy(system_strings.vehicle_name, name, VEHICLE_NAME_SIZE); strncpy(system_strings.vehicle_type, type, VEHICLE_TYPE_SIZE); osalSysUnlock(); }
/** * @brief Changes the interval of GPT peripheral. * @details This function changes the interval of a running GPT unit. * @pre The GPT unit must be running in continuous mode. * @post The GPT unit interval is changed to the new value. * * @param[in] gptp pointer to a @p GPTDriver object * @param[in] interval new cycle time in timer ticks * * @api */ void gptChangeInterval(GPTDriver *gptp, gptcnt_t interval) { osalDbgCheck(gptp != NULL); osalSysLock(); osalDbgAssert(gptp->state == GPT_CONTINUOUS, "invalid state"); gptChangeIntervalI(gptp, interval); osalSysUnlock(); }
/** * @brief Enables the extended input capture. * * @param[in] eicup Pointer to the @p EICUDriver object * * @api */ void eicuEnable(EICUDriver *eicup) { osalDbgCheck(eicup != NULL); osalSysLock(); osalDbgAssert(eicup->state == EICU_READY, "invalid state"); eicu_lld_enable(eicup); eicup->state = EICU_WAITING; osalSysUnlock(); }
/** * @brief Disables notifications. * @pre The ICU unit must have been activated using @p icuStart(). * @note If the notification is already disabled then the call has no effect. * * @param[in] icup pointer to the @p ICUDriver object * * @api */ void icuDisableNotifications(ICUDriver *icup) { osalDbgCheck(icup != NULL); osalSysLock(); osalDbgAssert((icup->state == ICU_WAITING) || (icup->state == ICU_ACTIVE), "invalid state"); icuDisableNotificationsI(icup); osalSysUnlock(); }
/** * @brief Get current alarm. * @note If an alarm has not been set then the returned alarm specification * is not meaningful. * * @param[in] rtcp pointer to RTC driver structure * @param[in] alarm alarm identifier * @param[out] alarmspec pointer to a @p RTCAlarm structure * * @api */ void rtcGetAlarm(RTCDriver *rtcp, rtcalarm_t alarm, RTCAlarm *alarmspec) { osalDbgCheck((rtcp != NULL) && (alarm < RTC_ALARMS) && (alarmspec != NULL)); osalSysLock(); rtcGetAlarmI(rtcp, alarm, alarmspec); osalSysUnlock(); }
/** * @brief Activates the opamp. * * @param[in] opampp pointer to the @p OPAMPDriver object * * @api */ void opampEnable(OPAMPDriver *opampp) { osalDbgCheck(opampp != NULL); osalSysLock(); osalDbgAssert(opampp->state == OPAMP_ACTIVE, "invalid state"); opamp_lld_enable(opampp); opampp->state = OPAMP_ACTIVE; osalSysUnlock(); }
/** * @brief Read some bites from slave device. * * @param[in] owp pointer to the @p onewireDriver object * @param[in] txbuf pointer to the buffer with data to be written * @param[in] txbytes amount of data to be written * @param[in] pullup_time how long strong pull up must be activated. Set * it to 0 if not needed. */ void onewireWrite(onewireDriver *owp, uint8_t *txbuf, size_t txbytes, systime_t pullup_time) { PWMDriver *pwmd; PWMConfig *pwmcfg; size_t mch, sch; osalDbgCheck((NULL != owp) && (NULL != txbuf)); osalDbgCheck((txbytes > 0) && (txbytes <= ONEWIRE_MAX_TRANSACTION_LEN)); osalDbgAssert(owp->reg.state == ONEWIRE_READY, "Invalid state"); #if !ONEWIRE_USE_STRONG_PULLUP osalDbgAssert(0 == pullup_time, "Non zero time is valid only when strong pull enabled"); #endif pwmd = owp->config->pwmd; pwmcfg = owp->config->pwmcfg; mch = owp->config->master_channel; sch = owp->config->sample_channel; owp->buf = txbuf; owp->reg.bit = 0; owp->reg.final_timeslot = false; owp->reg.bytes = txbytes; pwmcfg->period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH; pwmcfg->callback = pwm_write_bit_cb; pwmcfg->channels[mch].callback = NULL; pwmcfg->channels[mch].mode = owp->config->pwmmode; pwmcfg->channels[sch].callback = NULL; pwmcfg->channels[sch].mode = PWM_OUTPUT_DISABLED; #if ONEWIRE_USE_STRONG_PULLUP if (pullup_time > 0) { owp->reg.state = ONEWIRE_PULL_UP; owp->reg.need_pullup = true; } #endif ow_bus_active(owp); osalSysLock(); pwmEnablePeriodicNotificationI(pwmd); osalThreadSuspendS(&owp->thread); osalSysUnlock(); pwmDisablePeriodicNotification(pwmd); ow_bus_idle(owp); #if ONEWIRE_USE_STRONG_PULLUP if (pullup_time > 0) { osalThreadSleep(pullup_time); owp->config->pullup_release(); owp->reg.state = ONEWIRE_READY; } #endif }
/** * @brief Enables a PWM channel. * @pre The PWM unit must have been activated using @p pwmStart(). * @post The channel is active using the specified configuration. * @note Depending on the hardware implementation this function has * effect starting on the next cycle (recommended implementation) * or immediately (fallback implementation). * * @param[in] pwmp pointer to a @p PWMDriver object * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1) * @param[in] width PWM pulse width as clock pulses number * * @api */ void pwmEnableChannel(PWMDriver *pwmp, pwmchannel_t channel, pwmcnt_t width) { osalDbgCheck((pwmp != NULL) && (channel < PWM_CHANNELS)); osalSysLock(); osalDbgAssert(pwmp->state == PWM_READY, "not ready"); pwm_lld_enable_channel(pwmp, channel, width); osalSysUnlock(); }
/** * @brief Deactivates the WDG peripheral. * * @param[in] wdgp pointer to the @p WDGDriver object * * @api */ void wdgStop(WDGDriver *wdgp) { osalDbgCheck(wdgp != NULL); osalSysLock(); osalDbgAssert((wdgp->state == WDG_STOP) || (wdgp->state == WDG_READY), "invalid state"); wdg_lld_stop(wdgp); wdgp->state = WDG_STOP; osalSysUnlock(); }
/** * @brief Deactivates the ADC peripheral. * * @param[in] adcp pointer to the @p ADCDriver object * * @api */ void adcStop(ADCDriver *adcp) { osalDbgCheck(adcp != NULL); osalSysLock(); osalDbgAssert((adcp->state == ADC_STOP) || (adcp->state == ADC_READY), "invalid state"); adc_lld_stop(adcp); adcp->state = ADC_STOP; osalSysUnlock(); }
/** * @brief Configures and starts the driver. * * @param[in] sdp pointer to a @p SerialDriver object * @param[in] config the architecture-dependent serial driver configuration. * If this parameter is set to @p NULL then a default * configuration is used. * * @api */ void sdStart(SerialDriver *sdp, const SerialConfig *config) { osalDbgCheck(sdp != NULL); osalSysLock(); osalDbgAssert((sdp->state == SD_STOP) || (sdp->state == SD_READY), "invalid state"); sd_lld_start(sdp, config); sdp->state = SD_READY; osalSysUnlock(); }
/** * @brief Deactivates the I2C peripheral. * * @param[in] i2cp pointer to the @p I2CDriver object * * @api */ void i2cStop(I2CDriver *i2cp) { osalDbgCheck(i2cp != NULL); osalDbgAssert((i2cp->state == I2C_STOP) || (i2cp->state == I2C_READY) || (i2cp->state == I2C_LOCKED), "invalid state"); osalSysLock(); i2c_lld_stop(i2cp); i2cp->state = I2C_STOP; osalSysUnlock(); }
/** * @brief Stops the input capture. * * @param[in] icup pointer to the @p ICUDriver object * * @api */ void icuStopCapture(ICUDriver *icup) { osalDbgCheck(icup != NULL); osalSysLock(); osalDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) || (icup->state == ICU_ACTIVE), "invalid state"); icuStopCaptureI(icup); osalSysUnlock(); }
/** * @brief Deactivates the ICU peripheral. * * @param[in] icup pointer to the @p ICUDriver object * * @api */ void icuStop(ICUDriver *icup) { osalDbgCheck(icup != NULL); osalSysLock(); osalDbgAssert((icup->state == ICU_STOP) || (icup->state == ICU_READY), "invalid state"); icu_lld_stop(icup); icup->state = ICU_STOP; osalSysUnlock(); }
/** * @brief Deactivates the EXT peripheral. * * @param[in] extp pointer to the @p EXTDriver object * * @api */ void extStop(EXTDriver *extp) { osalDbgCheck(extp != NULL); osalSysLock(); osalDbgAssert((extp->state == EXT_STOP) || (extp->state == EXT_ACTIVE), "invalid state"); ext_lld_stop(extp); extp->state = EXT_STOP; osalSysUnlock(); }
/** * @brief Deactivates the EICU peripheral. * * @param[in] eicup Pointer to the @p EICUDriver object * * @api */ void eicuStop(EICUDriver *eicup) { osalDbgCheck(eicup != NULL); osalSysLock(); osalDbgAssert((eicup->state == EICU_STOP) || (eicup->state == EICU_READY), "invalid state"); eicu_lld_stop(eicup); eicup->state = EICU_STOP; osalSysUnlock(); }
void send_mouse(report_mouse_t *report) { osalSysLock(); if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { osalSysUnlock(); return; } if(usbGetTransmitStatusI(&USB_DRIVER, MOUSE_IN_EPNUM)) { /* Need to either suspend, or loop and call unlock/lock during * every iteration - otherwise the system will remain locked, * no interrupts served, so USB not going through as well. * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[MOUSE_IN_EPNUM]->in_state->thread, MS2ST(10)==MSG_TIMEOUT)) { osalSysUnlock(); return; } } usbStartTransmitI(&USB_DRIVER, MOUSE_IN_EPNUM, (uint8_t *)report, sizeof(report_mouse_t)); osalSysUnlock(); }
/** * @brief Deactivates the GPT peripheral. * * @param[in] gptp pointer to the @p GPTDriver object * * @api */ void gptStop(GPTDriver *gptp) { osalDbgCheck(gptp != NULL); osalSysLock(); osalDbgAssert((gptp->state == GPT_STOP) || (gptp->state == GPT_READY), "invalid state"); gpt_lld_stop(gptp); gptp->state = GPT_STOP; osalSysUnlock(); }
/** * @brief Aborts the ongoing SPI operation, if any. * * @param[in] spip pointer to the @p SPIDriver object * * @api */ void spiAbort(SPIDriver *spip) { osalSysLock(); osalDbgAssert((spip->state == SPI_READY) || (spip->state == SPI_ACTIVE), "invalid state"); if (spip->state == SPI_ACTIVE) { spiAbortI(spip); osalOsRescheduleS(); } osalSysUnlock(); }
/** * @brief Deactivates the MAC peripheral. * * @param[in] macp pointer to the @p MACDriver object * * @api */ void macStop(MACDriver *macp) { osalDbgCheck(macp != NULL); osalSysLock(); osalDbgAssert((macp->state == MAC_STOP) || (macp->state == MAC_ACTIVE), "invalid state"); mac_lld_stop(macp); macp->state = MAC_STOP; osalSysUnlock(); }
/** * @brief Deactivates the OPAMP peripheral. * * @param[in] opampp pointer to the @p OPAMPDriver object * * @api */ void opampStop(OPAMPDriver *opampp) { osalDbgCheck(opampp != NULL); osalSysLock(); osalDbgAssert((opampp->state == OPAMP_STOP) || (opampp->state == OPAMP_ACTIVE), "invalid state"); opamp_lld_stop(opampp); opampp->state = OPAMP_STOP; osalSysUnlock(); }
/** * @brief Deactivates the PWM peripheral. * * @param[in] pwmp pointer to a @p PWMDriver object * * @api */ void pwmStop(PWMDriver *pwmp) { osalDbgCheck(pwmp != NULL); osalSysLock(); osalDbgAssert((pwmp->state == PWM_STOP) || (pwmp->state == PWM_READY), "invalid state"); pwm_lld_stop(pwmp); pwmp->state = PWM_STOP; osalSysUnlock(); }
/** * @brief Receives data from the SPI bus. * @details This synchronous function performs a receive operation. * @pre In order to use this function the option @p SPI_USE_WAIT must be * enabled. * @pre In order to use this function the driver must have been configured * without callbacks (@p end_cb = @p NULL). * @note The buffers are organized as uint8_t arrays for data sizes below * or equal to 8 bits else it is organized as uint16_t arrays. * * @param[in] spip pointer to the @p SPIDriver object * @param[in] n number of words to receive * @param[out] rxbuf the pointer to the receive buffer * * @api */ void spiReceive(SPIDriver *spip, size_t n, void *rxbuf) { osalDbgCheck((spip != NULL) && (n > 0U) && (rxbuf != NULL)); osalSysLock(); osalDbgAssert(spip->state == SPI_READY, "not ready"); osalDbgAssert(spip->config->end_cb == NULL, "has callback"); spiStartReceiveI(spip, n, rxbuf); (void) osalThreadSuspendS(&spip->thread); osalSysUnlock(); }
/** * @brief Ignores data on the SPI bus. * @details This synchronous function performs the transmission of a series of * idle words on the SPI bus and ignores the received data. * @pre In order to use this function the option @p SPI_USE_WAIT must be * enabled. * @pre In order to use this function the driver must have been configured * without callbacks (@p end_cb = @p NULL). * * @param[in] spip pointer to the @p SPIDriver object * @param[in] n number of words to be ignored * * @api */ void spiIgnore(SPIDriver *spip, size_t n) { osalDbgCheck((spip != NULL) && (n > 0U)); osalSysLock(); osalDbgAssert(spip->state == SPI_READY, "not ready"); osalDbgAssert(spip->config->end_cb == NULL, "has callback"); spiStartIgnoreI(spip, n); (void) osalThreadSuspendS(&spip->thread); osalSysUnlock(); }
/** * @brief Exchanges data on the SPI bus. * @details This asynchronous function starts a simultaneous transmit/receive * operation. * @pre A slave must have been selected using @p spiSelect() or * @p spiSelectI(). * @post At the end of the operation the configured callback is invoked. * @note The buffers are organized as uint8_t arrays for data sizes below * or equal to 8 bits else it is organized as uint16_t arrays. * * @param[in] spip pointer to the @p SPIDriver object * @param[in] n number of words to be exchanged * @param[in] txbuf the pointer to the transmit buffer * @param[out] rxbuf the pointer to the receive buffer * * @api */ void spiStartExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { osalDbgCheck((spip != NULL) && (n > 0U) && (rxbuf != NULL) && (txbuf != NULL)); osalSysLock(); osalDbgAssert(spip->state == SPI_READY, "not ready"); spiStartExchangeI(spip, n, txbuf, rxbuf); osalSysUnlock(); }
/** * @brief Configures and activates the SPI peripheral. * * @param[in] spip pointer to the @p SPIDriver object * @param[in] config pointer to the @p SPIConfig object * * @api */ void spiStart(SPIDriver *spip, const SPIConfig *config) { osalDbgCheck((spip != NULL) && (config != NULL)); osalSysLock(); osalDbgAssert((spip->state == SPI_STOP) || (spip->state == SPI_READY), "invalid state"); spip->config = config; spi_lld_start(spip); spip->state = SPI_READY; osalSysUnlock(); }
/** * @brief Deactivates the USB peripheral. * * @param[in] usbp pointer to the @p USBDriver object * * @api */ void usbStop(USBDriver *usbp) { osalDbgCheck(usbp != NULL); osalSysLock(); osalDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY) || (usbp->state == USB_SELECTED) || (usbp->state == USB_ACTIVE), "invalid state"); usb_lld_stop(usbp); usbp->state = USB_STOP; osalSysUnlock(); }
/** * @brief Starts a receive operation on the UART peripheral. * @note The buffers are organized as uint8_t arrays for data sizes below * or equal to 8 bits else it is organized as uint16_t arrays. * * @param[in] uartp pointer to the @p UARTDriver object * @param[in] n number of data frames to receive * @param[in] rxbuf the pointer to the receive buffer * * @api */ void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf) { osalDbgCheck((uartp != NULL) && (n > 0U) && (rxbuf != NULL)); osalSysLock(); osalDbgAssert(uartp->state == UART_READY, "is active"); osalDbgAssert(uartp->rxstate != UART_RX_ACTIVE, "rx active"); uart_lld_start_receive(uartp, n, rxbuf); uartp->rxstate = UART_RX_ACTIVE; osalSysUnlock(); }
/** * @brief Starts a transmission on the UART peripheral. * @note The buffers are organized as uint8_t arrays for data sizes below * or equal to 8 bits else it is organized as uint16_t arrays. * * @param[in] uartp pointer to the @p UARTDriver object * @param[in] n number of data frames to send * @param[in] txbuf the pointer to the transmit buffer * * @api */ void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf) { osalDbgCheck((uartp != NULL) && (n > 0U) && (txbuf != NULL)); osalSysLock(); osalDbgAssert(uartp->state == UART_READY, "is active"); osalDbgAssert(uartp->txstate != UART_TX_ACTIVE, "tx active"); uart_lld_start_send(uartp, n, txbuf); uartp->txstate = UART_TX_ACTIVE; osalSysUnlock(); }