spi can't read more than 64 bytes

Daniel. danielhilst at gmail.com
Wed Jul 6 12:42:30 EDT 2016


Hi, isn't it possible that your hal_frame_read be called again prior
rf_rx_completion_handler is called, and because of this calling
spi_message_init on a spi_message that is in spi queue yet?

2016-07-06 10:25 GMT-03:00 Moti Cohen <motic.mail at gmail.com>:
> Hi all,
>
>
>
> I'm trying to write a kernel device driver for a Freescale imx6 processor
> based board.
>
> This driver is using spi to communicate with a radio module (using linux
> spi.c).
>
> I managed to wr/rd from the module, however once I'm trying to read more
> than 64 bytes I'm getting coruppted data. here are some details:
>
>
>
>
> The SPI reading process goes as follows:
>
> 1.      Interrupt function is invoked from SPI device via dedicated GPIO
> line.
>
> 2.       The interrupt function performs asynchronous SPI read in the
> following order:
>
> 2.1   radio_trx_end_callback is called, as it is the registered call back
> function.
>
> 2.2   radio_trx_end_callback calls hal_frame_read function which prepares
> spi_message and spi_transfer structures and fill them with relevant data:
> spi_device , data tx, transfer len , complete handler , …
>
> 3.      The read itself  is done by calling to function spi_async
>
> 4.      The completion handler function is called and prints the read
> message, but trying to read more than 64 bytes in one transaction causes the
> read data to be corrupted.
>
> Any idea why am I seeing this behavior ?
>
> Is there (in Linux) any definition for the size to be read via the SPI ?
>
> The relevant variables and functions can be seen below:
>
> Thanks in advance for helping..
>
> __________________________
>
> uint8_t rx_buf[200];
>
> uint8_t reg[200] = {HAL_TRX_CMD_FR, 0xff, 0xff};
>
> struct spi_transfer transfer;
>
> struct spi_message  spi_msg;
>
>
>
> // interrupt function
>
> //-----------------------------------------------------------------------------------------------------------------------
>
> static irq_handler_t radio_trx_end_callback(unsigned int irq, void *dev_id,
> struct pt_regs *regs)
>
> {
>
>     hal_frame_read(irq, dev_id);
>
>     return (irq_handler_t) IRQ_HANDLED;      // Announce that the IRQ has
> been handled correctly
>
> }
>
>
>
> //read function
>
> //-----------------------------------------------------------------------------------------------------------------------
>
> void hal_frame_read(unsigned int irq, void *dev_id)
>
> {
>
>         int status;
>
>         spi_device->irq = irq;
>
>         spi_message_init(&spi_msg);
>
>         spi_msg.spi = spi_device;
>
>         spi_msg.complete = rf_rx_completion_handler;
>
>         spi_msg.context = NULL;
>
>         memset((uint8_t*)&transfer, 0, sizeof(transfer));
>
>
>
>         memset(rx_buf, 0xFF, sizeof(rx_buf));
>
>         memset(reg, 0xFF, sizeof(reg));
>
>         reg[0] = HAL_TRX_CMD_FR;
>
>         transfer.tx_buf = reg;
>
>         transfer.len =64;
>
>         transfer.rx_buf = rx_buf;
>
>         spi_message_add_tail(&transfer, &spi_msg);
>
>
>
>         memset(rx_buf, 0x0, sizeof(rx_buf));
>
>         status = spi_async(spi_device, &spi_msg);
>
>     return;
>
> }
>
>
>
> //read completion handler
>
> //-----------------------------------------------------------------------------------------------------------------------
>
> static void rf_rx_completion_handler(void *arg)
>
> {
>
>         int ii;
>
>
>
> //print the received message
>
> printk("\npure message: rx_buf [1]-2=%02X\n      ", rx_buf [1]-2);
>
>         for (ii=0; ii< rx_buf [1]-2; ii++)
>
>                         printk("%02X ", rx_buf [2+ii]);
>
>
>
>
>
>         printk("\nframe len=%X actual len=%X
> status=%i\n",spi_msg.frame_length, spi_msg.actual_length, spi_msg.status);
>
>
>
>         send_up_rf_event_to_workque(TRX_END_EVENT);
>
> }
>
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>



-- 
"Do or do not. There is no try"
  Yoda Master



More information about the Kernelnewbies mailing list