Raspberry Pi: SPI not working, spi_bcm2835 not showing with lsmod

Viewed 2900

I'm trying to control my WS2801 LED Stripe with my Raspberry Pi 4 over the SPI interface.

The Pi is running un Ubuntu 20.04 with the kernel version: Linux ubuntu 5.3.0-1030-raspi2 #32-Ubuntu SMP Sun Jul 12 21:20:28 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux

The setup and connection to the LED Strip should be fine. I've validated it with a test script on my Pi3 and it worked properly. With the test script running on the PI there is no error, but nothing happens on the LED stripe.

So far, I have the understanding that in order to communicate over the SPI we need the spidev and the spi-bcm2835 module to be loaded. Output of lsmod | grep spi:

spidev                 28672  0

IMO, there should be spi_bcm2835 as well. In the /dev/ folder there is spidev0.0 and spidev0.1, as it should be. Calling sudo modprobe spi_bcm2835 gives no error but does not solve the issue.

My /boot/firmware/config.txt:

[pi4]
kernel=uboot_rpi_4.bin
max_framebuffers=2

[pi3]
kernel=uboot_rpi_3.bin

[all]
arm_64bit=1
device_tree_address=0x03000000
start_x=1
gpu_mem=512
dtparam=spi=on
dtparam=sound=on
dtparam=i2c_arm=on
dtparam=i2s=on
dtoverlay=spi-bcm2835

My /etc/modules:

i2c-dev
spi-bcm2835
spi-dev
snd-bcm2835

There is no blacklist entry with respect to the spi inside the /etc/modeprob.d/ files.

The only related entry in dmesg is [ 1.559971] spi-bcm2835 fe204000.spi: could not get clk: -517. But as far as I know -517 means that the module is just loaded later because it's not ready at this timestep.

Does anybody know what the issue might be here? Thanks!

This is my test_script:

/******************************************************************************/
/*                                                                            */
/*                                                         FILE: ledstrip.cpp */
/*                                                                            */
/*    Displays the contents of a file on a LED strip                          */
/*    ==============================================                          */
/*                                                                            */
/*    V0.01  18-DEC-2015   Te                                                 */
/*                                                                            */
/******************************************************************************/

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>

static const char             *device = "/dev/spidev0.0" ;
static uint32_t                speed  = 500000 ;
static uint8_t                 mode   = SPI_MODE_0 ;
static uint8_t                 bits   = 8 ;

static unsigned char           tx[75] ;
static unsigned char           rx[75] ;

static struct spi_ioc_transfer parameters[1];

static int                     offset = 0 ;
static int                     spi ;

/*************/
 int OpenSPI()
/*************/

{
   spi = open( device, O_RDWR ) ;
   if( spi < 0 )
   {
      fprintf( stderr, "can't open device\n" ) ;
      return 1 ;
   }

   int ret = ioctl( spi, SPI_IOC_WR_MODE, &mode ) ;
   if( ret == -1 )
   {
      close( spi ) ;
      fprintf( stderr, "can't set mode\n" ) ;
      return 2 ;
   }

   ret = ioctl( spi, SPI_IOC_WR_BITS_PER_WORD, &bits ) ;
   if( ret == -1 )
   {
      close( spi ) ;
      fprintf( stderr, "can't set bits\n" ) ;
      return 3 ;
   }

   ret = ioctl( spi, SPI_IOC_WR_MAX_SPEED_HZ, &speed ) ;
   if( ret == -1 )
   {
      close( spi ) ;
      fprintf( stderr, "can't set speed\n" ) ;
      return 4 ;
   }

   memset( &parameters, 0, sizeof(spi) ) ;
 
   parameters[0].tx_buf        = (unsigned long)tx ;
   parameters[0].rx_buf        = (unsigned long)rx ;
   parameters[0].len           = 75 ;
   parameters[0].delay_usecs   = 0 ; 
   parameters[0].speed_hz      = speed ;
   parameters[0].bits_per_word = bits ;
   parameters[0].cs_change     = 0 ;

   return 0 ;
}

/***************/
 void CloseSPI()
/***************/

{
   close( spi ) ;
}

/*****************/
 void ResetState()
/*****************/

{
   memset( tx, 0, sizeof(tx) ) ;
}


/****************/
 void ShowState()
/****************/

{
   if( ioctl(spi,SPI_IOC_MESSAGE(1),&parameters) == -1 )
      fprintf( stderr, "can't transfer data\n" ) ;
}

/*******************************/
 void Token( const char *token )
/*******************************/

{
   if( isdigit(*token) )
   {
      int value = atoi( token ) - 1 ;

      if( (value >= 0) && (value <= 24) )
         tx[value*3+offset] = 255 ;
   }
   else
   {
      switch( tolower(*token) )
      {
         case 'r' : offset = 0 ;
                    break ; 
         case 'g' : offset = 1 ;
                    break ; 
         case 'b' : offset = 2 ;
                    break ; 
      }
   }
}

/***************************/
 void Line( const char *ps )
/***************************/

{
   ResetState() ;

   char    token[25] ;
   size_t  i = 0 ;

   while( *ps != '\0' )
   {
      if( isspace(*ps) )
      {
         if( i > 0 )
         {
            token[i] = '\0' ;
            Token( token ) ;
         }

         i = 0 ;
      }
      else
      {
         if( i < sizeof(token) - 1 )
            token[i++] = *ps ;
      }
            
      ++ps ;
   }

   ShowState() ;
}


/***************************/
 void ReadFile( FILE *file )
/***************************/

{
   char            line[1024] ;
   struct timespec in ;
   struct timespec out ;
 

   while( fgets(line,sizeof(line),file) != NULL )
   {
      Line( line ) ;

      in.tv_sec  = 0 ;
      in.tv_nsec = 125000000 ;
      nanosleep( &in, &out ) ;
   }
}

/*********************************/
 void File( const char *filename )
/*********************************/

{
   FILE *file = fopen( filename, "r" ) ;

   if( file != NULL )
   {
      ReadFile( file ) ;
      fclose( file ) ;
   }
}

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

{
   if( OpenSPI() != 0 )
      return 1 ;

   if( argc == 1 )
      ReadFile( stdin ) ;
   else
   {
      for( int i = 1; i < argc; i++ )
         File( argv[i] ) ;
   }

   CloseSPI() ;

   return 0 ;
}
1 Answers

I had a similar problem. This answer has helped me.

Change usercfg.txt instead of config.txt.

Related