Jump to content

SPI not working properly


Kishan

Recommended Posts

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?

Link to comment
Share on other sites

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);
    
}
 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Important Information

Terms of Use - Privacy Policy - Guidelines