void Uart_t::Init(uint32_t ABaudrate, GPIO_TypeDef *PGpioTx, const uint16_t APinTx, GPIO_TypeDef *PGpioRx, const uint16_t APinRx) { #else void Uart_t::Init(uint32_t ABaudrate, GPIO_TypeDef *PGpioTx, const uint16_t APinTx) { #endif PinSetupAlterFunc(PGpioTx, APinTx, omPushPull, pudNone, UART_AF); IBaudrate = ABaudrate; // ==== USART configuration ==== if (UART == USART1) { rccEnableUSART1(FALSE); } else if(UART == USART2) { rccEnableUSART2(FALSE); } #if defined STM32F072xB // Setup HSI as UART's clk src if(UART == USART1) RCC->CFGR3 |= RCC_CFGR3_USART1SW_HSI; else if(UART == USART2) RCC->CFGR3 |= RCC_CFGR3_USART2SW_HSI; OnAHBFreqChange(); #else OnAHBFreqChange(); // Setup baudrate #endif UART->CR2 = 0; #if UART_USE_DMA // ==== DMA ==== // Remap DMA request if needed #if defined STM32F0XX if(UART_DMA_TX == STM32_DMA1_STREAM4) SYSCFG->CFGR1 |= SYSCFG_CFGR1_USART1TX_DMA_RMP; #endif dmaStreamAllocate (UART_DMA_TX, IRQ_PRIO_MEDIUM, CmdUartTxIrq, NULL); dmaStreamSetPeripheral(UART_DMA_TX, &UART_TX_REG); dmaStreamSetMode (UART_DMA_TX, UART_DMA_TX_MODE); IDmaIsIdle = true; #endif #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(PGpioRx, APinRx, omOpenDrain, pudPullUp, UART_AF); // Remap DMA request if needed #if defined STM32F0XX if(UART_DMA_RX == STM32_DMA1_STREAM5) SYSCFG->CFGR1 |= SYSCFG_CFGR1_USART1RX_DMA_RMP; #endif dmaStreamAllocate (UART_DMA_RX, IRQ_PRIO_LOW, nullptr, NULL); dmaStreamSetPeripheral(UART_DMA_RX, &UART_RX_REG); dmaStreamSetMemory0 (UART_DMA_RX, IRxBuf); dmaStreamSetTransactionSize(UART_DMA_RX, UART_RXBUF_SZ); dmaStreamSetMode (UART_DMA_RX, UART_DMA_RX_MODE); dmaStreamEnable (UART_DMA_RX); // Thread IPThd = chThdCreateStatic(waUartRxThread, sizeof(waUartRxThread), LOWPRIO, UartRxThread, NULL); #else UART->CR1 = USART_CR1_TE; // Transmitter enabled #if UART_USE_DMA UART->CR3 = USART_CR3_DMAT; // Enable DMA at transmitter #endif #endif UART->CR1 |= USART_CR1_UE; // Enable USART }
static void dma_rx_end_cb(UARTDriver *uart) { osalSysLockFromISR(); uart->usart->CR3 &= ~(USART_CR3_DMAT | USART_CR3_DMAR); (void)uart->usart->SR; (void)uart->usart->DR; (void)uart->usart->DR; dmaStreamDisable(uart->dmarx); dmaStreamDisable(uart->dmatx); iomcu.process_io_packet(); num_total_rx++; num_dma_complete_rx = num_total_rx - num_idle_rx; dmaStreamSetMemory0(uart->dmarx, &iomcu.rx_io_packet); dmaStreamSetTransactionSize(uart->dmarx, sizeof(iomcu.rx_io_packet)); dmaStreamSetMode(uart->dmarx, uart->dmamode | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); dmaStreamEnable(uart->dmarx); uart->usart->CR3 |= USART_CR3_DMAR; dmaStreamSetMemory0(uart->dmatx, &iomcu.tx_io_packet); dmaStreamSetTransactionSize(uart->dmatx, iomcu.tx_io_packet.get_size()); dmaStreamSetMode(uart->dmatx, uart->dmamode | STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); dmaStreamEnable(uart->dmatx); uart->usart->CR3 |= USART_CR3_DMAT; osalSysUnlockFromISR(); }
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 }
uint8_t i2c_t::CmdWriteRead(uint8_t Addr, uint8_t *WPtr, uint8_t WLength, uint8_t *RPtr, uint8_t RLength) { 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(WLength != 0) { if(WaitEv8() != OK) return FAILURE; dmaStreamSetMemory0(PDmaTx, WPtr); dmaStreamSetMode (PDmaTx, I2C_DMATX_MODE); dmaStreamSetTransactionSize(PDmaTx, WLength); chSysLock(); PRequestingThread = chThdSelf(); dmaStreamEnable(PDmaTx); chSchGoSleepS(THD_STATE_SUSPENDED); // Sleep until end chSysUnlock(); dmaStreamDisable(PDmaTx); } // Read if needed if(RLength != 0) { if(WaitEv8() != OK) return FAILURE; // Send repeated start SendStart(); if(WaitEv5() != OK) return FAILURE; SendAddrWithRead(Addr); if(WaitEv6() != OK) { SendStop(); return FAILURE; } // If single byte is to be received, disable ACK before clearing ADDR flag if(RLength == 1) AckDisable(); else AckEnable(); ClearAddrFlag(); dmaStreamSetMemory0(PDmaRx, RPtr); dmaStreamSetMode (PDmaRx, I2C_DMARX_MODE); dmaStreamSetTransactionSize(PDmaRx, RLength); DmaLastTransferSet(); // Inform DMA that this is last transfer => do not ACK last byte chSysLock(); PRequestingThread = chThdSelf(); dmaStreamEnable(PDmaRx); chSchGoSleepS(THD_STATE_SUSPENDED); // Sleep until end chSysUnlock(); dmaStreamDisable(PDmaRx); } // if != 0 else WaitBTF(); // if nothing to read, just stop SendStop(); return OK; }
void i2c_t::Init( I2C_TypeDef *pi2c, GPIO_TypeDef *PGpio, uint16_t SclPin, uint16_t SdaPin, uint32_t BitrateHz, const stm32_dma_stream_t *APDmaTx, const stm32_dma_stream_t *APDmaRx ) { ii2c = pi2c; IPGpio = PGpio; ISclPin = SclPin; ISdaPin = SdaPin; IBitrateHz = BitrateHz; Standby(); Resume(); // ==== DMA ==== // Here only unchanged parameters of the DMA are configured. uint16_t DmaChnl = 3; // I2C3 if (ii2c == I2C1) DmaChnl = 1; else if (ii2c == I2C2) DmaChnl = 7; // Setup Dma TX PDmaTx = APDmaTx; dmaStreamAllocate(PDmaTx, IRQ_PRIO_MEDIUM, i2cDmaIrqHandler, this); dmaStreamSetPeripheral(PDmaTx, &ii2c->DR); dmaStreamSetMode (PDmaTx, STM32_DMA_CR_CHSEL(DmaChnl) | DMA_PRIORITY_LOW | STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MINC | // Memory pointer increase STM32_DMA_CR_DIR_M2P | // Direction is memory to peripheral STM32_DMA_CR_TCIE // Enable Transmission Complete IRQ ); // Setup Dma RX PDmaRx = APDmaRx; dmaStreamAllocate(PDmaRx, IRQ_PRIO_MEDIUM, i2cDmaIrqHandler, this); //dmaStreamAllocate(PDmaRx, 1, i2cDmaRXIrqHandler, NULL); dmaStreamSetPeripheral(PDmaRx, &ii2c->DR); dmaStreamSetMode (PDmaRx, STM32_DMA_CR_CHSEL(DmaChnl) | DMA_PRIORITY_LOW | STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MINC | // Memory pointer increase STM32_DMA_CR_DIR_P2M // Direction is peripheral to memory | STM32_DMA_CR_TCIE // Enable Transmission Complete IRQ ); }
/** * @brief Sends data over the SPI bus. * @details This asynchronous function starts a transmit 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 send * @param[in] txbuf the pointer to the transmit buffer * * @notapi */ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { dmaStreamSetMemory0(spip->dmarx, &dummyrx); dmaStreamSetTransactionSize(spip->dmarx, n); dmaStreamSetMode(spip->dmarx, spip->rxdmamode); dmaStreamSetMemory0(spip->dmatx, txbuf); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC); dmaStreamEnable(spip->dmarx); dmaStreamEnable(spip->dmatx); }
/** * @brief Ignores data on the SPI bus. * @details This asynchronous function starts the transmission of a series of * idle words on the SPI bus and ignores the received data. * @post At the end of the operation the configured callback is invoked. * * @param[in] spip pointer to the @p SPIDriver object * @param[in] n number of words to be ignored * * @notapi */ void spi_lld_ignore(SPIDriver *spip, size_t n) { dmaStreamSetMemory0(spip->dmarx, &dummyrx); dmaStreamSetTransactionSize(spip->dmarx, n); dmaStreamSetMode(spip->dmarx, spip->rxdmamode); dmaStreamSetMemory0(spip->dmatx, &dummytx); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode); dmaStreamEnable(spip->dmarx); dmaStreamEnable(spip->dmatx); }
/** * @brief Receives data from the SPI bus. * @details This asynchronous function starts a 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 receive * @param[out] rxbuf the pointer to the receive buffer * * @notapi */ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { dmaStreamSetMemory0(spip->dmarx, rxbuf); dmaStreamSetTransactionSize(spip->dmarx, n); dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC); dmaStreamSetMemory0(spip->dmatx, &dummytx); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode); dmaStreamEnable(spip->dmarx); dmaStreamEnable(spip->dmatx); }
/** * @brief Ignores data on the SPI bus. * @details This asynchronous function starts the transmission of a series of * idle words on the SPI bus and ignores the received data. * @post At the end of the operation the configured callback is invoked. * * @param[in] spip pointer to the @p SPIDriver object * @param[in] n number of words to be ignored * * @notapi */ void spi_lld_ignore(SPIDriver *spip, size_t n) { osalDbgAssert(n < 65536, "unsupported DMA transfer size"); dmaStreamSetMemory0(spip->dmarx, &dummyrx); dmaStreamSetTransactionSize(spip->dmarx, n); dmaStreamSetMode(spip->dmarx, spip->rxdmamode); dmaStreamSetMemory0(spip->dmatx, &dummytx); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode); dmaStreamEnable(spip->dmarx); dmaStreamEnable(spip->dmatx); }
/** * @brief Receives data from the SPI bus. * @details This asynchronous function starts a 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 receive * @param[out] rxbuf the pointer to the receive buffer * * @notapi */ void spi_lld_receive(SPIDriver *spip, size_t n, 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, &dummytx); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode); 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; 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); dmaStreamEnable(adcp->dmastp); /* 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; }
static void usart_support_init_tx(struct usart_support_s *sd) { /* Setup TX DMA */ dmaStreamSetMode(sd->tx.dma, sd->dmamode | STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); dmaStreamSetPeripheral(sd->tx.dma, &sd->usart->DR); }
static void idle_rx_handler(UARTDriver *uart) { volatile uint16_t sr = uart->usart->SR; if (sr & (USART_SR_LBD | USART_SR_ORE | /* overrun error - packet was too big for DMA or DMA was too slow */ USART_SR_NE | /* noise error - we have lost a byte due to noise */ USART_SR_FE | USART_SR_PE)) { /* framing error - start/stop bit lost or line break */ /* send a line break - this will abort transmission/reception on the other end */ osalSysLockFromISR(); uart->usart->SR = ~USART_SR_LBD; uart->usart->CR1 |= USART_CR1_SBK; num_rx_error++; uart->usart->CR3 &= ~(USART_CR3_DMAT | USART_CR3_DMAR); (void)uart->usart->SR; (void)uart->usart->DR; (void)uart->usart->DR; dmaStreamDisable(uart->dmarx); dmaStreamDisable(uart->dmatx); dmaStreamSetMemory0(uart->dmarx, &iomcu.rx_io_packet); dmaStreamSetTransactionSize(uart->dmarx, sizeof(iomcu.rx_io_packet)); dmaStreamSetMode(uart->dmarx, uart->dmamode | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); dmaStreamEnable(uart->dmarx); uart->usart->CR3 |= USART_CR3_DMAR; osalSysUnlockFromISR(); return; } if (sr & USART_SR_IDLE) { dma_rx_end_cb(uart); num_idle_rx++; } }
void Adc_t::Init() { rccResetADC1(); rccEnableADC1(FALSE); // Enable digital clock // Configure ADC1->CFGR1 = (ADC_CFGR1_CONT | ADC_CFGR1_DMAEN); // Enable Continuous mode and DMA request ADC1->CFGR2 = (0b01 << 30); // Clock: PCLK/2 // Setup channels ADC1->CHSELR = 0; for(uint8_t i=0; i < ADC_CHANNEL_CNT; i++) { ADC1->CHSELR |= (1 << AdcChannels[i]); } ADC1->SMPR = (uint32_t)ast55d5Cycles; // Setup sampling time // Calibrate uint32_t cnt=0; ADC1->CR |= ADC_CR_ADCAL; // Start calibration while(BitIsSet(ADC1->CR, ADC_CR_ADCAL)) { if(cnt++ >= 63000) { Uart.Printf("ADC calib fail\r"); return; } } // Enable ADC ADC1->CR |= ADC_CR_ADEN; // Enable ADC while(!BitIsSet(ADC1->ISR, ADC_ISR_ADRDY)); // Wait until ADC is ready // ==== DMA ==== dmaStreamAllocate (ADC_DMA, IRQ_PRIO_LOW, AdcTxIrq, NULL); dmaStreamSetPeripheral(ADC_DMA, &ADC1->DR); dmaStreamSetMode (ADC_DMA, ADC_DMA_MODE); // Uart.Printf("ADC is set\r"); }
/** * @brief Fill an area with a color. * @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] color The color of the fill * * @notapi */ void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { uint32_t area; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } 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 area = cx*cy; gdisp_lld_setwindow(x, y, x+cx-1, y+cy-1); write_index(RA8875_WRITE_MEMORY_START); #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) uint8_t i; dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color); dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | 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 uint32_t index; for(index = 0; index < area; index++) write_data(color); #endif //#ifdef GDISP_USE_DMA }
void DbgUart_t::Init(uint32_t ABaudrate) { PWrite = TXBuf; PRead = TXBuf; ICountToSendNext = 0; IDmaIsIdle = true; //PinSetupAlterFunc(GPIOA, 9, omPushPull, pudNone, AF7); // TX1 PinSetupAlterFunc(GPIOA, 2, omPushPull, pudNone, AF7); // TX2 // ==== USART configuration ==== UART_RCC_ENABLE(); UART->BRR = Clk.APB2FreqHz / ABaudrate; UART->CR2 = 0; UART->CR3 = USART_CR3_DMAT; // Enable DMA at transmitter UART->CR1 = USART_CR1_TE; // Transmitter enabled // ==== DMA ==== // Here only the unchanged parameters of the DMA are configured. dmaStreamAllocate (UART_DMA, 1, DbgUartIrq, NULL); dmaStreamSetPeripheral(UART_DMA, &UART->DR); dmaStreamSetMode (UART_DMA, STM32_DMA_CR_CHSEL(UART_DMA_CHNL) | DMA_PRIORITY_LOW | STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MINC | // Memory pointer increase STM32_DMA_CR_DIR_M2P | // Direction is memory to peripheral STM32_DMA_CR_TCIE // Enable Transmission Complete IRQ ); UART->CR1 |= USART_CR1_UE; // Enable USART }
void Lcd_t::Init(void) { BckLt.Init(LCD_BCKLT_GPIO, LCD_BCKLT_PIN, LCD_BCKLT_TMR, LCD_BCKLT_CHNL, LCD_TOP_BRIGHTNESS); // Remap Timer15 to PB14 & PB15 AFIO->MAPR2 |= 0x00000001; // ==== GPIOs ==== // Configure LCD_XRES, LCD_XCS, LCD_SCLK & LCD_SDA as Push-Pull output PinSetupOut(LCD_GPIO, LCD_XRES, omPushPull); PinSetupOut(LCD_GPIO, LCD_XRES, omPushPull); PinSetupOut(LCD_GPIO, LCD_XCS, omPushPull); PinSetupOut(LCD_GPIO, LCD_SCLK, omPushPull); PinSetupOut(LCD_GPIO, LCD_SDA, omPushPull); // ========================= Init LCD ====================================== SCLK_Lo(); XCS_Hi(); // Reset display XRES_Lo(); chThdSleepMilliseconds(7); XRES_Hi(); WriteCmd(0xAF); // display ON // Reset display again XRES_Lo(); chThdSleepMilliseconds(7); XRES_Hi(); chThdSleepMilliseconds(7); // Initial commands WriteCmd(0xAF); // display ON WriteCmd(0xA4); // Set normal display mode WriteCmd(0x2F); // Charge pump on WriteCmd(0x40); // Set start row address = 0 WriteCmd(0xC8); // Mirror Y axis //WriteCmd(0xA1); // Mirror X axis // Set x=0, y=0 WriteCmd(0xB0); // Y axis initialization WriteCmd(0x10); // X axis initialisation1 WriteCmd(0x00); // X axis initialisation2 Cls(); // clear LCD buffer // ====================== Switch to USART + DMA ============================ PinSetupAlterFuncOutput(LCD_GPIO, LCD_SCLK, omPushPull); PinSetupAlterFuncOutput(LCD_GPIO, LCD_SDA, omPushPull); // Workaround hardware bug with disabled CK3 when SPI2 is enabled SPI2->CR2 |= SPI_CR2_SSOE; // ==== USART init ==== clock enabled, idle low, first edge, enable last bit pulse rccEnableUSART3(FALSE); USART3->CR1 = USART_CR1_UE; // Enable USART3->BRR = Clk.APB1FreqHz / LCD_UART_SPEED; USART3->CR2 = USART_CR2_CLKEN | USART_CR2_LBCL; // Enable clock, enable last bit clock USART3->CR1 = USART_CR1_UE | USART_CR1_M | USART_CR1_TE; USART3->CR3 = USART_CR3_DMAT; // Enable DMA at transmitter // DMA dmaStreamAllocate (LCD_DMA, IRQ_PRIO_LOW, nullptr, NULL); dmaStreamSetPeripheral(LCD_DMA, &USART3->DR); dmaStreamSetMemory0 (LCD_DMA, IBuf); dmaStreamSetTransactionSize(LCD_DMA, LCD_VIDEOBUF_SIZE); dmaStreamSetMode (LCD_DMA, LCD_DMA_TX_MODE); // Start transmission XCS_Lo(); dmaStreamEnable(LCD_DMA); }
uint8_t i2c_t::Write(uint32_t Addr, uint8_t *WPtr, uint32_t WLength) { 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 WriteEnd; } if(IBusyWait() != OK) { Rslt = BUSY; goto WriteEnd; } IReset(); // Reset I2C // Prepare TX DMA dmaStreamSetMode(PParams->PDmaTx, DMA_MODE_TX); dmaStreamSetMemory0(PParams->PDmaTx, WPtr); dmaStreamSetTransactionSize(PParams->PDmaTx, WLength); // Prepare tx 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; WriteEnd: chBSemSignal(&BSemaphore); return Rslt; }
void DbgUart_t::Init(uint32_t ABaudrate) { PWrite = TXBuf; PRead = TXBuf; ICountToSendNext = 0; IDmaIsIdle = true; PinSetupAlterFunc(GPIOA, 9, omPushPull, pudNone, AF7); // TX1 // ==== USART configuration ==== rccEnableUSART1(FALSE); // UART clock, no clock in low-power USART1->BRR = Clk.APB2FreqHz / 115200; USART1->CR2 = 0; USART1->CR3 = USART_CR3_DMAT; // Enable DMA at transmitter USART1->CR1 = USART_CR1_TE; // Transmitter enabled // ==== DMA ==== // Here only the unchanged parameters of the DMA are configured. dmaStreamAllocate (STM32_DMA2_STREAM7, 1, DbgUartIrq, NULL); dmaStreamSetPeripheral(STM32_DMA2_STREAM7, &USART1->DR); dmaStreamSetMode (STM32_DMA2_STREAM7, STM32_DMA_CR_CHSEL(4) | // DMA2 Stream7 Channel4 is USART1_TX request DMA_PRIORITY_LOW | STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MINC | // Memory pointer increase STM32_DMA_CR_DIR_M2P | // Direction is memory to peripheral STM32_DMA_CR_TCIE // Enable Transmission Complete IRQ ); USART1->CR1 |= USART_CR1_UE; // Enable USART }
void DbgUart_t::Init(uint32_t ABaudrate) { PWrite = TXBuf; PRead = TXBuf; ICountToSendNext = 0; IDmaIsIdle = true; PinSetupAlterFuncOutput(GPIOA, 9, omPushPull); // TX1 // ==== USART configuration ==== rccEnableUSART1(FALSE); // UART clock USART1->BRR = Clk.APB2FreqHz / ABaudrate; USART1->CR2 = 0; USART1->CR3 = USART_CR3_DMAT; // Enable DMA at transmitter USART1->CR1 = USART_CR1_TE; // Transmitter enabled // ==== DMA ==== // Here only the unchanged parameters of the DMA are configured. dmaStreamAllocate (STM32_DMA1_STREAM4, 1, DbgUartIrq, NULL); dmaStreamSetPeripheral(STM32_DMA1_STREAM4, &USART1->DR); dmaStreamSetMode (STM32_DMA1_STREAM4, STM32_DMA_CR_PL(0b10) | // Priority is high STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MINC | // Memory pointer increase STM32_DMA_CR_DIR_M2P | // Direction is memory to peripheral STM32_DMA_CR_TCIE // Enable Transmission Complete IRQ ); USART1->CR1 |= USART_CR1_UE; // Enable USART }
/** * @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; }
/** * @brief Fill an area with a color. * @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] color The color of the fill * * @notapi */ void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } 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 uint32_t area; area = cx*cy; GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1); GDISP_LLD(writestreamstart)(); #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) uint8_t i; dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color); dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | 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 uint32_t index; for(index = 0; index < area; index++) GDISP_LLD(writedata)(color); #endif //#ifdef GDISP_USE_DMA }
/** * @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 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->sdmmc->DTIMER = SDMMC_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->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS; sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_DTIMEOUTIE | SDMMC_MASK_RXOVERRIE | SDMMC_MASK_DATAENDIE; sdcp->sdmmc->DLEN = bytes; /* Transaction starts just after DTEN bit setting.*/ sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DTDIR | SDMMC_DCTRL_DTMODE | /* multibyte data transfer */ SDMMC_DCTRL_DMAEN | SDMMC_DCTRL_DTEN; return HAL_SUCCESS; }
/** * @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); }
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(); }
/** * @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); }
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(); }