QtSerialPort with /dev/spidev



  • Did anybody make QSerialPort(Info) work on /dev/spidev* kernel driver?

    I have running (visible, configured, operable via spidev_test.c) /dev/spidev0.0, however QSerialPortInfo::availablePorts returns list with just one member, for /dev/ttyAMA0. I guess I can not (simply) use QSerialPort constructor with "/dev/spidev0.0" parameter before "somehow" getting /dev/spidev0.0 accepted by QSerialPortInfo. Am I wrong? What to do to make /dev/spidev0.0 appear in the list?

    Any clues and advices heartily welcome. (I am able to workaround based on QFile of course, however I would love to do things Qt way ;) .)



  • QSerialPort and QSerialPortInfo were written to work with serial ports aka (UART, RS232, e.t.c), not with SPI interfaces.



  • Thanks for explanation.

    SPI has same basic characteristics like serial port (baud rate, parity...) and even (kind of) asynchronous in/out driven by kernel device so this is why I expected same object could manage them both.

    Now I intend to develop some object for accessing RS-485 UART on RaspComm board (which is itself driven via SPI). Is there something in Qt (ready or WIP) about this (not to re-invent wheel) or is there some design skeleton/advice allowing eventually later extend QtSerialPort by this "device"? (I am willing to contribute, should my development be evaluated as worth it.)



  • AFAIK there isn't any implementation for SPI interface in Qt. So probably you must write your own implementation. As i assumed you use raspberry for your project so you can try bcm2835 library for this.



  • Getting back to document conclusions of my research on best practice of using RaspiComm RS-485 under Qt for anybody, who finds this thread useful (I expect many of it is valid for RS-232 on same board as well, did not test myself):

    1. Do not try to implement communication with MAX3140 UART chip yourself (maybe except of asm based implementation, what is however most probably unnecessary exertion). I succeeded to implement it based on kernel /dev/spidev0.0 only to find out that even this partially system driver supported solution is too slow for even 19 200 Bd speed (loosing about 5 characters on one received).
      I myself feared about RaspiComm RS-485 driver /dev/ttyRPC0 based on some forums complaints and not clear versioning, however found out, that the forum thread was heavy outdated. These official installation instructions worked like a charm and the resulting driver worked out-of-box for my latest Raspbian Wheezy (4.1.7+ #817). So I strongly recommend to take this approach.

    2. QSerialPort class has constructor with signature QSerialPort(const QString &, QObject *), where QString may contain even device which is not included in the QList that QSerialPortInfo::availablePorts() returns. This works with no surprise. If one does not set anything than (eventually) baud speed, one gets standard 8 bit, 1 stop bit, no parity without any character translations, good old plain raw binary. So QSerialPort may be used with /dev/ttyRPC0 directly and easily.

      QSerialPort rpc0("/dev/ttyRPC0");
      rpc0.write("Binary request\0even\xffcontaining weird\x03characters", length_of_binary);
      if(rpc0.waitForReadyRead(100)) // Enough long time in miliseconds
          QByteArray data = rpc0.readAll(); // You may have to wait/read repetitively in loop 
                                            // and merge data on higher link speeds
    
    1. Hardware of RaspiComm uses RTS pin to select in/out direction of data. CTS is kept active permanently by wiring, so using default use RTS/CTS mode works properly with no inappropriate blocking.

    That's all you should need, so enjoy your communication.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.