Changeset 847638a in rtems


Ignore:
Timestamp:
Mar 6, 2019, 11:48:31 AM (7 weeks ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
b82a4b4
Parents:
923a033
git-author:
Sebastian Huber <sebastian.huber@…> (03/06/19 11:48:31)
git-committer:
Sebastian Huber <sebastian.huber@…> (03/06/19 12:07:17)
Message:

bsp/atsam: Fix SPI CS change support

The previous approach contained a severe bug which disabled the SPI
module in some cases leading to a blocked SPI bus.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • bsps/arm/atsam/spi/atsam_spi_bus.c

    r923a033 r847638a  
    5757  spi_bus base;
    5858  rtems_binary_semaphore sem;
    59   bool msg_cs_change;
    6059  const spi_ioc_transfer *msg_current;
    61   const spi_ioc_transfer *msg_next;
    6260  uint32_t msg_todo;
    6361  int msg_error;
     
    6967  size_t trailbuf_rx_buffered_len;
    7068  int transfer_in_progress;
    71   bool chip_select_active;
    7269  bool chip_select_decode;
    7370  uint8_t spi_id;
     
    321318}
    322319
    323 static void atsam_spi_do_transfer(
    324   atsam_spi_bus *bus,
    325   const spi_ioc_transfer *msg
    326 )
    327 {
    328   if (!bus->chip_select_active){
    329     Spi *spi_regs = bus->spi_regs;
    330 
    331     bus->chip_select_active = true;
    332 
    333     if (bus->chip_select_decode) {
    334       spi_regs->SPI_MR = (spi_regs->SPI_MR & ~SPI_MR_PCS_Msk) | SPI_MR_PCS(msg->cs);
    335     } else {
    336       SPI_ChipSelect(spi_regs, 1 << msg->cs);
    337     }
    338     SPI_Enable(spi_regs);
    339   }
    340 
    341   atsam_spi_start_dma_transfer(bus, msg);
    342 }
    343 
    344320static int atsam_check_configure_spi(atsam_spi_bus *bus, const spi_ioc_transfer *msg)
    345321{
     
    375351  bus->transfer_in_progress = 2;
    376352
    377   if (bus->msg_cs_change) {
    378     bus->chip_select_active = false;
    379     SPI_ReleaseCS(bus->spi_regs);
    380     SPI_Disable(bus->spi_regs);
    381   }
    382 
    383353  if (msg_todo > 0) {
    384     const spi_ioc_transfer *msg = bus->msg_next;
     354    const spi_ioc_transfer *msg;
    385355    int error;
    386356
    387     bus->msg_cs_change = msg->cs_change;
    388     bus->msg_next = msg + 1;
    389     bus->msg_current = msg;
    390     bus->msg_todo = msg_todo - 1;
    391 
     357    msg = bus->msg_current;
    392358    error = atsam_check_configure_spi(bus, msg);
    393359    if (error == 0) {
    394       atsam_spi_do_transfer(bus, msg);
     360      atsam_spi_start_dma_transfer(bus, msg);
    395361    } else {
    396362      bus->msg_error = error;
     
    425391    }
    426392
     393    if (msg->cs_change) {
     394      bus->spi_regs->SPI_CR = SPI_CR_LASTXFER;
     395    }
     396
    427397    atsam_spi_copy_back_rx_after_dma_transfer(bus);
     398
     399    bus->msg_current = msg + 1;
     400    --bus->msg_todo;
     401
    428402    atsam_spi_setup_transfer(bus);
    429403  }
     
    438412  atsam_spi_bus *bus = (atsam_spi_bus *)base;
    439413
    440   bus->msg_cs_change = false;
    441   bus->msg_next = &msgs[0];
    442   bus->msg_current = NULL;
     414  bus->msg_current = msgs;
    443415  bus->msg_todo = msg_count;
    444416  bus->msg_error = 0;
Note: See TracChangeset for help on using the changeset viewer.