Jump to content

Debian - GPIO


Nick

Recommended Posts

I'm currently playing with a Banana Pi M1 + and don't seem to be able to get the GPIO to work.

 

I *think* that I have correctly mapped the IO pins that I am using through the schematic and fex file to find the corrisponding GPIO number for debian.

 

When playing around in /sys/class/gpio I am able to export the GPIO pin that I'm looking for and change it's properties, direction, value etc. However these changes don't seem to appear on the physical IO pins.

 

I noticed that some of the pins that I'm using are shared by UART 2, so I have disabled that in the FEX file but still no luck.

 

I have a feeling that this is probably going to be DTB related, however I'm a little confused by the fact that Debian allows me to export them.

Link to comment
Share on other sites

GPIO pin numbering schemes are different in legacy kernel (and fex file) and in mainline kernel: https://linux-sunxi.org/GPIO

 

If you are using mainline kernel, you need to map board expansion pin to SoC port bank and number using schematics (or wiki) (i.e. PH10) and use formula in wiki to calculate correct GPIO pin number for exporting.

Link to comment
Share on other sites

Hi Zador,

Once again you come to my rescue, thank you :-)

I have the GPIO working now, just trying to debug the SPI port. I have a device but no pins toggling at the moment.

 

Just out of interest, is the FEX file used at all by mainline now, or does it just use DTB?

Link to comment
Share on other sites

Brilliant, that's good to know, at least I can just concentrate on checking the settings in mainline without having to worry about the FEX file as well.

 

 

Just out of interest, if I'm using mainline, is the FEX file used at all, for example by UBOOT or the SoC's internal bootloader? In other words, if  were to delete the fex file from the SD card whilst using mainline would it still work?

 

Getting back to the SPI...

I've checked and re-checked my DTB file (including decompiling the file on the device), and SPI appears to be enable, it appears to be using the correct pins as per the schematic and spidev32766.0 appears in /dev

 

My code (which worked with the legacy kernel) is very similar to the code found here: https://linux-sunxi.org/SPIdev there are no apparent erros when the code runs, but nothing is output on any of the physical SPI pins. 

Link to comment
Share on other sites

Just out of interest, if I'm using mainline, is the FEX file used at all, for example by UBOOT or the SoC's internal bootloader? In other words, if  were to delete the fex file from the SD card whilst using mainline would it still work?

FEX file isn't ised in legacy kernel too  :) It's compiled to bin file, which is used by legacy kernel. In any case u-boot uses its own precompiled configuration and DT file, so deleting .bin and .fex file has no effect when using mainline kernel.

Link to comment
Share on other sites

Looking at the signals on a scope, the CLK pin is awful. I've tried increasing the drive strength to 40mA in the DTB file to no avail.

 

The MOSI line looks fine on the scope, but the CLK line looks more like a sinewave that a square wave.

 

If I override the CLK pin using the /sys/class/gpio then the line goes high, so I am confident that there are no electrical shorts on the board.

Link to comment
Share on other sites

Here is my SPI code


#include "system.h"
#include "spi.h"
#include "debug.h"

#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>

static const char *device = "/dev/spidev32766.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 500000;
static uint16_t delay;

static unsigned char rxByte;

int fd;

static void pabort(const char *s)
{
	perror(s);
	abort();
}

void spiInit(void)
{
  unsigned int ret;

  printf("SpiInit()...");
  fd = open(device, O_RDWR);
  if (fd < 0)
    {
      printf("can't open device: %s\r\n", device);
      abort();
    }
  

  //   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;


  /*
   * 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)
    pabort("can't set bits per word");
  
  ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
  if (ret == -1)
    pabort("can't get bits per word");
  
  /*
   * max speed hz
   */
  ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
  if (ret == -1)
    pabort("can't set max speed hz");
  
  ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
  if (ret == -1)
    pabort("can't get max speed hz");
  printf("Done.\r\n"); 
}

void spiTxByte(unsigned char byte)
{
  unsigned int ret;

	struct spi_ioc_transfer tr = {
		.tx_buf = (unsigned long)&byte,
		.rx_buf = (unsigned long)&rxByte,
		.len = 1,
		.delay_usecs = delay,
		.speed_hz = speed,
		.bits_per_word = bits,
	};

	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);

	//	printf("spi: by: %#x, rxB: %#x\r\n",byte, rxByte);
	if (ret < 1)
		pabort("can't send spi message");
}

unsigned char spiRxByte(void)
{
  spiTxByte(0x00);
  return rxByte;
} 
Link to comment
Share on other sites

Looking at the signals on a scope, the CLK pin is awful. I've tried increasing the drive strength to 40mA in the DTB file to no avail.

 

The MOSI line looks fine on the scope, but the CLK line looks more like a sinewave that a square wave.

 

If I override the CLK pin using the /sys/class/gpio then the line goes high, so I am confident that there are no electrical shorts on the board.

I just looked at SPI on cubietruck with mainline kernel. I used spidev_test.c, and for some reason it ignores max speed settings and always goes at 50MHz (probably from DT setting "spi-max-frequency = <50000000>;"). At this speed it's hard to expect square signal on CLK pin.

 

Try lowering max speed in DT at least to 1MHz (maybe I'll try it too later when I have some spare time).

Link to comment
Share on other sites

Ahh that's where spi_test is, I tried looking for it but ended up at a page (I think on kernel.org) that just had a nice explanation of it instead :-(

 

I'll try those changes, thank you. My scope is only 70MHz so I doubt it was able to do much with a 50MHz signal. The chip that I'm trying to talk to certainly wouldn't handle it!

 

Thanks for the tip, I'll let you know how I get on :-)

Link to comment
Share on other sites

60 / 70 MHz would allow you to measure the frequency but probably wouldn't give you much of a square wave as it's too close to the frequency being measured. I wouldn't trust a 70MHz scope to display much more than a 35/40MHz signal as the Nyquist frequency is Fsample / 2.

 

That said, I didn't think to measure / calculate the frequency at all, I just saw the awful wave. Had I thought to measure it I probably would have noticed that it was 50MHz.

 

Just for reference, I've changed the Max frequency in the DTB file to 5MHz and everything is working brilliantly now, thank you very much.

Link to comment
Share on other sites

On my Legacy CB1 system, I'm not seeing the gpiochip0 under /sys/class/gpio. For my case:

root@cubieboard:/sys/class/gpio# uname -a
Linux cubieboard 3.4.112-sun4i #1 PREEMPT Wed Jun 8 11:09:31 EDT 2016 armv7l GNU/Linux
root@cubieboard:/sys/class/gpio# lsb_release -a
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux 8.5 (jessie)
Release:	8.5
Codename:	jessie
root@cubieboard:/sys/class/gpio# ls -la
total 0
drwxr-xr-x  2 root root    0 Dec 31  1969 .
drwxr-xr-x 57 root root    0 Dec 31  1969 ..
--w-------  1 root root 4096 Jun  9 14:17 export
--w-------  1 root root 4096 Dec 31  1969 unexport
root@cubieboard:/sys/class/gpio# 

Is there something that qualifies that?

 

I did the operation

dd if=CB1_U-Boot of=/dev/sdd bs=1k seek=8

to overwrite the built in u-boot with the one that Steve gave me (see http://forum.armbian.com/index.php/topic/1178-cubieboard-1-legacy-boot-failure/?p=10244), as the default u-boot was hanging for CB's although not other hardware. Steve's version boots up.

 

Is there something else required to enable GPIO? Did overwriting the original u-boot disconnect something?

 

Thanks

Chris

Link to comment
Share on other sites

Additional data point: I get this in dmesg:

[    0.133078] sunxi_gpio driver init ver 1.3
[    0.139085] sunxi_gpio_probe can't find script.bin '[gpio_para]' 'gpio_used'
[    0.144097] gpio-sunxi: probe of gpio-sunxi failed with error -4

Can't find script.bin ? where is it looking? It's in the usual place.

 

Chris

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