Ejemplo n.º 1
0
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");
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
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
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
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;
}