Hi Daniel,

It doesn't look like it..

The interrupt is invoked (via GPIO pin) only once and it's after the entire
packet is completely received.


On Wed, Jul 6, 2016 at 7:42 PM, Daniel. <[email protected]> wrote:

> 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 <[email protected]>:
> > 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
> > [email protected]
> > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
> >
>
>
>
> --
> "Do or do not. There is no try"
>   Yoda Master
>
_______________________________________________
Kernelnewbies mailing list
[email protected]
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

Reply via email to