void interface_init(void) { pc_txns = perf_alloc(PC_ELAPSED, "txns"); pc_errors = perf_alloc(PC_COUNT, "errors"); pc_ore = perf_alloc(PC_COUNT, "overrun"); pc_fe = perf_alloc(PC_COUNT, "framing"); pc_ne = perf_alloc(PC_COUNT, "noise"); pc_idle = perf_alloc(PC_COUNT, "idle"); pc_badidle = perf_alloc(PC_COUNT, "badidle"); pc_regerr = perf_alloc(PC_COUNT, "regerr"); pc_crcerr = perf_alloc(PC_COUNT, "crcerr"); /* allocate DMA */ tx_dma = stm32_dmachannel(PX4FMU_SERIAL_TX_DMA); rx_dma = stm32_dmachannel(PX4FMU_SERIAL_RX_DMA); /* configure pins for serial use */ stm32_configgpio(PX4FMU_SERIAL_TX_GPIO); stm32_configgpio(PX4FMU_SERIAL_RX_GPIO); /* reset and configure the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* clear status/errors */ (void)rSR; (void)rDR; /* configure line speed */ uint32_t usartdiv32 = PX4FMU_SERIAL_CLOCK / (PX4FMU_SERIAL_BITRATE / 2); uint32_t mantissa = usartdiv32 >> 5; uint32_t fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1; rBRR = (mantissa << USART_BRR_MANT_SHIFT) | (fraction << USART_BRR_FRAC_SHIFT); /* connect our interrupt */ irq_attach(PX4FMU_SERIAL_VECTOR, serial_interrupt); up_enable_irq(PX4FMU_SERIAL_VECTOR); /* enable UART and error/idle interrupts */ rCR3 = USART_CR3_EIE; rCR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE | USART_CR1_IDLEIE; #if 0 /* keep this for signal integrity testing */ for (;;) { while (!(rSR & USART_SR_TXE)) ; rDR = 0xfa; while (!(rSR & USART_SR_TXE)) ; rDR = 0xa0; } #endif /* configure RX DMA and return to listening state */ dma_reset(); debug("serial init"); }
void interface_init(void) { debug("i2c init"); /* allocate DMA handles and initialise DMA */ rx_dma = stm32_dmachannel(DMACHAN_I2C1_RX); i2c_rx_setup(); tx_dma = stm32_dmachannel(DMACHAN_I2C1_TX); i2c_tx_setup(); /* enable the i2c block clock and reset it */ modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_I2C1EN); modifyreg32(STM32_RCC_APB1RSTR, 0, RCC_APB1RSTR_I2C1RST); modifyreg32(STM32_RCC_APB1RSTR, RCC_APB1RSTR_I2C1RST, 0); /* configure the i2c GPIOs */ stm32_configgpio(GPIO_I2C1_SCL); stm32_configgpio(GPIO_I2C1_SDA); /* soft-reset the block */ rCR1 |= I2C_CR1_SWRST; rCR1 = 0; /* set for DMA operation */ rCR2 |= I2C_CR2_ITEVFEN | I2C_CR2_ITERREN | I2C_CR2_DMAEN; /* set the frequency value in CR2 */ rCR2 &= ~I2C_CR2_FREQ_MASK; rCR2 |= STM32_PCLK1_FREQUENCY / 1000000; /* set divisor and risetime for fast mode */ uint16_t result = STM32_PCLK1_FREQUENCY / (400000 * 25); if (result < 1) { result = 1; } result = 3; rCCR &= ~I2C_CCR_CCR_MASK; rCCR |= I2C_CCR_DUTY | I2C_CCR_FS | result; rTRISE = (uint16_t)((((STM32_PCLK1_FREQUENCY / 1000000) * 300) / 1000) + 1); /* set our device address */ rOAR1 = 0x1a << 1; /* enable event interrupts */ irq_attach(STM32_IRQ_I2C1EV, i2c_interrupt); irq_attach(STM32_IRQ_I2C1ER, i2c_interrupt); up_enable_irq(STM32_IRQ_I2C1EV); up_enable_irq(STM32_IRQ_I2C1ER); /* and enable the I2C port */ rCR1 |= I2C_CR1_ACK | I2C_CR1_PE; #ifdef DEBUG i2c_dump(); #endif }
int PX4IO_serial::init() { /* allocate DMA */ _tx_dma = stm32_dmachannel(PX4IO_SERIAL_TX_DMAMAP); _rx_dma = stm32_dmachannel(PX4IO_SERIAL_RX_DMAMAP); if ((_tx_dma == nullptr) || (_rx_dma == nullptr)) { return -1; } /* configure pins for serial use */ stm32_configgpio(PX4IO_SERIAL_TX_GPIO); stm32_configgpio(PX4IO_SERIAL_RX_GPIO); /* reset & configure the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* eat any existing interrupt status */ (void)rSR; (void)rDR; /* configure line speed */ uint32_t usartdiv32 = PX4IO_SERIAL_CLOCK / (PX4IO_SERIAL_BITRATE / 2); uint32_t mantissa = usartdiv32 >> 5; uint32_t fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1; rBRR = (mantissa << USART_BRR_MANT_SHIFT) | (fraction << USART_BRR_FRAC_SHIFT); /* attach serial interrupt handler */ irq_attach(PX4IO_SERIAL_VECTOR, _interrupt); up_enable_irq(PX4IO_SERIAL_VECTOR); /* enable UART in DMA mode, enable error and line idle interrupts */ rCR3 = USART_CR3_EIE; rCR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE | USART_CR1_IDLEIE; /* create semaphores */ sem_init(&_completion_semaphore, 0, 0); sem_init(&_bus_semaphore, 0, 1); /* XXX this could try talking to IO */ return 0; }
void interface_init(void) { debug("spi init"); pc_txns = perf_alloc(PC_ELAPSED, "txns"); pc_errors = perf_alloc(PC_COUNT, "errors"); pc_ore = perf_alloc(PC_COUNT, "overrun"); pc_fe = perf_alloc(PC_COUNT, "framing"); pc_ne = perf_alloc(PC_COUNT, "noise"); pc_idle = perf_alloc(PC_COUNT, "idle"); pc_badidle = perf_alloc(PC_COUNT, "badidle"); pc_regerr = perf_alloc(PC_COUNT, "regerr"); pc_crcerr = perf_alloc(PC_COUNT, "crcerr"); /* allocate DMA handles and initialise DMA */ rx_dma = stm32_dmachannel(DMACHAN_SPI3_RX); tx_dma = stm32_dmachannel(DMACHAN_SPI3_TX); /* enable the spi block clock and reset it */ modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_SPI3EN); modifyreg32(STM32_RCC_APB1RSTR, 0, RCC_APB1RSTR_SPI3RST); modifyreg32(STM32_RCC_APB1RSTR, RCC_APB1RSTR_SPI3RST, 0); /* configure the spi GPIOs */ stm32_configgpio(RPI_SPI_NSS); stm32_configgpio(RPI_SPI_SCK); stm32_configgpio(RPI_SPI_MISO); stm32_configgpio(RPI_SPI_MOSI); /* reset and configure the SPI */ rCR1 = SPI_CR1_CPHA | SPI_CR1_CPOL; /* set for DMA operation */ rCR2 = SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN | SPI_CR2_ERRIE; /* enable event interrupts */ irq_attach(STM32_IRQ_SPI3, spi_interrupt); up_enable_irq(STM32_IRQ_SPI3); /* configure RX DMA and return to listening state */ dma_reset(); /* and enable the SPI port */ rCR1 |= SPI_CR1_SPE; #ifdef DEBUG spi_dump(); #endif }
static int dac_chaninit(FAR struct stm32_chan_s *chan) { uint16_t clearbits; uint16_t setbits; #ifdef HAVE_TIMER int ret; #endif /* Is the selected channel already in-use? */ if (chan->inuse) { /* Yes.. then return EBUSY */ return -EBUSY; } /* Configure the DAC output pin: * * DAC -" Once the DAC channelx is enabled, the corresponding GPIO pin * (PA4 or PA5) is automatically connected to the analog converter output * (DAC_OUTx). In order to avoid parasitic consumption, the PA4 or PA5 pin * should first be configured to analog (AIN)". */ stm32_configgpio(chan->pin); /* DAC channel configuration: * * - Set the trigger selection based upon the configuration. * - Set wave generation == None. * - Enable the output buffer. */ /* Disable before change */ stm32_dac_modify_cr(chan, DAC_CR_EN, 0); clearbits = DAC_CR_TSEL_MASK | DAC_CR_MAMP_MASK | DAC_CR_WAVE_MASK | DAC_CR_BOFF; setbits = chan->tsel | /* Set trigger source (SW or timer TRGO event) */ DAC_CR_MAMP_AMP1 | /* Set waveform characteristics */ DAC_CR_WAVE_DISABLED | /* Set no noise */ DAC_CR_BOFF_EN; /* Enable output buffer */ stm32_dac_modify_cr(chan, clearbits, setbits); #ifdef HAVE_DMA /* Determine if DMA is supported by this channel */ if (chan->hasdma) { /* Remap DMA request if necessary*/ dma_remap(chan); /* DAC trigger enable if not external triggering */ if (!chan->text) { stm32_dac_modify_cr(chan, 0, DAC_CR_TEN); } /* Allocate a DMA channel */ chan->dma = stm32_dmachannel(chan->dmachan); if (!chan->dma) { aerr("ERROR: Failed to allocate a DMA channel\n"); return -EBUSY; } /* Configure the timer that supports the DMA operation * Do nothing if HRTIM is selected as trigger. * All necessary configuration is done in the HRTIM driver. */ #ifdef HAVE_TIMER if (chan->timer != TIM_INDEX_HRTIM) { ret = dac_timinit(chan); if (ret < 0) { aerr("ERROR: Failed to initialize the DMA timer: %d\n", ret); return ret; } } #endif } #endif /* Mark the DAC channel "in-use" */ chan->inuse = 1; return OK; }
PX4IO_serial_f4::PX4IO_serial_f4() : _tx_dma(nullptr), _rx_dma(nullptr), _current_packet(nullptr), _rx_dma_status(_dma_status_inactive), _completion_semaphore(SEM_INITIALIZER(0)), #if 0 _pc_dmasetup(perf_alloc(PC_ELAPSED, "io_dmasetup ")), _pc_dmaerrs(perf_alloc(PC_COUNT, "io_dmaerrs ")) #else _pc_dmasetup(nullptr), _pc_dmaerrs(nullptr) #endif { } PX4IO_serial_f4::~PX4IO_serial_f4() { if (_tx_dma != nullptr) { stm32_dmastop(_tx_dma); stm32_dmafree(_tx_dma); } if (_rx_dma != nullptr) { stm32_dmastop(_rx_dma); stm32_dmafree(_rx_dma); } /* reset the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* detach our interrupt handler */ up_disable_irq(PX4IO_SERIAL_VECTOR); irq_detach(PX4IO_SERIAL_VECTOR); /* restore the GPIOs */ px4_arch_unconfiggpio(PX4IO_SERIAL_TX_GPIO); px4_arch_unconfiggpio(PX4IO_SERIAL_RX_GPIO); /* Disable APB clock for the USART peripheral */ modifyreg32(PX4IO_SERIAL_RCC_REG, PX4IO_SERIAL_RCC_EN, 0); /* and kill our semaphores */ px4_sem_destroy(&_completion_semaphore); perf_free(_pc_dmasetup); perf_free(_pc_dmaerrs); } int PX4IO_serial_f4::init() { /* initialize base implementation */ int r; if ((r = PX4IO_serial::init(&_io_buffer_storage)) != 0) { return r; } /* allocate DMA */ _tx_dma = stm32_dmachannel(PX4IO_SERIAL_TX_DMAMAP); _rx_dma = stm32_dmachannel(PX4IO_SERIAL_RX_DMAMAP); if ((_tx_dma == nullptr) || (_rx_dma == nullptr)) { return -1; } /* Enable the APB clock for the USART peripheral */ modifyreg32(PX4IO_SERIAL_RCC_REG, 0, PX4IO_SERIAL_RCC_EN); /* configure pins for serial use */ px4_arch_configgpio(PX4IO_SERIAL_TX_GPIO); px4_arch_configgpio(PX4IO_SERIAL_RX_GPIO); /* reset & configure the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* eat any existing interrupt status */ (void)rSR; (void)rDR; /* configure line speed */ uint32_t usartdiv32 = PX4IO_SERIAL_CLOCK / (PX4IO_SERIAL_BITRATE / 2); uint32_t mantissa = usartdiv32 >> 5; uint32_t fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1; rBRR = (mantissa << USART_BRR_MANT_SHIFT) | (fraction << USART_BRR_FRAC_SHIFT); /* attach serial interrupt handler */ irq_attach(PX4IO_SERIAL_VECTOR, _interrupt, this); up_enable_irq(PX4IO_SERIAL_VECTOR); /* enable UART in DMA mode, enable error and line idle interrupts */ rCR3 = USART_CR3_EIE; rCR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE | USART_CR1_IDLEIE; /* create semaphores */ px4_sem_init(&_completion_semaphore, 0, 0); /* _completion_semaphore use case is a signal */ px4_sem_setprotocol(&_completion_semaphore, SEM_PRIO_NONE); /* XXX this could try talking to IO */ return 0; }
PX4IO_serial_f7::PX4IO_serial_f7() : _tx_dma(nullptr), _rx_dma(nullptr), _current_packet(nullptr), _rx_dma_status(_dma_status_inactive), _completion_semaphore(SEM_INITIALIZER(0)), #if 0 _pc_dmasetup(perf_alloc(PC_ELAPSED, "io_dmasetup ")), _pc_dmaerrs(perf_alloc(PC_COUNT, "io_dmaerrs ")) #else _pc_dmasetup(nullptr), _pc_dmaerrs(nullptr) #endif { } PX4IO_serial_f7::~PX4IO_serial_f7() { if (_tx_dma != nullptr) { stm32_dmastop(_tx_dma); stm32_dmafree(_tx_dma); } if (_rx_dma != nullptr) { stm32_dmastop(_rx_dma); stm32_dmafree(_rx_dma); } /* reset the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* detach our interrupt handler */ up_disable_irq(PX4IO_SERIAL_VECTOR); irq_detach(PX4IO_SERIAL_VECTOR); /* restore the GPIOs */ px4_arch_unconfiggpio(PX4IO_SERIAL_TX_GPIO); px4_arch_unconfiggpio(PX4IO_SERIAL_RX_GPIO); /* Disable APB clock for the USART peripheral */ modifyreg32(PX4IO_SERIAL_RCC_REG, PX4IO_SERIAL_RCC_EN, 0); /* and kill our semaphores */ px4_sem_destroy(&_completion_semaphore); perf_free(_pc_dmasetup); perf_free(_pc_dmaerrs); } int PX4IO_serial_f7::init() { /* initialize base implementation */ int r; if ((r = PX4IO_serial::init((IOPacket *)ROUND_UP_TO_POW2_CT((uintptr_t)_io_buffer_storage, CACHE_LINE_SIZE))) != 0) { return r; } /* allocate DMA */ _tx_dma = stm32_dmachannel(PX4IO_SERIAL_TX_DMAMAP); _rx_dma = stm32_dmachannel(PX4IO_SERIAL_RX_DMAMAP); if ((_tx_dma == nullptr) || (_rx_dma == nullptr)) { return -1; } /* Enable the APB clock for the USART peripheral */ modifyreg32(PX4IO_SERIAL_RCC_REG, 0, PX4IO_SERIAL_RCC_EN); /* configure pins for serial use */ px4_arch_configgpio(PX4IO_SERIAL_TX_GPIO); px4_arch_configgpio(PX4IO_SERIAL_RX_GPIO); /* reset & configure the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* clear data that may be in the RDR and clear overrun error: */ if (rISR & USART_ISR_RXNE) { (void)rRDR; } rICR = rISR & rISR_ERR_FLAGS_MASK; /* clear the flags */ /* configure line speed */ uint32_t usartdiv32 = (PX4IO_SERIAL_CLOCK + (PX4IO_SERIAL_BITRATE) / 2) / (PX4IO_SERIAL_BITRATE); rBRR = usartdiv32; /* attach serial interrupt handler */ irq_attach(PX4IO_SERIAL_VECTOR, _interrupt, this); up_enable_irq(PX4IO_SERIAL_VECTOR); /* enable UART in DMA mode, enable error and line idle interrupts */ rCR3 = USART_CR3_EIE; /* TODO: maybe use DDRE */ rCR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE | USART_CR1_IDLEIE; /* TODO: maybe we need to adhere to the procedure as described in the reference manual page 1251 (34.5.2) */ /* create semaphores */ px4_sem_init(&_completion_semaphore, 0, 0); /* _completion_semaphore use case is a signal */ px4_sem_setprotocol(&_completion_semaphore, SEM_PRIO_NONE); /* XXX this could try talking to IO */ return 0; }