Jump to content

Recommended Posts

Posted

Hello Genius ,

I am using Orange Pi Zero with (Armbian_5.38) to communicate with my ADC(AD7124-4) while by activating all channels(0 to 7=total 8) SPI able to display only odd channels(1,3,7) not all(evens and odds = total 8=>1,2,3,....7).when same code I run in raspberry pi without any changes it is working fine and displaying all channels(evens and odds=0 to 7=>total 8).   I also tried old OS version with Armbian_5.35,Armbian_5.30 but still facing problem.

Does anyone know proper solution for it?

Posted

It's hard to diagnose without seeing your code. The default max SPI speed is 33Mhz, so that shouldn't be a limiting factor. Which model Raspberry Pi? 

Posted

Dear Larry Bank,

thanks for reply. I am getting OK with same code (given below) using raspberry pi 3 but not with ORANGE PI ZERO and that is what upsetting me.

My code is below:

---------------------------------------------------------------------------------------------------------------------


/*
    spidevlib.c - A user-space program to comunicate using spidev.
                Gustavo Zamboni
*/
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <string.h>
 
char buf[10];
char buf2[10];
 
struct spi_ioc_transfer xfer[2];
 

int spi_init(char filename[40])
    {
        int file;
    __u8    mode=0, lsb, bits;
    __u32 speed=1000000;
 
        if ((file = open(filename,O_RDWR)) < 0)
        {
            printf("Failed to open the bus.");
            /* ERROR HANDLING; you can check errno to see what went wrong */
        //com_serial=0;
            exit(1);
            }
 
        ///////////////
        // Verifications
        ///////////////
        //possible modes: mode |= SPI_LOOP; mode |= SPI_CPHA; mode |= SPI_CPOL; mode |= SPI_LSB_FIRST; mode |= SPI_CS_HIGH; mode |= SPI_3WIRE; mode |= SPI_NO_CS; mode |= SPI_READY;
        //multiple possibilities using |
           mode = SPI_MODE_3;
           //mode |= SPI_NO_CS;
            //mode |= SPI_LSB_FIRST;
        
            if (ioctl(file, SPI_IOC_WR_MODE, &mode)<0)   {
                perror("can't set spi mode");
                // return;
                }
        
 
            if (ioctl(file, SPI_IOC_RD_MODE, &mode) < 0)
                {
                perror("SPI rd_mode");
                // return;
                }
            if (ioctl(file, SPI_IOC_RD_LSB_FIRST, &lsb) < 0)
                {
                perror("SPI rd_lsb_fist");
                // return;
                }
        //sunxi supports only 8 bits
        
            if (ioctl(file, SPI_IOC_WR_BITS_PER_WORD, 8 ) <0)   
                {
                perror("can't set bits per word");
                // return;
                }
        
            if (ioctl(file, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) 
                {
                perror("SPI bits_per_word");
                // return;
                }
        
            if (ioctl(file, SPI_IOC_WR_MAX_SPEED_HZ, &speed)<0)  
                {
                perror("can't set max speed hz");
               // return;
                }
        
            if (ioctl(file, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) 
                {
                perror("SPI max_speed_hz");
                // return;
                }
     
 
    printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",filename, mode, bits, lsb ? "(lsb first) " : "", speed);
 
    xfer[0].tx_buf = (unsigned long)buf;
    xfer[0].len = 3; /* Length of  command to write*/
    xfer[0].cs_change = 0; /* Keep CS activated */
    xfer[0].delay_usecs = 0, //delay in us
    xfer[0].speed_hz = 2500000, //speed
    xfer[0].bits_per_word = 8, // bites per word 8
 
    xfer[1].rx_buf = (unsigned long) buf2;
    xfer[1].len = 4; /* Length of Data to read */
    xfer[1].cs_change = 0; /* Keep CS activated */
    // xfer[0].delay_usecs = 0;
    // xfer[0].speed_hz = 2500000;
    // xfer[0].bits_per_word = 8;
 
    return file;
    }
 
char * spi_read_status(int add1,int nbytes,int file)
    {
    int status;
   // mode2("/dev/spidev1.0"); 
    // memset(buf, 0, sizeof buf);
    // memset(buf2, 0, sizeof buf2);
    buf[0] = add1;
    // buf[1] = add1;
    // buf[2] = add2;
    xfer[0].tx_buf = (unsigned long)buf;
    xfer[0].len = 1; /* Length of  command to write*/
    xfer[1].rx_buf = (unsigned long) buf2;
    xfer[1].len = nbytes; /* Length of Data to read */
    status = ioctl(file, SPI_IOC_MESSAGE(2), xfer);
    if (status < 0)
        {
        perror("SPI_IOC_MESSAGE");
        // return;
        }
   
    printf("status: %02x \n", buf2[0]);

    // adc = (buf2[0] << 16) | (buf2[1] << 8) | buf2[2];
    // volt = adc / 8388607 - 1;
    // volt = volt * 2.5 / 1;

    //  printf("Volt: %lf\n", volt);
 
    // com_serial=1;
    // failcount=0;
    // return buf2;

  //    for (int ret = 0; ret < 4; ret++) {
        // if (!(ret % 6))
        //     puts("");
        // printf("%.2X ", buf2[ret]);
  //   }
}
 

char * spi_read(int add1,int nbytes,int file)
    {
    int status;
    double adc,volt;
     //mode0("/dev/spidev1.0");
    memset(buf, 0, sizeof buf);
    memset(buf2, 0, sizeof buf2);
    buf[0] = add1;
    // buf[1] = add1;
    // buf[2] = add2;
    xfer[0].tx_buf = (unsigned long)buf;
    xfer[0].len = 1; /* Length of  command to write*/
    xfer[1].rx_buf = (unsigned long) buf2;
    xfer[1].len = nbytes; /* Length of Data to read */
    status = ioctl(file, SPI_IOC_MESSAGE(2), xfer);
    if (status < 0)
        {
        perror("SPI_IOC_MESSAGE");
        // return;
        }
    printf("env: %02x \n", buf[0]);
    printf("Data: %02x %02x %02x %02x\n", buf2[0], buf2[1], buf2[2], buf2[3]);

    adc = (buf2[0] << 16) | (buf2[1] << 8) | buf2[2];
    volt = adc / 8388607 - 1;
    volt = volt * 2.5 / 1;

    //printf("Volt: %lf   %02x  %02x\n", volt, buf2[3],buf2[4]);
 
    // com_serial=1;
    // failcount=0;
    // return buf2;

  //    for (int ret = 0; ret < 4; ret++) {
        // if (!(ret % 6))
        //     puts("");
        // printf("%.2X ", buf2[ret]);
  //   }
}


void spi_write(int add,int d1,int d2,int d3,int nbytes,int file)
    {
    unsigned char   buf[32];
    int status;
   // mode0("/dev/spidev1.0");
 
    buf[0] = add;
    buf[1] = d1;
    buf[2] = d2;
    buf[3] = d3;

    xfer[0].tx_buf = (unsigned long)buf;
    xfer[0].len = nbytes+1; /* Length of  command to write*/
    status = ioctl(file, SPI_IOC_MESSAGE(1), xfer);
    
    if (status < 0)
        {
        perror("SPI_IOC_MESSAGE");
        }
    printf("write: %02x %02x %02x\n", buf[0], buf[1], buf[2]);
    //printf("ret: %02x %02x %02x %02x\n", buf2[0], buf2[1], buf2[2], buf2[3]);
     }

void main()
{
    /* code */
    char *buffer;
    char buf[10];
    int file;
     
    file=spi_init("/dev/spidev1.0"); //dev
     
    spi_write(0x09,0x80,0x13,0x00,2,file); usleep(10000);
    spi_write(0x0a,0x80,0x33,0x00,2,file); usleep(10000);
    spi_write(0x0b,0x80,0x53,0x00,2,file); usleep(10000);
    spi_write(0x0c,0x80,0x73,0x00,2,file); usleep(10000);
    spi_write(0x0d,0x80,0x93,0x00,2,file); usleep(10000);
    spi_write(0x0e,0x80,0xa3,0x00,2,file); usleep(10000);
    spi_write(0x0f,0x80,0xc3,0x00,2,file); usleep(10000);

   // spi_write(0x07,0x00,0x00,0x44,3,file); usleep(10000);

    spi_write(0x01,0x04,0x00,0x00,2,file); usleep(10000);


    while(1)
    {
        // spi_read_status(0x42,1,file);
        // usleep(125000);
        spi_read(0x42,4,file);
        usleep(125000);
    }
    
     
    close(file);
    
}
 

Posted

Looks like there are a bunch of potential problems with that code. I see some commented out lines which hardcode the SPI bus number as 1. On the Orange Pi Zero (and most H2/H3 boards), the header exposes SPI bus 0. Other issues are in the spi_read() function, it looks like it's trying to do an asymmetrical number of bytes of writing versus reading. That will potentially cause odd behavior in the driver since SPI reads/writes simultaneously the same number of bytes. In other words, if you shift out 1 byte, you only read back 1 byte. Why not start from a simpler set of code (e.g. my ArmbianIO project)?

Posted

thanks larry bank,I tried all changes that you suggested but still same.and more surprise is same code working fine in raspberry  but not in orangepi.

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines