www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

Uporaba SPI vodila v C-ju (imam težave)

 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Raspberry Pi sekcija
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
peterv6i
Član
Član



Pridružen-a: Tor 22 Jan 2008 13:30
Prispevkov: 116
Aktiv.: 0.59
Kraj: Izola

PrispevekObjavljeno: Pon Jul 17, 2017 3:27 pm    Naslov sporočila:  Uporaba SPI vodila v C-ju (imam težave) Odgovori s citatom

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]
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
peterv6i
Član
Član



Pridružen-a: Tor 22 Jan 2008 13:30
Prispevkov: 116
Aktiv.: 0.59
Kraj: Izola

PrispevekObjavljeno: Sre Avg 02, 2017 2:45 pm    Naslov sporočila:   Odgovori s citatom

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)..

Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Raspberry Pi sekcija Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Stran 1 od 1

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 48 dni


Powered by phpBB © 2001, 2005 phpBB Group