2008-01-10 18:03:17     DMA read/write on SPORT

Document created by Aaronwu Employee on Aug 7, 2013
Version 1Show Document
  • View in full screen mode

2008-01-10 18:03:17     DMA read/write on SPORT

Jim Lee (UNITED STATES)

Message: 49459    Hi,

 

First the good news; I'm able to tx 32-bit words over primary and secondary channels @ 40 MHz via the sport interface to my FPGA.

 

The FPGA responds to my query command (issued via a sport write) in under 400 nsec.  This means that by the time I finish writing and try to execute a sport read in the next line of my high level code, the FPGA already finished talking.  I'm thinking I need to have a DMA read already set up and waiting for the frame sync from the FPGA before I even execute the sport write.

 

The questions:

 

Q1) The DMA read looks like it blocks  (in ../drivers/char/bfin_sport.c):

 

static ssize_t sport_read(struct file *filp, char __user *buf, size_t count,

                loff_t *f_pos)

{

 

[snip]

 

    dev->regs->rcr1 |= RSPEN;

    __builtin_bfin_ssync();

    //dprintk("\r\nBefore wait event; rcr1 = 0x%04x",dev->regs->rcr1);

 

    wait_event_interruptible(dev->waitq, dev->wait_con);

    dev->wait_con = 0;

 

    dprintk("Complete called in dma rx irq handler\n");

    up(&dev->sem);

 

    return count;

}

 

on the line wait_even_interruptible(dev->waitq, dev->wait_con);

 

I'm confused why a DMA would block execution until it finishes.  I guess I need to understand what wait_event_interruptible is trying to do.  It looks like I have to re-write the driver so that the DMA gets set up and is waiting, then do the sport write as usual, then the DMA read fires an interrupt when it finishes and *then* I call wait_event_interruptible to service the DMA read interrupt?  I'd essentially be making a new entry in the fops table with a function name like "readAndWrite"...?

 

Q2) Would you reccomend using two separate threads (one for write the other for read)  or is that just going to be a bigger can of worms?

 

Thanks in advance,

Jim

QuoteReplyEditDelete

 

 

2008-01-10 19:34:30     Re: DMA read/write on SPORT

Mike Frysinger (UNITED STATES)

Message: 49461    wait_event_interruptible(queue, condition) means "go to sleep on 'queue' until 'condition' evaluates to true"

 

in other words, the code sleeps until the transfer finishes ... this is standard and expected behavior in character devices

 

basically you want a sport driver that supports async/bidirectional transfers ?  the current sport driver supports neither of these things, so you'd probably need need to add support via ioctls for such things ... i'm pretty sure there is no standard framework for doing either of these things, but if you look at the spidev.c file, it should be a good example of doing it via ioctls ...

QuoteReplyEditDelete

 

 

2008-01-11 12:55:33     Re: DMA read/write on SPORT

Jim Lee (UNITED STATES)

Message: 49507    Mike,

 

Yeah, I guess the fundamental assumption that the sport is a char device is not going to cut it in my case.  Thanks for pointing me to the spidev example.

 

Jim

QuoteReplyEditDelete

 

 

2008-10-02 04:48:10     Re: DMA read/write on SPORT

Ruslan Cray (GERMANY)

Message: 63014   

 

 

    int                sport_fd;

    int16            rx_buf[MAX_SIZE];

    int16            tx_buf[MAX_SIZE];

    int                rx_size;

    int                tx_size;

    int                supposed_rx_size;

    int                timeout;

    int                read_thread_is_running;

    int                errors;

    struct event_t  event;

 

int res;

 

 

void main(void)

 

{

 

    timeout        = ACK_TIMEOUT_FROM_FPGA;

    event.flag        = 0;

    supposed_rx_size    = DATASIZE_ACK_IN_BYTES;

    pthread_mutex_init(&event.lock, 0);

    pthread_cond_init(&event.event, 0);

 

 

 

    write_read(tx_buf, tx_size);

 

}

 

 

 

 

 

 

 

 

/*

* sport_read_child

*/

void* sport_read_child(void* arg)

{

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

 

    pthread_testcancel();

 

    read_thread_is_running = 1;

 

    rx_size = read(args->fd, rx_buf, supposed_rx_size);

 

    pthread_testcancel();

    if( supposed_rx_size != rx_size )

        errors |= ERR_SPORT;

    else

        errors &= ~ERR_SPORT;

 

    args->event.flag = 1;

    pthread_cond_signal(&args->event.event);

 

    return 0;

}

 

 

 

 

 

 

 

/*

* write_read

*/

int write_read(int16 *tx_buf, int tx_size)

{

 

    pthread_t            sport_read_thread;

 

    struct timeval        tod;

    struct timespec        tm;

 

 

    if ( pthread_create(&sport_read_thread, NULL, sport_read_child, &args) < 0 )

        return ERR_THREAD_CREATION;

 

    while(1)

    {

        if(read_thread_is_running)

            break;

        my_sleep(a_few);

    }

 

    gettimeofday(&tod, NULL);

 

    tm.tv_sec = tod.tv_sec;

 

    tm.tv_nsec = tod.tv_usec*1000;

 

 

    write(sport_fd, tx_bux, tx_size);

 

    while(!event.flag)

    {

        res = pthread_cond_timedwait(&event.event, &event.lock, &tm);

        if (res == ETIMEDOUT)

        {

            pthread_cancel(sport_read_thread);

            if( pthread_join(sport_read_thread, NULL) != 0 )

                errors |= (ERR_JOIN | ERR_TIMEOUT);

            else

            {

                errors &= ~ERR_JOIN;

                errors |= ERR_TIMEOUT;

            }

            break;

        }

        else    // signal was sended by sport_read_child

        {

            errors &= ~ERR_TIMEOUT;

            if( pthread_join(sport_read_thread, NULL) != 0 )

                errors |= ERR_JOIN;

            else

                errors &= ~ERR_JOIN;

            break;

        }

    }

 

    event.flag = 0;

 

}

 

 

 

 

 

 

 

 

 

P.S.

 

variable read_thread_is_running must use under mutex.

QuoteReplyEditDelete

 

 

2008-10-02 04:55:13     Re: DMA read/write on SPORT

Ruslan Cray (GERMANY)

Message: 63015   

 

And you must correct sport driver.

 

 

bfin_sport.h

bfin_sport.c

Attachments

Outcomes