Announcement

Collapse
No announcement yet.

SPI over UART instead of "soft" serials.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • SPI over UART instead of "soft" serials.

    I've been looking for an option to having extra uarts without adding additional HOSTS, even in the hardware world, the chips are not only more expensive than the HOST microcontroller, but the support of them is of lacking. I decided to try my way at the I2C bus, but even though it worked, I put it aside as the speed was not sufficient. The code I made for arduino uses the hardware serial over the SPI bus using SPI transactions, running @ 200000 baud, you may name your virtual uart anything you want. I've tested it both on uLCD-43PT and uLCD-70DT and seems to be working good, the fact that the checksummed frames are going to and from and processed is promising, but as anything, everything needs improvement regardless, it works, thats the point of it.

    I call it virtUart. It uses the Stream class and passes the data over SPI so you should be able to use any uart device, not just 4d displays.
    Please note that this class is static to one CS in the CPP. Therefore, you can only use ONE external uart. To add additional, you'll need to add parameters to the classes, then each external arduino can be an SPI UART, 3 arduino minis can be 3 uarts that way, again, im not good at coding but this is a step forward

    virtUart.h
    Code:
    /*
    
      virtUart.h - Library with SPI transaction support.
      Created by Antonio Brewer, May 7, 2016.
    
    */
    
    #ifndef virtUart_h
    #define virtUart_h
    
    #include "Arduino.h"
    #include <SPI.h>
    
    class virtUart : public Stream {
     public:
      virtUart();
      virtual size_t write(uint8_t byte);
      virtual int read();
      virtual int peek();
      virtual int available();
      virtual void flush();
    
     private:
    };
    #endif

    virtUart.cpp
    Code:
    /*
    
      virtUart.cpp - Library with SPI transaction support.
      Created by Antonio Brewer, May 7, 2016.
    
    */
    
    #define virtUart_SETTING SPISettings(1000000,MSBFIRST,SPI_MODE0)
    #include "Arduino.h"
    #include <SPI.h>
    #include "virtUart.h"
    
    
    virtUart::virtUart() {
    }
    
    int virtUart::peek() { }
    void virtUart::flush() { }
    
    size_t virtUart::write(uint8_t b) {
        SPI.beginTransaction(virtUart_SETTING);
        digitalWrite(53, LOW);
        SPI.transfer('1');
        delayMicroseconds(20);
        SPI.transfer((byte)b);
        delayMicroseconds(20);
        digitalWrite(53, HIGH);
        SPI.endTransaction();
    }
    
    
    int virtUart::read() {
        SPI.beginTransaction(virtUart_SETTING);
        digitalWrite(53, LOW);
        SPI.transfer('2');
        delayMicroseconds(20);
        SPI.transfer(0x00);
        delayMicroseconds(20);
        byte y = SPI.transfer(0x00);
        digitalWrite(53, HIGH);
        SPI.endTransaction();
        return y;
    }
    
    
    int virtUart::available() {
        SPI.beginTransaction(virtUart_SETTING);
        digitalWrite(53, LOW);
        byte t = SPI.transfer('A');
        delayMicroseconds(20);
        SPI.transfer(0x00);
        delayMicroseconds(20);
        digitalWrite(53, HIGH);
        SPI.endTransaction();
        return t;
    }

    SPI Slave Arduino
    Code:
    #include <SPI.h>
    volatile byte command = 0; // SPI COMMAND, DO NOT TOUCH!
    const int reset_Pin = 23; // RESET PIN OF UART DEVICE
    const int reset_Delay = 100; // MS DELAY OF RESET PIN
    
    
    
    void setup (void) {
      /////////////////////////////////////////////////////////////////
      Serial1.begin (200000); // SET YOUR PORT & BAUD HERE
      /////////////////////////////////////////////////////////////////
      pinMode(reset_Pin, OUTPUT);
      digitalWrite(reset_Pin, 0);
      delay(reset_Delay);
      digitalWrite(reset_Pin, 1);
      SPCR |= bit (SPE);
      pinMode(MISO, OUTPUT);
      SPI.attachInterrupt();
    }
    ISR (SPI_STC_vect) {
      byte c = SPDR;
      switch (command) {
        case 0:
          command = c;
          break;
        case 'A': { //UART AVAILABILITY
            SPDR = Serial1.available();
            command = 0;
            break;
          }
        case '1': { //UART WRITE
            Serial1.write(c);
            command = 0;
            break;
          }
        case '2': { //UART READ
            byte r = Serial1.read();
            if (r != 255) SPDR = r;
            command = 0;
            break;
          }
      }
    }
    
    void loop() { }


    Sample Master SPI Arduino
    Code:
    #include <SPI.h>
    #include <genieArduino.h>
    #include <virtUart.h>
    virtUart myUART;
    Genie genie;
    
    void setup() {
      digitalWrite(SS, HIGH);
      SPI.begin();
      Serial.begin(115200);
      delay(6000);
      genie.Begin(myUART);
      genie.AttachEventHandler(myGenieEventHandler);
      genie.WriteContrast(2);
    
    }
    
    int x = 4;
    uint32_t timer = millis();
    void loop() {
      genie.DoEvents();
    
      if (timer > millis()) timer = millis();
      if (millis() - timer > 100) {
        timer = millis();
        x++;
        if ( x > 99) x = 0;
        genie.WriteObject(GENIE_OBJ_LED_DIGITS, 8 , x);
      }
    
    
    }
    
    
    void myGenieEventHandler(void) {
      genieFrame Event;
      genie.DequeueEvent(&Event);
      Serial.println(Event.reportObject.object);
      Serial.println(Event.reportObject.index);
    }

  • #2
    https://www.youtube.com/watch?v=fYoYNnklPAA

    MASTER on bottom, with 4DVISI GENIE library, SPI connected to top SLAVE, with actual LCD hookup.

    (LIBRARY & MASTER) < -- > (LCD & SLAVE)

    Sorry did topic wrong, it's UART over SPI..
    Last edited by tonton81; 8 May 2016, 04:57 AM.

    Comment

    Working...
    X