Spi Chip Select Problem

Hello,

I have recently purchased a Vim 3 Pro and I am having problems when configuring SPI. According to the documentation (VIM3/3L SPI [Khadas Docs]), I have modified /boot/env.txt file, but chip select is not working. MOSI and clock signals work fine. I do not know if it is a board configuration problem or a code problem.

Edit: I am using mode 3 (CPOL = 1 and CPHA = 1)

#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <fcntl.h>
#include <time.h>
#include <sys/ioctl.h>
#include <linux/ioctl.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

int ade9430_fd;

void ade9430_write_16bit(int fd, uint16_t address, uint16_t value){
    int ret;

	uint8_t data_tx[4] = {(address >> 4), 
						(address & 0x0F) << 4,
						(value & 0xFF00) >> 8,
						(value & 0x00FF)};

    struct spi_ioc_transfer tr = {
        .tx_buf = (unsigned long)data_tx,
        //.rx_buf = (unsigned long)data_rx,
        .len = WRITE16_BYTES, // 4 bytes
        .delay_usecs = 0,
        .speed_hz = speed, // 15.0 MHz
       // .cs_change = 0,
        .bits_per_word = bits,	// 8
    };

    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    if (ret < 1){
        printf("can't send spi message\n");
	}
}

int ade9430_check_comms(int fd){

    if (fd < 0){
		perror("Error Opening SPI Bus\n");
		return -1;
	}

	/* Setup of the SPI Bus */
	if(ioctl(fd, SPI_IOC_WR_MODE, &mode) < 0){
		perror("Error setting SPI mode\n");
		close(fd);
		return -1;
	}

	if(ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0){
		perror("Error setting SPI speed\n");
		close(fd);
		return -1;
	}

	if(ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0){
		perror("Error setting SPI mode\n");
		close(fd);
		return -1;
	}

    return 0;
}

int main(int argc, char *argv[]){

  int num = 0;

  /* Stablish & configure ADE9430 SPI communications */
  printf("Preparing SPI BUS\n");

	/* Open the SPI bus file descriptor */
	ade9430_fd = -1;
        ade9430_fd = open("/dev/spidev1.1", O_RDWR);
	if (ade9430_fd  < 0){
		perror("Error Opening SPI Bus.\n");
		return -1;
	}

	if (ade9430_check_comms(ade9430_fd) != 0){
		printf("SPI configuration failure.\n");
		return -1;
	}

    /* Loop */
    while(1){
        system("sleep 0.25");
        ade9430_write_16bit(ade9430_fd, 0x483, 0xDC75);
        printf("SPI TX number %d\n", num);
        num++;
    }
    return 0;
}

Have you also removed uart3 node? The CS pin is used for uart3 by default, if you want to use it please remove it from the overlay node.

Hello numbqq,

Yes. I did it before asking (overlay=spi1).
I have checked the GPIOs status and it is configured as input.

| GPIO | wPi | Name | Mode | V | DS | PU/PD | Physical |
| 433 | 2 | PIN.H6 | IN | 0 | | P/D | 15 |

Do I have to configure the GPIO as it says here? GPIO Header [Khadas Docs]

Hello @inigoatm

Do you attach multi devices on the SPI bus ? If only one device then the CS pin is no need.

The board just needs to connect to an Analog Devices ADE9430 (ADC), that needs the chip select signal. I developed a library for STM32 microcontrollers and it does not work if there is no chip select. The ADE9430 needs this signal in order to know when the transmission starts (high to low transition) and finishes (low to high transition). When the microcontroller/microprocessor sends a read data order, the ADE9430 sends data until CS GPIO level is high.

image

Okay, you can control the CS pin level via GPIO library. Check here: GPIO Header [Khadas Docs]

1 Like

Ok. Thanks for your help.