uint8_t Infrared_t::TransmitWord(uint16_t wData, uint8_t PwrPercent) { // Uart.Printf("T\r"); if(IsBusy) return BUSY; IsBusy = true; // Calculate power uint32_t Pwr = (MaxPower * PwrPercent) / 100; // Fill buffer with powers depending on data uint16_t *p = TxPwrBuf; // Header *p++ = Pwr; *p++ = Pwr; *p++ = Pwr; *p++ = Pwr; // Data for(uint8_t i=0; i<IR_BIT_CNT; i++) { *p++ = 0; // Off = Space *p++ = Pwr; // '0' is single ON if(wData & 0x8000) *p++ = Pwr; // '1' is double ON wData <<= 1; } *p++ = 0; // Off - finishing delay // Enable DMA uint8_t CountToTx = p - TxPwrBuf; dmaStreamSetTransactionSize(IR_TX_DMA_STREAM, CountToTx); dmaStreamEnable(IR_TX_DMA_STREAM); // Start master timer Modulator.GenerateUpdateEvt(); // Generate update: clear counter and request DMA Modulator.Enable(); return OK; }
/** * @brief Prepares to handle read transaction. * @details Designed for read special registers from card. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[out] buf pointer to the read buffer * @param[in] bytes number of bytes to read * * @return The operation status. * @retval HAL_SUCCESS operation succeeded. * @retval HAL_FAILED operation failed. * * @notapi */ static bool sdc_lld_prepare_read_bytes(SDCDriver *sdcp, uint8_t *buf, uint32_t bytes) { osalDbgCheck(bytes < 0x1000000); sdcp->sdio->DTIMER = STM32_SDC_READ_TIMEOUT; /* Checks for errors and waits for the card to be ready for reading.*/ if (_sdc_wait_for_transfer_state(sdcp)) return HAL_FAILED; /* Prepares the DMA channel for writing.*/ dmaStreamSetMemory0(sdcp->dma, buf); dmaStreamSetTransactionSize(sdcp->dma, bytes / sizeof (uint32_t)); dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M); dmaStreamEnable(sdcp->dma); /* Setting up data transfer.*/ sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS; sdcp->sdio->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | SDIO_MASK_STBITERRIE | SDIO_MASK_RXOVERRIE | SDIO_MASK_DATAENDIE; sdcp->sdio->DLEN = bytes; /* Transaction starts just after DTEN bit setting.*/ sdcp->sdio->DCTRL = SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | /* multibyte data transfer */ SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN; return HAL_SUCCESS; }
/** * @brief Starts an ADC conversion. * * @param[in] adcp pointer to the @p ADCDriver object * * @notapi */ void adc_lld_start_conversion(ADCDriver *adcp) { uint32_t mode; const ADCConversionGroup *grpp = adcp->grpp; /* DMA setup.*/ mode = adcp->dmamode; if (grpp->circular) { mode |= STM32_DMA_CR_CIRC; } if (adcp->depth > 1) { /* If the buffer depth is greater than one then the half transfer interrupt interrupt is enabled in order to allows streaming processing.*/ mode |= STM32_DMA_CR_HTIE; } dmaStreamSetMemory0(adcp->dmastp, adcp->samples); dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels * (uint32_t)adcp->depth); dmaStreamSetMode(adcp->dmastp, mode); /* ADC setup.*/ adcp->adc->SR = 0; adcp->adc->SMPR1 = grpp->smpr1; adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SQR1 = grpp->sqr1; adcp->adc->SQR2 = grpp->sqr2; adcp->adc->SQR3 = grpp->sqr3; /* ADC configuration and start, the start is performed using the method specified in the CR2 configuration, usually ADC_CR2_SWSTART.*/ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; }
/** * @brief Starts an ADC conversion. * * @param[in] adcp pointer to the @p ADCDriver object * * @notapi */ void adc_lld_start_conversion(ADCDriver *adcp) { uint32_t mode, n; const ADCConversionGroup *grpp = adcp->grpp; /* DMA setup.*/ mode = adcp->dmamode; if (grpp->circular) mode |= STM32_DMA_CR_CIRC; if (adcp->depth > 1) { /* If the buffer depth is greater than one then the half transfer interrupt interrupt is enabled in order to allows streaming processing.*/ mode |= STM32_DMA_CR_HTIE; n = (uint32_t)grpp->num_channels * (uint32_t)adcp->depth; } else n = (uint32_t)grpp->num_channels; dmaStreamSetMemory0(adcp->dmastp, adcp->samples); dmaStreamSetTransactionSize(adcp->dmastp, n); dmaStreamSetMode(adcp->dmastp, mode); dmaStreamEnable(adcp->dmastp); /* ADC setup.*/ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN; adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON; adcp->adc->SMPR1 = grpp->smpr1; adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SQR1 = grpp->sqr1; adcp->adc->SQR2 = grpp->sqr2; adcp->adc->SQR3 = grpp->sqr3; /* ADC start by writing ADC_CR2_ADON a second time.*/ adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON; }
/** * @brief Starts an ADC conversion. * * @param[in] adcp pointer to the @p ADCDriver object * * @notapi */ void adc_lld_start_conversion(ADCDriver *adcp) { uint32_t mode, cr2; const ADCConversionGroup *grpp = adcp->grpp; /* DMA setup.*/ mode = adcp->dmamode; if (grpp->circular) { mode |= STM32_DMA_CR_CIRC; if (adcp->depth > 1) { /* If circular buffer depth > 1, then the half transfer interrupt is enabled in order to allow streaming processing.*/ mode |= STM32_DMA_CR_HTIE; } } dmaStreamSetMemory0(adcp->dmastp, adcp->samples); dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels * (uint32_t)adcp->depth); dmaStreamSetMode(adcp->dmastp, mode); dmaStreamEnable(adcp->dmastp); /* ADC setup.*/ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN; cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_ADON; if ((cr2 & (ADC_CR2_EXTTRIG | ADC_CR2_JEXTTRIG)) == 0) cr2 |= ADC_CR2_CONT; adcp->adc->CR2 = grpp->cr2 | cr2; adcp->adc->SMPR1 = grpp->smpr1; adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SQR1 = grpp->sqr1; adcp->adc->SQR2 = grpp->sqr2; adcp->adc->SQR3 = grpp->sqr3; /* ADC start by writing ADC_CR2_ADON a second time.*/ adcp->adc->CR2 = cr2; }
/** * @brief Exchanges data on the SPI bus. * @details This asynchronous function starts a simultaneous transmit/receive * operation. * @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 * * @notapi */ void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { osalDbgAssert(n < 65536, "unsupported DMA transfer size"); dmaStreamSetMemory0(spip->dmarx, rxbuf); dmaStreamSetTransactionSize(spip->dmarx, n); dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC); dmaStreamSetMemory0(spip->dmatx, txbuf); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC); dmaStreamEnable(spip->dmarx); dmaStreamEnable(spip->dmatx); }
/** * @brief Starts an ADC conversion. * * @param[in] adcp pointer to the @p ADCDriver object * * @notapi */ void adc_lld_start_conversion(ADCDriver *adcp) { uint32_t mode, cfgr1; const ADCConversionGroup *grpp = adcp->grpp; /* DMA setup.*/ mode = adcp->dmamode; cfgr1 = grpp->cfgr1 | ADC_CFGR1_DMAEN; if (grpp->circular) { mode |= STM32_DMA_CR_CIRC; cfgr1 |= ADC_CFGR1_DMACFG; if (adcp->depth > 1) { /* If circular buffer depth > 1, then the half transfer interrupt is enabled in order to allow streaming processing.*/ mode |= STM32_DMA_CR_HTIE; } } dmaStreamSetMemory0(adcp->dmastp, adcp->samples); dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels * (uint32_t)adcp->depth); dmaStreamSetMode(adcp->dmastp, mode); dmaStreamEnable(adcp->dmastp); /* ADC setup, if it is defined a callback for the analog watch dog then it is enabled.*/ adcp->adc->ISR = adcp->adc->ISR; adcp->adc->IER = ADC_IER_OVRIE | ADC_IER_AWDIE; adcp->adc->TR = grpp->tr; adcp->adc->SMPR = grpp->smpr; adcp->adc->CHSELR = grpp->chselr; /* ADC configuration and start.*/ adcp->adc->CFGR1 = cfgr1; adcp->adc->CR |= ADC_CR_ADSTART; }
void CmdUart_t::Init(uint32_t ABaudrate) { PWrite = TXBuf; PRead = TXBuf; IDmaIsIdle = true; IFullSlotsCount = 0; PinSetupAlterFunc(UART_GPIO, UART_TX_PIN, omPushPull, pudNone, UART_AF); // ==== USART configuration ==== UART_RCC_ENABLE(); UART->CR1 = USART_CR1_UE; // Enable USART UART->BRR = Clk.APBFreqHz / ABaudrate; UART->CR2 = 0; // ==== DMA ==== dmaStreamAllocate (UART_DMA_TX, IRQ_PRIO_HIGH, CmdUartTxIrq, NULL); dmaStreamSetPeripheral(UART_DMA_TX, &UART->TDR); dmaStreamSetMode (UART_DMA_TX, UART_DMA_TX_MODE); #if UART_RX_ENABLED UART->CR1 = USART_CR1_TE | USART_CR1_RE; // TX & RX enable UART->CR3 = USART_CR3_DMAT | USART_CR3_DMAR; // Enable DMA at TX & RX PinSetupAlterFunc(UART_GPIO, UART_RX_PIN, omOpenDrain, pudPullUp, UART_AF); dmaStreamAllocate (UART_DMA_RX, IRQ_PRIO_LOW, nullptr, NULL); dmaStreamSetPeripheral(UART_DMA_RX, &UART->RDR); dmaStreamSetMemory0 (UART_DMA_RX, IRxBuf); dmaStreamSetTransactionSize(UART_DMA_RX, UART_RXBUF_SZ); dmaStreamSetMode (UART_DMA_RX, UART_DMA_RX_MODE); dmaStreamEnable (UART_DMA_RX); #else UART->CR1 = USART_CR1_TE; // Transmitter enabled UART->CR3 = USART_CR3_DMAT; // Enable DMA at transmitter #endif UART->CR1 |= USART_CR1_UE; // Enable USART }
/** * @brief Sends data over the DAC bus. * @details This asynchronous function starts a transmit operation. * @post At the end of the operation the configured callback is invoked. * * @param[in] dacp pointer to the @p DACDriver object * @param[in] n number of words to send * @param[in] txbuf the pointer to the transmit buffer * * @notapi */ void dac_lld_start_conversion(DACDriver *dacp) { osalDbgAssert(dacp->samples, "dacp->samples is NULL pointer"); dmaStreamSetMemory0(dacp->dma, dacp->samples); dmaStreamSetTransactionSize(dacp->dma, dacp->depth); dmaStreamSetMode(dacp->dma, dacp->dmamode | STM32_DMA_CR_EN | STM32_DMA_CR_CIRC); }
/** * @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 * * @notapi */ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { /* TX DMA channel preparation and start.*/ dmaStreamSetMemory0(uartp->dmatx, txbuf); dmaStreamSetTransactionSize(uartp->dmatx, n); dmaStreamSetMode(uartp->dmatx, uartp->dmamode | STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); dmaStreamEnable(uartp->dmatx); }
void Adc_t::StartDMAMeasure() { (void)SPI_ADC->DR; // Clear input register dmaStreamSetMemory0(DMA_ADC, &IRslt); dmaStreamSetTransactionSize(DMA_ADC, 3); dmaStreamSetMode(DMA_ADC, ADC_DMA_MODE); dmaStreamEnable(DMA_ADC); CsLo(); ISpi.Enable(); }
uint8_t i2c_t::CmdWriteWrite(uint8_t Addr, uint8_t *WPtr1, uint8_t WLength1, uint8_t *WPtr2, uint8_t WLength2) { if(IBusyWait() != OK) return FAILURE; // Clear flags ii2c->SR1 = 0; while(RxIsNotEmpty()) (void)ii2c->DR; // Read DR until it empty ClearAddrFlag(); // Start transmission SendStart(); if(WaitEv5() != OK) return FAILURE; SendAddrWithWrite(Addr); if(WaitEv6() != OK) { SendStop(); return FAILURE; } ClearAddrFlag(); // Start TX DMA if needed if(WLength1 != 0) { if(WaitEv8() != OK) return FAILURE; dmaStreamSetMemory0(PDmaTx, WPtr1); dmaStreamSetMode (PDmaTx, I2C_DMATX_MODE); dmaStreamSetTransactionSize(PDmaTx, WLength1); chSysLock(); PRequestingThread = chThdSelf(); dmaStreamEnable(PDmaTx); chSchGoSleepS(THD_STATE_SUSPENDED); // Sleep until end chSysUnlock(); dmaStreamDisable(PDmaTx); } if(WLength2 != 0) { if(WaitEv8() != OK) return FAILURE; dmaStreamSetMemory0(PDmaTx, WPtr2); dmaStreamSetMode (PDmaTx, I2C_DMATX_MODE); dmaStreamSetTransactionSize(PDmaTx, WLength2); chSysLock(); PRequestingThread = chThdSelf(); dmaStreamEnable(PDmaTx); chSchGoSleepS(THD_STATE_SUSPENDED); // Sleep until end chSysUnlock(); dmaStreamDisable(PDmaTx); } WaitBTF(); SendStop(); return OK; }
void Adc_t::StartMeasurement() { while(BitIsSet(ADC1->CR, ADC_CR_ADSTP)); // Wait until stop is completed // DMA dmaStreamSetMemory0(ADC_DMA, IBuf); dmaStreamSetTransactionSize(ADC_DMA, ADC_SEQ_LEN); dmaStreamSetMode(ADC_DMA, ADC_DMA_MODE); dmaStreamEnable(ADC_DMA); // ADC StartConversion(); }
void Sound_t::SendZeroes() { // Uart.Printf("sz\r"); XDCS_Lo(); // Start data transmission uint32_t FLength = (ZeroesCount > 32)? 32 : ZeroesCount; dmaStreamSetMemory0(VS_DMA, &SZero); dmaStreamSetTransactionSize(VS_DMA, FLength); dmaStreamSetMode(VS_DMA, VS_DMA_MODE); // Do not increase memory pointer dmaStreamEnable(VS_DMA); ZeroesCount -= FLength; }
/** * @brief Receives data via the I2C bus as master. * @details Number of receiving bytes must be more than 1 on STM32F1x. This is * hardware restriction. * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] addr slave device address * @param[out] rxbuf pointer to the receive buffer * @param[in] rxbytes number of bytes to be received * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval RDY_OK if the function succeeded. * @retval RDY_RESET if one or more I2C errors occurred, the errors can * be retrieved using @p i2cGetErrors(). * @retval RDY_TIMEOUT if a timeout occurred before operation end. <b>After a * timeout the driver must be stopped and restarted * because the bus is in an uncertain state</b>. * * @notapi */ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr, uint8_t *rxbuf, size_t rxbytes, systime_t timeout) { I2C_TypeDef *dp = i2cp->i2c; VirtualTimer vt; #if defined(STM32F1XX_I2C) chDbgCheck((rxbytes > 1), "i2c_lld_master_receive_timeout"); #endif /* Global timeout for the whole operation.*/ if (timeout != TIME_INFINITE) chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp); /* Releases the lock from high level driver.*/ chSysUnlock(); /* Initializes driver fields, LSB = 1 -> receive.*/ i2cp->addr = (addr << 1) | 0x01; i2cp->errors = 0; /* RX DMA setup.*/ dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode); dmaStreamSetMemory0(i2cp->dmarx, rxbuf); dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); /* Waits until BUSY flag is reset and the STOP from the previous operation is completed, alternatively for a timeout condition.*/ while ((dp->SR2 & I2C_SR2_BUSY) || (dp->CR1 & I2C_CR1_STOP)) { chSysLock(); if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt)) return RDY_TIMEOUT; chSysUnlock(); } /* This lock will be released in high level driver.*/ chSysLock(); /* Atomic check on the timer in order to make sure that a timeout didn't happen outside the critical zone.*/ if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt)) return RDY_TIMEOUT; /* Starts the operation.*/ dp->CR2 |= I2C_CR2_ITEVTEN; dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK; /* Waits for the operation completion or a timeout.*/ i2cp->thread = chThdSelf(); chSchGoSleepS(THD_STATE_SUSPENDED); if ((timeout != TIME_INFINITE) && chVTIsArmedI(&vt)) chVTResetI(&vt); return chThdSelf()->p_u.rdymsg; }
uint8_t i2c_t::WriteRead(uint32_t Addr, uint8_t *WPtr, uint32_t WLength, uint8_t *RPtr, uint32_t RLength) { if(chBSemWait(&BSemaphore) != MSG_OK) return FAILURE; uint8_t Rslt; msg_t r; I2C_TypeDef *pi2c = PParams->pi2c; // To make things shorter if(WLength == 0 or WPtr == nullptr) { Rslt = CMD_ERROR; goto WriteReadEnd; } if(IBusyWait() != OK) { Rslt = BUSY; goto WriteReadEnd; } IReset(); // Reset I2C // Prepare TX DMA dmaStreamSetMode(PParams->PDmaTx, DMA_MODE_TX); dmaStreamSetMemory0(PParams->PDmaTx, WPtr); dmaStreamSetTransactionSize(PParams->PDmaTx, WLength); if(RLength != 0 and RPtr != nullptr) { // Prepare RX DMA dmaStreamSetMode(PParams->PDmaRx, DMA_MODE_RX); dmaStreamSetMemory0(PParams->PDmaRx, RPtr); dmaStreamSetTransactionSize(PParams->PDmaRx, RLength); ILen = RLength; IState = istWriteRead; } else IState = istWrite; // Nothing to read pi2c->CR2 = (Addr << 1) | (WLength << 16); dmaStreamEnable(PParams->PDmaTx); // Enable TX DMA // Enable IRQs: TX completed, error, NAck pi2c->CR1 |= (I2C_CR1_TCIE | I2C_CR1_ERRIE | I2C_CR1_NACKIE); pi2c->CR2 |= I2C_CR2_START; // Start transmission // Wait completion chSysLock(); r = chThdSuspendTimeoutS(&PThd, MS2ST(I2C_TIMEOUT_MS)); chSysUnlock(); // Disable IRQs pi2c->CR1 &= ~(I2C_CR1_TCIE | I2C_CR1_ERRIE | I2C_CR1_NACKIE); if(r == MSG_TIMEOUT) { pi2c->CR2 |= I2C_CR2_STOP; Rslt = TIMEOUT; } else Rslt = (IState == istFailure)? FAILURE : OK; WriteReadEnd: chBSemSignal(&BSemaphore); return Rslt; }
void Adc_t::StartMeasurement() { // DMA dmaStreamSetMemory0(ADC_DMA, IBuf); dmaStreamSetTransactionSize(ADC_DMA, ADC_SEQ_LEN); dmaStreamSetMode(ADC_DMA, ADC_DMA_MODE); dmaStreamEnable(ADC_DMA); // ADC ADC1->CR1 = ADC_CR1_SCAN; ADC1->CR2 = ADC_CR2_DMA | ADC_CR2_ADON; StartConversion(); }
// ==== IRQs ==== void DbgUart_t::IRQDmaTxHandler() { dmaStreamDisable(STM32_DMA2_STREAM7); // Registers may be changed only when stream is disabled if(ICountToSendNext == 0) IDmaIsIdle = true; else { // There is something to transmit more dmaStreamSetMemory0(STM32_DMA2_STREAM7, PRead); // Handle pointer uint32_t BytesLeft = UART_TXBUF_SIZE - (PRead - TXBuf); if(ICountToSendNext < BytesLeft) { // Data fits in buffer without split dmaStreamSetTransactionSize(STM32_DMA2_STREAM7, ICountToSendNext); PRead += ICountToSendNext; ICountToSendNext = 0; } else { // Some portion of data placed in the beginning dmaStreamSetTransactionSize(STM32_DMA2_STREAM7, BytesLeft); PRead = TXBuf; // Set pointer to beginning ICountToSendNext -= BytesLeft; } dmaStreamEnable(STM32_DMA2_STREAM7); // Restart DMA } }
void Uart_t::ISendViaDMA() { uint32_t PartSz = (TXBuf + UART_TXBUF_SZ) - PRead; // Cnt from PRead to end of buf ITransSize = MIN(IFullSlotsCount, PartSz); if(ITransSize != 0) { IDmaIsIdle = false; dmaStreamSetMemory0(UART_DMA_TX, PRead); dmaStreamSetTransactionSize(UART_DMA_TX, ITransSize); dmaStreamSetMode(UART_DMA_TX, UART_DMA_TX_MODE); dmaStreamEnable(UART_DMA_TX); } }
/** * @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 send * @param[out] rxbuf the pointer to the receive buffer * * @notapi */ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { /* Stopping previous activity (idle state).*/ dmaStreamDisable(uartp->dmarx); /* RX DMA channel preparation and start.*/ dmaStreamSetMemory0(uartp->dmarx, rxbuf); dmaStreamSetTransactionSize(uartp->dmarx, n); dmaStreamSetMode(uartp->dmarx, uartp->dmamode | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); dmaStreamEnable(uartp->dmarx); }
// CNV IRQ void eAdc_t::IIrqHandler() { CskTmr.Disable(); SPI1->DR = 0; Adc.Rslt = 0; dmaStreamAllocate (EADC_DMA, IRQ_PRIO_MEDIUM, SIrqDmaHandler, NULL); dmaStreamSetPeripheral(EADC_DMA, &ADC_SPI->DR); dmaStreamSetMode (EADC_DMA, EADC_DMA_MODE); dmaStreamSetMemory0(EADC_DMA, &Adc.Rslt); dmaStreamSetTransactionSize(EADC_DMA, 1); dmaStreamEnable(EADC_DMA); ADC_CNV_LOW(); }
/** * @brief Fill an area with a bitmap. * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled * @param[in] srcx, srcy The bitmap position to start the fill from * @param[in] srccx The width of a line in the bitmap. * @param[in] buffer The pixels to use to fill the area. * * @notapi */ void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; } if (srcx+cx > srccx) cx = srccx - srcx; if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1); GDISP_LLD(writestreamstart)(); buffer += srcx + srcy * srccx; #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) uint32_t area = cx*cy; uint8_t i; dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer); dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); for (i = area/65535; i; i--) { dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); } dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); #else coord_t endx, endy; unsigned lg; endx = srcx + cx; endy = y + cy; lg = srccx - cx; for(; y < endy; y++, buffer += lg) for(x=srcx; x < endx; x++) GDISP_LLD(writedata)(*buffer++); #endif //#ifdef GDISP_USE_DMA }
void i2c_t::IServeIRQ(uint32_t isr) { // Uart.PrintfI("isr: %X\r", isr); I2C_TypeDef *pi2c = PParams->pi2c; // To make things shorter #if 1 // ==== NACK ==== if((isr & I2C_ISR_NACKF) != 0) { // Stop DMA dmaStreamDisable(PParams->PDmaTx); dmaStreamDisable(PParams->PDmaRx); // Stop transaction pi2c->CR2 |= I2C_CR2_STOP; // Disable IRQs pi2c->CR1 &= ~(I2C_CR1_TCIE | I2C_CR1_TXIE | I2C_CR1_RXIE); IState = istFailure; IWakeup(); return; } #endif #if 1 // ==== TX partly completed ==== if((isr & I2C_ISR_TCR) != 0) { dmaStreamDisable(PParams->PDmaTx); if(IState == istWriteWrite) { // Send next ILen bytes pi2c->CR2 = (pi2c->CR2 & ~(I2C_CR2_NBYTES | I2C_CR2_RELOAD)) | (ILen << 16); // Prepare and enable TX DMA for second write dmaStreamSetMode(PParams->PDmaTx, DMA_MODE_TX); dmaStreamSetMemory0(PParams->PDmaTx, IPtr); dmaStreamSetTransactionSize(PParams->PDmaTx, ILen); dmaStreamEnable(PParams->PDmaTx); IState = istWrite; } } #endif #if 1 // ==== TX completed ==== if((isr & I2C_ISR_TC) != 0) { dmaStreamDisable(PParams->PDmaTx); // } dmaStreamDisable(PParams->PDmaRx); // } Both sorts of transaction may be completed if(IState == istWriteRead) { // Write phase completed // Receive ILen bytes pi2c->CR2 = (pi2c->CR2 & ~I2C_CR2_NBYTES) | I2C_CR2_RD_WRN | (ILen << 16); dmaStreamEnable(PParams->PDmaRx); pi2c->CR2 |= I2C_CR2_START; // Send repeated start IState = istRead; } // if WriteRead else { // istWrite, istRead IState = istIdle; pi2c->CR2 |= I2C_CR2_STOP; pi2c->CR1 &= ~I2C_CR1_TCIE; // Disable TransferComplete IRQ IWakeup(); } } #endif }
void Adc_t::Measure(Thread *PThread, eventmask_t Evt) { IPThread = PThread; IEvt = Evt; // DMA dmaStreamSetMemory0(ADC_DMA, Result); dmaStreamSetTransactionSize(ADC_DMA, ADC_BUF_SZ); dmaStreamSetMode(ADC_DMA, ADC_DMA_MODE); dmaStreamEnable(ADC_DMA); // ADC ADC1->CR1 = ADC_CR1_SCAN; ADC1->CR2 = ADC_CR2_DMA | ADC_CR2_ADON; StartConversion(); }
/** * @brief Puts the receiver in the UART_RX_IDLE state. * * @param[in] uartp pointer to the @p UARTDriver object */ static void set_rx_idle_loop(UARTDriver *uartp) { uint32_t mode; /* RX DMA channel preparation, if the char callback is defined then the TCIE interrupt is enabled too.*/ if (uartp->config->rxchar_cb == NULL) mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC; else mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TCIE; dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf); dmaStreamSetTransactionSize(uartp->dmarx, 1); dmaStreamSetMode(uartp->dmarx, uartp->dmamode | mode); dmaStreamEnable(uartp->dmarx); }
/** * @brief Sends a command with data over the QSPI bus. * @post At the end of the operation the configured callback is invoked. * * @param[in] qspip pointer to the @p QSPIDriver object * @param[in] cmd pointer to the command descriptor * @param[in] n number of bytes to send * @param[in] txbuf the pointer to the transmit buffer * * @notapi */ void qspi_lld_send(QSPIDriver *qspip, const qspi_command_t *cmdp, size_t n, const uint8_t *txbuf) { dmaStreamSetMemory0(qspip->dma, txbuf); dmaStreamSetTransactionSize(qspip->dma, n); dmaStreamSetMode(qspip->dma, qspip->dmamode | STM32_DMA_CR_DIR_M2P); qspip->qspi->DLR = n - 1; qspip->qspi->ABR = cmdp->alt; qspip->qspi->CCR = cmdp->cfg; qspip->qspi->AR = cmdp->addr; dmaStreamEnable(qspip->dma); }
/** * @brief Sends a command then receives data over the QSPI bus. * @post At the end of the operation the configured callback is invoked. * * @param[in] qspip pointer to the @p QSPIDriver object * @param[in] cmd pointer to the command descriptor * @param[in] n number of bytes to send * @param[out] rxbuf the pointer to the receive buffer * * @notapi */ void qspi_lld_receive(QSPIDriver *qspip, const qspi_command_t *cmdp, size_t n, uint8_t *rxbuf) { dmaStreamSetMemory0(qspip->dma, rxbuf); dmaStreamSetTransactionSize(qspip->dma, n); dmaStreamSetMode(qspip->dma, qspip->dmamode | STM32_DMA_CR_DIR_P2M); qspip->qspi->DLR = n - 1; qspip->qspi->ABR = cmdp->alt; qspip->qspi->CCR = cmdp->cfg | QUADSPI_CCR_FMODE_0; qspip->qspi->AR = cmdp->addr; dmaStreamEnable(qspip->dma); }
void LedSk_t::ISetCurrentColors() { PBuf = IBuf + (RST_W_CNT / 2); // First words are zero to form reset // Fill bit buffer for(uint32_t i=0; i<LED_CNT; i++) { AppendBitsMadeOfByte(ICurrentClr[i].G); AppendBitsMadeOfByte(ICurrentClr[i].R); AppendBitsMadeOfByte(ICurrentClr[i].B); AppendBitsMadeOfByte(ICurrentClr[i].W); } // Start transmission dmaStreamSetMemory0(LEDWS_DMA, IBuf); dmaStreamSetTransactionSize(LEDWS_DMA, TOTAL_W_CNT); dmaStreamSetMode(LEDWS_DMA, LED_DMA_MODE); dmaStreamEnable(LEDWS_DMA); }
*/ bool_t sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk, uint8_t *buf, uint32_t n) { uint32_t resp[1]; chDbgCheck((n < (0x1000000 / MMCSD_BLOCK_SIZE)), "max transaction size"); //SDIO->DTIMER = STM32_SDC_READ_TIMEOUT; SDIO->DTIMER = 0xFFFFFFFF; // KL /* Checks for errors and waits for the card to be ready for reading.*/ if (_sdc_wait_for_transfer_state(sdcp)) return CH_FAILED; /* Prepares the DMA channel for writing.*/ dmaStreamSetMemory0(sdcp->dma, buf); dmaStreamSetTransactionSize(sdcp->dma, (n * MMCSD_BLOCK_SIZE) / sizeof (uint32_t)); dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M); dmaStreamEnable(sdcp->dma); /* Setting up data transfer.*/ SDIO->ICR = STM32_SDIO_ICR_ALL_FLAGS; SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | SDIO_MASK_STBITERRIE | SDIO_MASK_RXOVERRIE | SDIO_MASK_DATAENDIE; SDIO->DLEN = n * MMCSD_BLOCK_SIZE; /* Talk to card what we want from it.*/ if (sdc_lld_prepare_read(sdcp, startblk, n, resp) == TRUE) goto error; /* Transaction starts just after DTEN bit setting.*/ SDIO->DCTRL = SDIO_DCTRL_DTDIR | SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN; if (sdc_lld_wait_transaction_end(sdcp, n, resp) == TRUE) goto error; return CH_SUCCESS; error: sdc_lld_error_cleanup(sdcp, n, resp); return CH_FAILED;
// ==== TX DMA IRQ ==== void CmdUart_t::IRQDmaTxHandler() { dmaStreamDisable(UART_DMA_TX); // Registers may be changed only when stream is disabled IFullSlotsCount -= ITransSize; PRead += ITransSize; if(PRead >= (TXBuf + UART_TXBUF_SIZE)) PRead = TXBuf; // Circulate pointer if(IFullSlotsCount == 0) IDmaIsIdle = true; // Nothing left to send else { // There is something to transmit more dmaStreamSetMemory0(UART_DMA_TX, PRead); uint32_t PartSz = (TXBuf + UART_TXBUF_SIZE) - PRead; ITransSize = (IFullSlotsCount > PartSz)? PartSz : IFullSlotsCount; dmaStreamSetTransactionSize(UART_DMA_TX, ITransSize); dmaStreamSetMode(UART_DMA_TX, UART_DMA_TX_MODE); dmaStreamEnable(UART_DMA_TX); // Restart DMA } }