コード例 #1
0
ファイル: sdc_lld.c プロジェクト: xobs/chibi-chibios
/**
 * @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;
}
コード例 #2
0
/**
 * @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();
}
コード例 #3
0
ファイル: hal_gpt.c プロジェクト: AlexShiLucky/ChibiOS
/**
 * @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();
}
コード例 #4
0
ファイル: eicu.c プロジェクト: TexZK/ChibiOS-Contrib
/**
 * @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();
}
コード例 #5
0
ファイル: icu.c プロジェクト: SVentas/SmartMDC
/**
 * @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();
}
コード例 #6
0
ファイル: rtc.c プロジェクト: GuzTech/senoko-chibios-3
/**
 * @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();
}
コード例 #7
0
ファイル: hal_opamp.c プロジェクト: ChibiOS/ChibiOS-Contrib
/**
 * @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();
}
コード例 #8
0
ファイル: hal_onewire.c プロジェクト: awygle/ChibiOS-Contrib
/**
 * @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
}
コード例 #9
0
ファイル: pwm.c プロジェクト: TheShed/ChibiOS
/**
 * @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();
}
コード例 #10
0
ファイル: wdg.c プロジェクト: akerlund/DSP_system
/**
 * @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();
}
コード例 #11
0
ファイル: adc.c プロジェクト: TheShed/ChibiOS
/**
 * @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();
}
コード例 #12
0
ファイル: hal_serial.c プロジェクト: KTannenberg/ChibiOS
/**
 * @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();
}
コード例 #13
0
ファイル: i2c.c プロジェクト: hmchen1/ChibiOS
/**
 * @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();
}
コード例 #14
0
ファイル: icu.c プロジェクト: SVentas/SmartMDC
/**
 * @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();
}
コード例 #15
0
ファイル: icu.c プロジェクト: SVentas/SmartMDC
/**
 * @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();
}
コード例 #16
0
ファイル: hal_ext.c プロジェクト: AlexShiLucky/ChibiOS
/**
 * @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();
}
コード例 #17
0
ファイル: eicu.c プロジェクト: TexZK/ChibiOS-Contrib
/**
 * @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();
}
コード例 #18
0
ファイル: usb_main.c プロジェクト: kawaken/qmk_firmware
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();
}
コード例 #19
0
ファイル: hal_gpt.c プロジェクト: AlexShiLucky/ChibiOS
/**
 * @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();
}
コード例 #20
0
ファイル: hal_spi.c プロジェクト: rusefi/ChibiOS
/**
 * @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();
}
コード例 #21
0
ファイル: mac.c プロジェクト: 0110/stm32f103playground
/**
 * @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();
}
コード例 #22
0
ファイル: hal_opamp.c プロジェクト: ChibiOS/ChibiOS-Contrib
/**
 * @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();
}
コード例 #23
0
ファイル: pwm.c プロジェクト: TheShed/ChibiOS
/**
 * @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();
}
コード例 #24
0
ファイル: hal_spi.c プロジェクト: KTannenberg/ChibiOS
/**
 * @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();
}
コード例 #25
0
ファイル: hal_spi.c プロジェクト: KTannenberg/ChibiOS
/**
 * @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();
}
コード例 #26
0
ファイル: hal_spi.c プロジェクト: KTannenberg/ChibiOS
/**
 * @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();
}
コード例 #27
0
ファイル: hal_spi.c プロジェクト: KTannenberg/ChibiOS
/**
 * @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();
}
コード例 #28
0
ファイル: usb.c プロジェクト: hmchen1/ChibiOS
/**
 * @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();
}
コード例 #29
0
ファイル: hal_uart.c プロジェクト: AlexShiLucky/ChibiOS
/**
 * @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();
}
コード例 #30
0
ファイル: hal_uart.c プロジェクト: AlexShiLucky/ChibiOS
/**
 * @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();
}