This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SPI BeagleBone Black (ARM3358) using mmap

Other Parts Discussed in Thread: SYSCONFIG, AM3358

Hi.

I am trying to configure SPI0 module through mmap.

I know that there is a library designed specifically for SPI module. The reason to use mmap is that I need to configure some aspects of this module for my project that can not be configured using IOCTL library.

To be more concise, I need to keep the clock running constantly, in order to have a system clock for the slave. I don´t know even it is possible, but I have been reading ARM335x Technical Reference Manual, and it seem that  modifying SYSCONFIG module, it will be possible.

Here is the code that I am using:

HEADER FILE

#ifndef _SPI_register_H_
#define _SPI_register_H_


// mmap McSPI0 Registers. Base Address

	#define MCSPI0_START_ADDR 0x48030000
	#define MCSPI0_END_ADDR 0x48031FFF
	#define MCSPI0_SIZE (MCSPI0_END_ADDR - MCSPI0_START_ADDR)

// Offsets

	#define MCSPI0_SYSCONFIG 0x110
	#define MCSPI0_MODULCTRL 0x128
	#define MCSPI0_CH0CONF 0x12C
	#define MCSPI0_CDAFRX 0x1A0


#endif

SOURCE FILE

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h> 
#include "SPI_register.h"
#include <stdint.h>
#include <unistd.h>
#include <getopt.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

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

    volatile void *spi0_addr = NULL;	 
    volatile unsigned int *spi0_sysconf_addr = NULL;																									
    static const char *device = "/dev/spidev1.0";
    unsigned int reg;

	
    int fd = open("/dev/mem", O_RDWR);
    printf("Mapping %X - %X (size: %X)\n", MCSPI0_START_ADDR, MCSPI0_END_ADDR, MCSPI0_SIZE );	
    spi0_addr = mmap(0, MCSPI0_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,MCSPI0_START_ADDR);	// now spi0_addr is pointing at base address

    if(spi0_addr == MAP_FAILED) {																
        printf("Unable to map SPI\n");
        exit(1);
    }
	
    spi0_sysconf_addr = spi0_addr + MCSPI0_SYSCONFIG; // now it is pointing at the target address

														
	
    printf("SPI mapped to %p\n", spi0_addr);
    printf("SPI sysconf mapped to %p\n", spi0_sysconf_addr);

  //  UNTIL HERE EVERYTHING WORKS PROPERLY
	
   reg = *spi0_sysconf_addr;													
   printf("SPI sys configuration: 0x%X\n", reg);


    close(fd);

    return 0;
}

As I have written in the source code, all the mapping process works. The problem arises when I trey to read one of those registers. It appears a bus error (SIGBUS)... I have thought that maybe bus clock is disabled...but I don´t know if I am right and how to fix this problem.

Is it possible that Linux does not allow me to access by this random way?

The think is that I have use exactly the same process to handle GPIOs and everything works perfectly.

I hope that you could help me.

Best regards,

Pablo

 

  • Moving this to the Linux forum.
  • Hi Pablo,

    You can access (read/write) registers from user space with devmem2 tool or readmem tool. These tools are executables based on the corresponding C files (I am attaching readmem.c file). You can explore readmem.c file and re-use it in your user space application.

    1256.readmem.c

    Make sure also you have enabled the SPI clock from the PRCM, before trying to access SPI registers.

    BR
    Pavel

  • I have exact same problem ... readmem.c and devmem2 give same SIGBUS error and SPI clock is enabled because I can do basic spi i/o ... and I am running as root ...

  • Hi Scott,


    Can you provide more details? Like which device you are using, AM335x or another? Custom board or TI board/EVM? Which TI SDK? Can you provide full console log output? What value you have in the PRCM SPI CLKCTRL register?


    Regards,
    Pavel

  • Hi Pavel,

    First, I must apologize.  I can indeed read and write my SPI registers.  I "thought" that my SPI clock was enabled when I read the registers, but it was not.  (Sorry about that).  That said tho', both the INITDLY field in the MODULCTRL register and the TCM field in the CH0_CONF register are 0, meaning there "should" be zero delays.  So I am still confused about the delay between CS and SCLK.

    We are using a Beaglebone Black, which runs an AM3358, and we are using the Debian Jessie release that was pulled from your web side a couple of days ago.

    So, still hoping for something to improve the bandwidth.

    Thanks in advance,

    Scott

  • Scott,

    So finally you are able to access the SPI module from user space.

    If you have another issue, please open new e2e thread with the corresponding subject.

    Regards,
    Pavel