0

Question refactored:

Im currently struggling to understand how to update the transmit FIFO of the bsc_xfer.

For reference:

Slave side:


int main(int argc, char** argv)
{
int GPIO = gpioInitialise();

if(GPIO)
{

    bsc_xfer_t xfer;
  
    xfer.control = (0x09<<16) | 0x305; 
    int status = bscXfer(&xfer);
    std::cout<<"\nstatus: "<<status<<std::endl;
    
    if(status >= 0)
    {
        while(1)
        {
            status = bscXfer(&xfer);
            if (status)
            {
                if(xfer.rxCnt > 0)
                {
                    
                    printf("\nRxCnt: %d RxVal: %x\n", xfer.rxCnt, xfer.rxBuf[0]);
                    switch(xfer.rxBuf[0])
                    {
                        case 0x00:
                        memcpy(xfer.txBuf, "ABCD", 4);
                        xfer.txCnt = 4;
                        break;
                        
                        case 0x01:
                        memcpy(xfer.txBuf, "FGHI", 4);
                        xfer.txCnt = 4;
                        break;
                        
                        default:
                        break;
                    }
                    memset( xfer.rxBuf, '\0', BSC_FIFO_SIZE );
                    
                }
            }
        }
    }
    
}
}

Master side:


int main(int argc, char** argv)
{
int GPIO = gpioInitialise();

if(GPIO)
{
    int handler = i2cOpen(1, 9, 0);
    
    std::cout<<"\nHandler: "<<handler<<std::endl;
    
    if(handler >= 0)
    {
        int wr = i2cWriteByte(handler, 0x00);
        
        std::cout<<"\nwr: "<<wr<<std::endl;
        
        if(wr >= 0)
        {
            char buf[5] = "1111";
           
            int test = i2cReadDevice(handler, buf, 4);
            
            std::cout<<"\ntest: "<<test<<std::endl;
            
            if(test >= 0)
            {
                std::cout<<"\nReceived: " << buf;
            }
            
            std::cout<<std::endl;
            
            wr = i2cWriteByte(handler, 0x01);
        
            std::cout<<"\nwr(2): "<<wr<<std::endl;
        
            if(wr >= 0)
            {
                test = i2cReadDevice(handler, buf, 4);
            
                std::cout<<"\ntest(2): "<<test<<std::endl;
            
                if(test >= 0)
                {
                    std::cout<<"\nReceived: "<<buf;
                }
            
                std::cout<<std::endl;
            }
        }
    }
}
else
{
    std::cout<<"\nGPIO init error"<<std::endl;
}
return 0;

}

expected output:

Received: ABCD

Received: FGHI

actual output:

Received: ABCD

Received: AFGH

Question: I'm missing how to reset the Tx fifo correctly, is there a proper way or am I touching something not covered by the lib?

0

I haven't looked at your code.

I would suggest you use pigs from the command line (if possible). That would give you a feel for what will/should happen.

Remember you need to fill the TX buffer before the other side requests the data. There is no way Linux/pigpio will be fast enough to construct the message on the fly. So the remote side should ask for the data in one transaction and read it in another a few milliseconds later.

  • I think I got it working; some points, I indeed ask the data by writing a byte then giving some ms before reading (even 0.1 ms works), I let it run for an hour and simple logs shows no error. 2nd points: this code misses all gpioTerminate / closing due to extraction from real file; 3rd point, I've been reading the sources and realized that I totaly missunderstood what txCnt meant, its not dynamically decreased, (i.e. become 0 once all bytes are sent) – Ebya May 7 '18 at 15:44
  • @Ebya It is very hard to clearly document code. Any documentation updates are welcome! – joan May 7 '18 at 18:44
  • one strange point: it seems that the 0.1ms between write & read on master->slave is only ok on Pi-zero, Rpi3 needs 1ms (nothing else running on it); Second point: is there a way to clean TX fifo without setting the BK bit in control to 1 ? – Ebya May 8 '18 at 1:00
  • @Ebya You wrote: "I think I got it working...". Please create an answer and accept it after two days. Only accepting an answer will finish the question and it will not pop up again and again for years. – Ingo Jun 1 '20 at 16:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.