spi_async data wrong in linux!!

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

spi_async data wrong in linux!!

1,353 Views
yongleili717
Contributor I


Hello, our IMX6ul SPI interface for data reading, ADC is TI's ADC124S051. When using spi_sync, the data can be read correctly. When using spi_async to read data, some error data will be collected. Below is my driver core code:


static int adc124s_adc_conversion(struct spi_device *spi, int count)
{
    int i,ret;
    u8 tx_buffer[1600];
    struct spi_transfer spi_trans_low = {
        .rx_buf = mmap_buffer,
        .tx_buf = tx_buffer,
        .len = 1496,
        //.cs_change = 0,
        .speed_hz = 5000000,
        .bits_per_word = BITS_PER_WORD,
    };
    struct spi_transfer spi_trans_high = {
        .rx_buf = mmap_buffer + 1496,
        .tx_buf = tx_buffer,
        .len = 1496,
        //.cs_change = 0,
        .speed_hz = 5000000,
        .bits_per_word = BITS_PER_WORD,
    };
    struct spi_message message_low;
    struct spi_message message_high;
    ret = 0;    
    for(i=0;i<1600;i++)
    {
        tx_buffer[i] = 0;
    }
    
    /* Do the transfer */
    
    switch(count)
    {
        case 1:
            date = 1;
            spi_message_init(&message_low);
            message_low.complete = adc_complete;
            message_low.context = NULL;
            spi_message_add_tail(&spi_trans_low, &message_low);
            ret=spi_async(spi, &message_low);
        break;
        case 2:
            date = 2;
            spi_message_init(&message_high);
            message_high.complete = adc_complete;
            message_high.context = NULL;
            spi_message_add_tail(&spi_trans_high, &message_high);
            ret=spi_async(spi, &message_high);
        break;
        default:
            printk("input count is err\n");
        break;
    }   

    return ret;
}
    
static void adc_complete(void *context)
{
    int ret,i;
    switch(date)
    {
        case 1:
            //可读时第三个参数设置为POLL_IN,可写时第三个参数设置为POLL_OUT
            //在这里将其仅仅作为一个参数值,POLL_IN=1;POLL_OUT=2
            for(i=0;i<748;i++)
            {
                printk("this is mmap_buffer[%d] : %d\n",i*2,mmap_buffer[i*2]);
            }
            kill_fasync(&button_async, SIGIO, POLL_IN);
            msleep(3000);
            ret=adc124s_adc_conversion(g_spi,2);
            break;
        case 2:
            for(i=748;i<1496;i++)
            {
                printk("this is mmap_buffer[%d] : %d\n",i*2,mmap_buffer[i*2]);
            }
            kill_fasync(&button_async, SIGIO, POLL_OUT);
            msleep(3000);
            ret=adc124s_adc_conversion(g_spi,1);
            break;
        default: printk("this is faile\n");
            break;
    }
}

static ssize_t adc124s_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
    int ret = 0;
    
    ret=adc124s_adc_conversion(g_spi,1);/* count每次读取的数据量 */
    
    return ret;
}
Labels (2)
0 Kudos
3 Replies

1,191 Views
igorpadykov
NXP Employee
NXP Employee

Hi 永磊 李

what bsp used in the case, one can try with latest nxp

linux-imx - i.MX Linux kernel 

also if sdma is used in the case one can try to disable sdma.

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,191 Views
yongleili717
Contributor I

Linux 4.1.15,

0 Kudos

1,191 Views
igorpadykov
NXP Employee
NXP Employee

please try with latest nxp

linux-imx - i.MX Linux kernel 

 

Best regards
igor

0 Kudos