www.elektronik.si
Uporaba SPI vodila v C-ju (imam težave)

www.elektronik.si -> Raspberry Pi sekcija

Avtor: peterv6iKraj: Izola PrispevekObjavljeno: Pon Jul 17, 2017 3:27 pm    Naslov sporočila:  Uporaba SPI vodila v C-ju (imam težave)
----------------------------------------------------------------------------
Pozdrav,
pred časom sem kupil vmesnik, ki ima 4 UART vhode (na eni strani) na drugi strani je pa SPI vodilo..
Na Arduinu sem zadevo uspešno uporabi sedaj pa bi želel to isto stvar probati še na Orangepi/raspberypi-ju.

Na 40 pinskem konektorju sem povezal signale

3.3V na 3.3V napajanje na vmesniku
GND na na GND vmesnika
MISO <--> MISO
MOSI <--> MOSI
SCK <--> CLK
CS0 <--> CS vmesnika




Namestil sem si knjižnico wiringPi in inštaliral Netbeans IDE..
Ustvaril sem C/C++ projekt.

Težave imam s sintakso in sicer na Arduinu imam te tri metode ali funkcije:

Koda:
void SetBaud(char UART, char BAUD)
{
   if (UART < 4)
   {
      if (BAUD < 10)
      {
         digitalWrite(_ss_pin, LOW);
         SPI.transfer(0x80 | UART);
         delayMicroseconds(50);
         SPI.transfer(BAUD);
         digitalWrite(_ss_pin, HIGH);
      delayMicroseconds(50);
      }
   }
}

char CheckRx(char UART)
{
   char RETVAL = 0;
   if (UART < 4)
   {
      digitalWrite(_ss_pin, LOW);
      SPI.transfer(0x10 | UART);
      delayMicroseconds(250);
      RETVAL = SPI.transfer(0xFF);
      digitalWrite(_ss_pin, HIGH);
      delayMicroseconds(50);
   }
   return (RETVAL);
}


void ReceiveString(char *RETVAL, char UART, char NUMBYTES)
{
   //Local variable definitions
   char IDX = (0x0);
   if (UART < 4)
   {
      digitalWrite(_ss_pin, LOW);
      SPI.transfer(0x20 | UART);
      delayMicroseconds(50);
      SPI.transfer(NUMBYTES);
      delayMicroseconds(50);
      while ((IDX < NUMBYTES))
      {
         RETVAL[IDX] = SPI.transfer(0xFF);
         delayMicroseconds(50);
         IDX = IDX + 1;
      }
      digitalWrite(_ss_pin, HIGH);
      delayMicroseconds(50);
      RETVAL[IDX] = 0;
   }
}


Iz zgornje kode lahko vidim, da je ena funkcija za pisanje preko SPI-ja druga pa za branje...

WiringPI knjižnica ima 1 funkcijo za pisanje in branje?!
int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ;

Kar želim je to, da bi tiste zgornje 3 funkcije predelal tako, da jih lahko uporabljam preko wiringPiSPIDataRW.. Prosim če je kakšen C stručko, da mi pomaga Wink

koda za orangepi/raspberyPi pa je:

Koda:
#include <unistd.h>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <wiringPiSPI.h>

using namespace std;

#define DEBUG 1
#define SPI0 0  // /dev/spidev0.0
#define CS0  10 // Slave1 ChipSelect pin 24 (gpio readall)

/*
 *
 */
void SetBaud(char UART, char BAUD)
{
   
    unsigned char value = 0x80 | UART;
    if (UART < 4)
   {
      if (BAUD < 10)
      {
         digitalWrite(CS0, LOW);
                        value = 0x80 | UART;
                        wiringPiSPIDataRW (SPI0,&value,1);
         usleep(50);
                        value = BAUD;
         wiringPiSPIDataRW (SPI0,&value,1);
         digitalWrite(CS0, HIGH);
         usleep(50);
      }
   }
}

char CheckRx(char UART)
{
   char RETVAL = 0;
        unsigned char data[7];
       
        unsigned char value =  0x10 | UART;
   if (UART < 4)
   {
      digitalWrite(CS0, LOW);
                wiringPiSPIDataRW (SPI0,&value,1);
      usleep(250);
                value = 0xFF;
      wiringPiSPIDataRW (SPI0,&value,1);
                RETVAL = value;
      digitalWrite(CS0, HIGH);
      usleep(50);
   }
   return (RETVAL);
}

void ReceiveString(char *RETVAL, char UART, char NUMBYTES)
{
   //Local variable definitions
    return;
        char IDX = (0x0);
        unsigned char c[1] = {0x20 | UART};
   unsigned char b[1] = {0xFF};
        if (UART < 4)
   {
      digitalWrite(CS0, LOW);
      //SPI.transfer(0x20 | UART);
                wiringPiSPIDataRW (SPI0,c,1);
      usleep(50);
                c[1] = NUMBYTES;
      //wiringPiSPIDataRW (SPI0,c[1],1);
      usleep(50);
      while ((IDX < NUMBYTES))
      {
         
                        wiringPiSPIDataRW (SPI0,b,1);
                        RETVAL[IDX] = b[1];
                        b[1] = 0xFF;
         usleep(50);
         IDX = IDX + 1;
      }

      digitalWrite(CS0, HIGH);
      usleep(50);
      RETVAL[IDX] = 0;
   }
}

int main(int argc, char** argv) {
    char Str1[1000];
    char LENGTH;
    setvbuf(stdout, NULL, _IONBF, 0);
    wiringPiSetup() ;
    printf("SPI TEST\n");
    pinMode(CS0, OUTPUT);
    digitalWrite(CS0, HIGH);

    if (wiringPiSPISetup(SPI0, 1000000) < 0) {
        printf("SPISetup failed:\n");
        return -1;
    }
   
    printf("Set baud rate\n");
    SetBaud(0, 3);
    SetBaud(1, 3);
    SetBaud(2, 3);
    SetBaud(3, 3);
   
    while(true)
    {
        printf(".");
        printf("%c",LENGTH);
        LENGTH = CheckRx(0); //check if datas are available
        if (LENGTH > 0)
        {
            ReceiveString(Str1, 0, LENGTH);
            printf("length %u\n", (unsigned int)LENGTH);
            printf("%c\n", Str1);
        }
        digitalWrite(CS0, LOW);
   
        sleep(1);
    }
   

    return 0;
}


Zanima me če bi mi kdo lahko pomagal, da bi pravilno prevedel prve tri funkcije s pomočjo WiringPi funkcij...

Tukaj je še spletna stran kako je ta vmesnik UART2SPI sestavljen in kakšne so komande (protokol):
http://www.instructables.com/id/SPI-to-4-x-UART-Bridge-MULTIUART/

hvala[img][/img]

Avtor: peterv6iKraj: Izola PrispevekObjavljeno: Sre Avg 02, 2017 2:45 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Sem rešil...

Koda:
#include <iostream>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/times.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <spi_lib.h>



using namespace std;

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

static const char *device = "/dev/spidev0.0";
static uint8_t mode = 0;
static uint8_t bits = 8;
static uint32_t speed = 250000; //250kHz
static uint16_t delays;

static void pabort(const char *s) {
    perror(s);
    abort();
}

void setBaudRate(int fd, char uart) {
    if (uart < 4) {
        int ret = -1;
        uint8_t tx_buffer_baud = (uint8_t) (0x80 | uart); //9600 baud rate UART 1
        ret = spi_write(fd, &tx_buffer_baud, 1);
        printf("ret1: %d\n", ret);
        usleep(150);

        tx_buffer_baud = (uint8_t) 3;

        ret = spi_write(fd, &tx_buffer_baud, 1);
        usleep(150);
        printf("ret1: %d\n", ret);
    }
}

void TransmitString(int fd, char uart, char *DATA, char NUMBYTES) {
    char IDX = (0x0);
    int ret = -1;
    if (uart < 4) {
        uint8_t tx_buffer_baud = (uint8_t) (0x40 | uart); //9600 baud rate UART 1
        ret = spi_write(fd, &tx_buffer_baud, 1);
        usleep(150);

        tx_buffer_baud = (uint8_t) (NUMBYTES);
        ret = spi_write(fd, &tx_buffer_baud, 1);
        usleep(150);
        while (IDX < NUMBYTES) {
            tx_buffer_baud = (uint8_t) DATA[IDX];
            ret = spi_write(fd, &tx_buffer_baud, 1);
            usleep(150);
            IDX = IDX + 1;
        }
        usleep(150);
    }
}

int main(int argc, char** argv) {
    int ret = 0;
    int fd;

    fd = open(device, O_RDWR); //read write
    if (fd < 0) {
        printf("can't open device");
        return -1;
    }
   
    /*
    * spi mode
    */
   ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
   if (ret == -1)
      pabort("can't set spi mode");

   ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
   if (ret == -1)
      pabort("can't get spi mode");

   /*
    * bits per word
    */
   ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
   if (ret == -1)
      printf("can't set bits per word");

   ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
   if (ret == -1)
      printf("can't get bits per word");

   /*
    * max speed hz
    */
   ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
   if (ret == -1)
      printf("can't set max speed hz");

   ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
   if (ret == -1)
      printf("can't get max speed hz");


   
    printf("spi mode: %d\n", mode);
    printf("bits per word: %d\n", bits);
    printf("max speed: %d Hz (%d KHz)\n", speed, speed / 1000);


   

    //set baud rate
    // Initialise the UART baud rates
    // 0=1200, 1=2400, 2=4800, 3=9600, 4=19200, 5=38400, 6=57600, 7=115200
    setBaudRate(fd, 0); //UART 1
   

    TransmitString(fd,0,"PETER",5);
   
    close(fd);
    return ret;

}


Tako mi sedaj deluje tudi serijska komunikacija preko SPI vodila (uporabljam vmesnik SPI na 4 UART)..


Stran 1 od 1

Powered by phpBB © 2001,2002 phpBB Group