Beispiel #1
0
/**
 * @brief   Shared end-of-rx service routine.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] flags     pre-shifted content of the ISR register
 */
static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {

  /* DMA errors handling.*/
#if defined(STM32_SPI_DMA_ERROR_HOOK)
  if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
    STM32_SPI_DMA_ERROR_HOOK(spip);
  }
#else
  (void)flags;
#endif

  /* Stop everything.*/
  dmaStreamDisable(spip->dmatx);
  dmaStreamDisable(spip->dmarx);

#if STM32_SPI_USE_BIDIMODE
  spip->spi->CR1 |= SPI_CR1_BIDIOE;

  /* Errors reset sequence. It is required becaue BIDIOE could cause extra
     clock pulses after DMA stopped reading.*/
  (void)spip->spi->DR;
  (void)spip->spi->SR;
#endif

  /* Portable SPI ISR code defined in the high level driver, note, it is
     a macro.*/
  _spi_isr_code(spip);
}
Beispiel #2
0
/**
 * @brief   Common IRQ handler.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 */
static void serve_interrupt(SPIDriver *spip) {
  SSP *ssp = spip->spd_ssp;

  if ((ssp->SSP_MIS & MIS_ROR) != 0) {
    /* The overflow condition should never happen because priority is given
       to receive but a hook macro is provided anyway...*/
    LPC214x_SPI_SSP_ERROR_HOOK();
  }
  ssp->SSP_ICR = ICR_RT | ICR_ROR;
  while ((ssp->SSP_SR & SR_RNE) != 0) {
    if (spip->spd_rxptr != NULL) {
      if ((ssp->SSP_CR0 & CR0_DSSMASK) > CR0_DSS8BIT)
        *(uint16_t *)spip->spd_rxptr++ = ssp->SSP_DR;
      else
        *(uint8_t *)spip->spd_rxptr++ = ssp->SSP_DR;
    }
    else
      (void)ssp->SSP_DR;
    if (--spip->spd_rxcnt == 0) {
      chDbgAssert(spip->spd_txcnt == 0,
                  "spi_serve_interrupt(), #1", "counter out of synch");
      /* Stops the IRQ sources.*/
      ssp->SSP_IMSC = 0;
      /* Portable SPI ISR code defined in the high level driver, note, it is
         a macro.*/
      _spi_isr_code(spip);
      return;
    }
  }
  ssp_fifo_preload(spip);
  if (spip->spd_txcnt == 0)
    ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
}
Beispiel #3
0
static void spi_serve_rx_irq(edma_channel_t channel, void *p) {
  SPIDriver *spip = (SPIDriver *)p;

  (void)channel;

  /* Stops the DSPI and clears the queues.*/
  spip->dspi->MCR.R = SPC5_MCR_MSTR    | SPC5_MCR_HALT    |
                      SPC5_MCR_CLR_TXF | SPC5_MCR_CLR_RXF;

  /* Portable SPI ISR code defined in the high level driver, note, it is
     a macro.*/
  _spi_isr_code(spip);
}
Beispiel #4
0
/**
 * @brief   Shared interrupt handling code.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 */
static void spi_lld_serve_interrupt(SPIDriver *spip) {
    uint32_t sr = spip->spi->SPI_SR;

    if ((sr & AT91C_SPI_ENDRX) != 0) {
        (void)spip->spi->SPI_RDR;                   /* Clears eventual overflow.*/
        spip->spi->SPI_PTCR = AT91C_PDC_RXTDIS |
                              AT91C_PDC_TXTDIS; /* PDC disabled.            */
        spip->spi->SPI_IDR  = AT91C_SPI_ENDRX;      /* Interrupt disabled.      */
        spip->spi->SPI_CR   = AT91C_SPI_SPIDIS;     /* SPI disabled.            */
        /* Portable SPI ISR code defined in the high level driver, note, it is
           a macro.*/
        _spi_isr_code(spip);
    }
}
void serve_spi_irq(SPIDriver *spip) {
  uint8_t dummy __attribute__((__unused__));
  if (spip->rx_buf) {
    *spip->rx_buf++ = spip->spi->SPI_RDR;
  } else {
    dummy = spip->spi->SPI_RDR;
  }
  if (--spip->size == 0) {
    spip->spi->SPI_IDR = 0xFFFFFFFF;
    _spi_isr_code(spip);
  } else {
    if (spip->tx_buf)
      spip->spi->SPI_TDR = *(++spip->tx_buf);
    else
      spip->spi->SPI_TDR = 0xFFFF;
  }
}
Beispiel #6
0
/**
 * @brief   Shared end-of-rx service routine.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] flags     pre-shifted content of the ISR register
 */
static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {

  /* DMA errors handling.*/
  #if defined(SAMA_SPI_DMA_ERROR_HOOK)
  if ((flags & (XDMAC_CIS_RBEIS | XDMAC_CIS_ROIS)) != 0) {
    SAMA_SPI_DMA_ERROR_HOOK(spip);
  }
#else
  (void)flags;
#endif

  /* Stop everything.*/
  dmaChannelDisable(spip->dmatx);
  dmaChannelDisable(spip->dmarx);

  /* Portable SPI ISR code defined in the high level driver, note, it is
     a macro.*/
  _spi_isr_code(spip);
}
Beispiel #7
0
/**
 * @brief   Shared end-of-rx service routine.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] flags     pre-shifted content of the ISR register
 */
static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {

  /* DMA errors handling.*/
#if defined(STM32_SPI_DMA_ERROR_HOOK)
  if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
    STM32_SPI_DMA_ERROR_HOOK(spip);
  }
#else
  (void)flags;
#endif

  /* Stop everything.*/
  dmaStreamDisable(spip->dmatx);
  dmaStreamDisable(spip->dmarx);

  /* Portable SPI ISR code defined in the high level driver, note, it is
     a macro.*/
  _spi_isr_code(spip);
}
Beispiel #8
0
/**
 * @brief   Common IRQ handler.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 */
static void spi_serve_interrupt(SPIDriver *spip)
{
  SSI_TypeDef *ssi = spip->ssi;
  uint32_t mis = ssi->MIS;
  uint32_t dmachis = UDMA->CHIS;

  /* SPI error handling.*/
  if ((mis & (TIVA_MIS_RORMIS | TIVA_MIS_RTMIS)) != 0) {
    TIVA_SPI_SSI_ERROR_HOOK(spip);
  }

  if ( (dmachis & ( (1 << spip->dmarxnr) | (1 << spip->dmatxnr) ) ) ==
      ( (1 << spip->dmarxnr) | (1 << spip->dmatxnr) ) ) {
    /* Clear DMA Channel interrupts.*/
    UDMA->CHIS = (1 << spip->dmarxnr) | (1 << spip->dmatxnr);

    /* Portable SPI ISR code defined in the high level driver, note, it is a
       macro.*/
    _spi_isr_code(spip);
  }
}
void serve_spi_dma(uint8_t ch, const void *state)
{
  (void)ch;
  _spi_isr_code((SPIDriver*)state);
}