Kishan Posted March 14, 2018 Share Posted March 14, 2018 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 More sharing options...
Larry Bank Posted March 14, 2018 Share Posted March 14, 2018 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? Link to comment Share on other sites More sharing options...
Kishan Posted March 15, 2018 Author Share Posted March 15, 2018 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 More sharing options...
Larry Bank Posted March 15, 2018 Share Posted March 15, 2018 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 More sharing options...
Kishan Posted March 16, 2018 Author Share Posted March 16, 2018 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. Link to comment Share on other sites More sharing options...
Recommended Posts