mmap SPI1 beaglebone black

Dear all,
I have tried to work with SPI1 on the beaglebone black (kernel 3.8) by using spidev.
I saw several guides on that and so, I compiled my own device tree and it works:
I can send and receive packet, change the spi clock frequency and so on.
This is my device tree file

/dts-v1/;
/plugin/;

/ {
compatible = “ti,beaglebone”, “ti,beaglebone-black”;
part-number = “BB-SPI1”;
version = “00A0”;

fragment@0 {
target = <&am33xx_pinmux>;
overlay {
bone_replicape_spi1_pins: pinmux_replicape_spi1_pins {
pinctrl-single,pins = <
0x190 0x3B /* P9_31 = mcasp0_aclkx.spi1_sclk , NO PULL | MODE3 /
0x194 0x3B /
P9_29 = mcasp0_fsx.spi1_d0 , NO PULL | MODE3 /
0x198 0x1B /
P9_30 = mcasp0_axr0.spi1_d1 , NO PULL | MODE3 /
0x19c 0x1B /
P9_28 = mcasp0_ahclkr.spi1_cs0 , NO PULL | MODE3 /
0x164 0x0A /
P9_42 = spi1_cs1 , NO PULL | MODE2 */

;
};
};
};

fragment@1 {
target = <&spi1>;
overlay {
#address-cells = <1>;
#size-cells = <0>;
status = “okay”;
pinctrl-names = “default”;
pinctrl-0 = <&bone_replicape_spi1_pins>;
cs-gpios = <&gpio4 17 0>, <&gpio1 7 0>;

cs0-device {
#address-cells = <1>;
#size-cells = <0>;
compatible = “spidev”;
reg = <0>;
spi-max-frequency = <16000000>;
};
cs1-device {
#address-cells = <1>;
#size-cells = <0>;
compatible = “spidev”;
reg = <1>;
spi-max-frequency = <16000000>;
};
};
};
};

Now I would like to go ahead and try to map it directly by mmap.

This is my C code:

#define SPI_BASE 0x481A0000 // SPI BASE Register
#define REGLEN 0x400
#define SPI_REVISION (0x000/4)
#define SPI_SYSCONFIG (0x110/4)
#define SPI_SYSSTATUS (0x114/4)



int main() {

volatile unsigned int *data = NULL;
volatile unsigned int *spi_addr = NULL;
int fd_gp = open(“/dev/mem”,O_RDWR);
spi_addr = mmap(NULL, REGLEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd_gp, SPI_BASE);
data = spi_addr + SPI_REVISION;
printf(“SPI_REVISION value = 0x%x.\n”,*data);
return 0;
}

As soon as I try to print the SPI_REVISION value, my program gets stuck.

I am quite sure I am doing a stupid error somewhere but I do not see where.

Can you help me?

Thanks.

Alberto

I think your problem is probably related to page alignment issues. This issue was discussed on this mailing list back in April 27/28. Search google groups for:

“Re: [beagleboard] Official eQEP driver Support”

Regards,
John

Yes, I can help you! I am talking to the SPI0 hardware directly so I can use it in slave mode. Since you are not using the driver, you need to enable the clock to the SPI module or else register accesses fail. I do it like this:

// map a pointer to the clock control block:
pClockControl = (char *)mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, mem, CM_PER_BASE);

if(pClockControl == (char *)0xFFFFFFFF)
{
printf(“Memory map failed. error %i\n”, (uint32_t)pClockControl);
close( mem );
return 2;
}
printf(“pClockControl = 0x%08X\n”, (uint32_t)(pClockControl) );
value = *(uint32_t *)(pClockControl + CM_PER_SPI0_CLKCTRL);
printf(“CM_PER_SPI0_CLKCTRL was 0x%08X\n”, value);
*(uint32_t *)(pClockControl + CM_PER_SPI0_CLKCTRL) = SPIO_CLKCTRL_MODE_ENABLE;
value = *(uint32_t *)(pClockControl + CM_PER_SPI0_CLKCTRL);
printf(“CM_PER_SPI0_CLKCTRL now 0x%08X\n”, value);
while( value != SPIO_CLKCTRL_MODE_ENABLE )
{
// poll until the SPI clock is enabled
value = *(uint32_t *)(pClockControl + CM_PER_SPI0_CLKCTRL);
printf(“CM_PER_SPI0_CLKCTRL now 0x%08X\n”, value);
}

munmap( pClockControl, 4096 ); // free this memory map element

My code is enabling the clock to SPI0, so you might have to change some enable bits to handle SPI1, but you get the general idea. Check the spruh73.pdf to see those bits.