This is one way for direct-register access control of the GPIO and SPI1 ARM
interface of the Gumstix Overo Water.
I mounted the Gumstix on a TOBI board for connections. I obtained to
control the gpio_186 digital pin and to write
at 48Mhz on the SPI1 interface . The procedure can be easily modified for
other digital pins and for other SPI parameters.
I haven't recompiled the kernel or touched the setup files or the
pre-existing drivers... nothing of this.
This is my recipe:
1) install on a formatted SD card the stable Gumstix armstrong linux version
( see http://gumstix.org/get-started/how-to.html )
2) connect your Overo Water + Tobi system on Internet by LAN cable
3) connect the Gumstix to your windows PC by the USB cable and by the
software putty.exe, open a control windows
selecting an emulated serial connection (see putty instructions)
3) Check the internet link, use ( on the Gumstix )
ifconfig eth1 192.168.0.5 netmask 255.255.255.0
or whatever the desired IP address+netmask for connecting the Gumstix @
your router
4) install the C cross compiler :
$ echo 'src/gz angstrom-base
http://www.angstrom-distribution.org/feeds/unstable/ipk/glibc/armv7a/base'
> /etc/opkg/angstrom-base.conf
$ opkg update
$ opkg install task-native-sdk
or better use
$ opkg update
$ opkg install task-native-sdk
for updating all the software.
5) Reboot the gustix
6) Put the following code on your home directory ( or wherewer you prefer )
editing it with
VI main.c
or with any other any other editor you like. I use normally Eclipse for
editing my software on the PC and transferring
it to the remote system (the Gumstix) ( contact me if you want more info
on this);
call the file "main.c"
Refers to the Technical Reference manual of OMA35x Application Processor by
Texas Instruments:
http://www.ti.com/product/omap3530
or directly
http://www.ti.com/lit/ug/spruf98x/spruf98x.pdf
/****************************************************************************************
LOCAL INCLUDES DEFINITION
****************************************************************************************/
#include <stdio.h> // for lprint instruction
#include <fcntl.h> //ok for mmap param
#include <sys/mman.h> //ok for mmap
/****************************************************************************************
LOCAL PARAMETERS DEFINITION
****************************************************************************************/
#define CM_IVA2_BASE 0x48004000
#define CM_CORE_BASE 0x48004A00 // Clock distribution pag. 338,343,344
#define CM_CORE_BASE_OFFSET 0xA00
#define CM_FCLKEN1_CORE_OFFSET 0x0 // pag 443
#define CM_ICLKEN1_CORE_OFFSET 0x10 // pag 446
#define SCM_INTERFACE_BASE 0x48002000 // Pad function definition
#define SCM_PADCONFS_BASE 0x48002030
#define SCM_PADCONFS_BASE_OFFSET 0x30 // defined by nic
#define CONTROL_PADCONF_SYS_NIRQ_OFFSET 0x1B0 // pag. 861 offset from
SCM_PADCONFS_BASE, for GPIO6
#define CONTROL_PADCONF_MCSPI1_CLK_OFFSET 0x198 // pag. 861 offset from
SCM_PADCONFS_BASE
#define CONTROL_PADCONF_MCSPI1_SOMI_OFFSET 0x19C
#define CONTROL_PADCONF_MCSPI1_CS1_OFFSET 0x1A0
#define CONTROL_PADCONF_MCSPI1_CS3_OFFSET 0x1A4
#define GPIO6_BASE 0x49058000 // General Purpose IO n6 config
#define GPIO6_SYSCONFIG_OFFSET 0x10 // from GPIO6_BASE
#define GPIO6_CLEARDATAOUT_OFFSET 0x90
#define GPIO6_SETDATAOUT_OFFSET 0x94
#define GPIO6_OE_OFFSET 0x34
#define GPIO6_CTRL_OFFSET 0x30
#define McSPI1_BASE 0x48098000
#define McSPI1_SYSCONFIG_OFFSET 0x10
#define McSPI1_SYSSTATUS_OFFSET 0x14
#define McSPI1_MODULCTRL_OFFSET 0x28
#define McSPI1_IRQENABLE_OFFSET 0x1C
#define McSPI1_SYST_OFFSET 0x24
#define McSPI1_CH0CONF_OFFSET 0x2C
#define McSPI1_CH1CONF_OFFSET 0x40
#define McSPI1_CH0CTRL_OFFSET 0x34
#define McSPI1_RX0_OFFSET 0x3C
#define McSPI1_TX0_OFFSET 0x38
#define McSPI1_IRQSTATUS_OFFSET 0x18
#define MAP_SIZE (volatile unsigned long) 4*1024
#define MAP_MASK (volatile unsigned long)( MAP_SIZE - 1 )
/****************************************************************************************
COMMON VARIABLES DEFINITION
****************************************************************************************/
#define u32 volatile unsigned long
u32 *A;
u32 *B;
//u32 *regaddr;
/****************************************************************************************
LOCAL FUNCTIONS DEFINITION
****************************************************************************************/
int main(void){
unsigned long i;
int fd;
printf("\n\n\n\n\n\n\n");
printf("\n\n");
printf(" ------------------------------------------\n");
printf(" | GPIO & SPI Example |\n");
printf(" ------------------------------------------\n");
printf(" | Direct Register Access |\n");
printf(" ------------------------------------------\n");
printf("Base address McSPI1: 0x%04x\n",(McSPI1_BASE & ~MAP_MASK ));
printf("Base address GPIO6: 0x%04x\n",(GPIO6_BASE ));// OK
printf("\n");
/******************************************************************************************************************/
// clock distribution
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0) {printf("Could not open file\n"); return;}
B = (volatile unsigned long*) mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, CM_IVA2_BASE & ~MAP_MASK ); // NO MASK
if (B<=0) {printf("Mapping failed\n"); close(fd); return;}
*(u32 *)((u32)B+CM_CORE_BASE_OFFSET+CM_FCLKEN1_CORE_OFFSET)|= 0x00040000;
// enable MCSPI1 CM_FCLK pag.340,344,443
// *(u32 *)((u32)B+CM_ICLKEN1_CORE_OFFSET)|= 0x00040000; // enable
MCSPI1 CM_ICLK - Running after reset pag.345,446
close(fd);
/******************************************************************************************************************/
/******************************************************************************************************************/
// SET GPIO MUX
fd = open("/dev/mem", O_RDWR | O_SYNC); // memory handling
if (fd < 0) {printf("Could not open file\n"); return;} // check memory
handling ok
A = (u32 *) mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
SCM_INTERFACE_BASE & ~MAP_MASK); //attenzione ! interface non pad; pad ha un
offset di 0x30
if (A<=0) {printf("Mapping failed\n"); close(fd); return;} // just in
case
/*********** GPIO6 pad config ***********/
// show registers content for gpio_186 over GPIO6 interface
//printf("SCM_SCM_BASE 0x%08x\n",SCM_INTERFACE_BASE);
printf("SCM_PADCONFS_BASE 0x%08x\n",SCM_INTERFACE_BASE+0x30);
printf("SCM_PADCONFS offset 0x%08x\n",CONTROL_PADCONF_SYS_NIRQ_OFFSET);
printf("Pointer: 0x%08x\n",(u32) A); printf("Pointer+offset:
0x%08x\n",(u32)A+0x30+CONTROL_PADCONF_SYS_NIRQ_OFFSET );
printf("Pointer+offset content: 0x%08x\n",*(u32
*)((u32)A+0x30+CONTROL_PADCONF_SYS_NIRQ_OFFSET) );
*(u32
*)((u32)A+SCM_PADCONFS_BASE_OFFSET+CONTROL_PADCONF_SYS_NIRQ_OFFSET)|=(0b100<<16);
// imposta mode 4 sul registro configurazione pad 186; abilita uso pin
digitale
printf("gpio_186 PAD configuration done.\n",MAP_SIZE);
/********** SPI_1 **********/
*(u32
*)((u32)A+SCM_PADCONFS_BASE_OFFSET+CONTROL_PADCONF_MCSPI1_CLK_OFFSET) &=
0xfffffff8; // set mode 0 on mcspi1_clk pin ; enable pin for mcspi1 clock
function
*(u32
*)((u32)A+SCM_PADCONFS_BASE_OFFSET+CONTROL_PADCONF_MCSPI1_CLK_OFFSET) |=
0x00000100; // set the input-enable-bit on clock pin for functionality,
retiming pag.2843,2845
*(u32
*)((u32)A+SCM_PADCONFS_BASE_OFFSET+CONTROL_PADCONF_MCSPI1_CLK_OFFSET) &=
0xfff8ffff; // set mode 0 on mcspi1_simo pin ; pin for mcspi1 is simo (slave
in - master out)
*(u32
*)((u32)A+SCM_PADCONFS_BASE_OFFSET+CONTROL_PADCONF_MCSPI1_SOMI_OFFSET)
&=0xfffffff8; // set mode 0 on mcspi1_somi pin ; pin for mcspi1 is somi
*(u32
*)((u32)A+SCM_PADCONFS_BASE_OFFSET+CONTROL_PADCONF_MCSPI1_SOMI_OFFSET)
&=0xfff8ffff; // set mode 0 on mcspi1_cs0 pin ; pin for mcspi1 is used as
cs0
*(u32
*)((u32)A+SCM_PADCONFS_BASE_OFFSET+CONTROL_PADCONF_MCSPI1_CS1_OFFSET) &=
0xfffffff8; // set mode 0 on mcspi1_cs1 pin ; pin for mcspi1 is used as cs1
//*(u32
*)((u32)A+SCM_PADCONFS_BASE_OFFSET+CONTROL_PADCONF_MCSPI1_CS1_OFFSET)|=
0x00070000; // set mode 7 on mcspi1_cs2 pin ; pin for mcspi1 is in safe mode
//*(u32
*)((u32)A+SCM_PADCONFS_BASE_OFFSET+CONTROL_PADCONF_MCSPI1_CS3_OFFSET)|=
0x00000007; // set mode 7 on mcspi1_cs3 pin ; pin for mcspi1 is in safe mode
*(u32 *)((u32)A+SCM_PADCONFS_BASE_OFFSET+0x108)|= 0x00000007; // 0x4 set
mode4 on gpio_114; 0x7 safe mode
/********************/
printf("SPI1 PAD configuration done.\n",MAP_SIZE);
close(fd);
/******************************************************************************************************************/
/******************************************************************************************************************/
// GPIO6 control
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0) {printf("Could not open file\n"); return;}
B = (u32 *) mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
GPIO6_BASE & ~MAP_MASK); // COM1 0x4806A000
//if (B == MAP_FAILED) {printf("Mapping failed value 0x%04x\n",B);
close(fd); return;} // %d.\n
if (B<=0) {printf("Mapping failed\n"); close(fd); return;}
// gpio_186 handling over GPIO6 interface
*(u32 *)((u32)B+GPIO6_SYSCONFIG_OFFSET)|= 0x00000004;// bit2=1 enable/wake
up, free running clock
*(u32 *)((u32)B+GPIO6_CTRL_OFFSET)&= 0xfffffffe; // bit0=0 module
enabled, clock not gated , clock=interface clock divided by 8, 0xe=0b1110
//*(u32 *)((u32)B+GPIO6_CTRL_OFFSET)&= 0xfffffff8; //
bit0=0,bit1=0,bit2=0 module enabled, clock not gated , clock=interface clock
not divided,0x8=0b1000
*(u32 *)((u32)B+GPIO6_OE_OFFSET)&= 0xfbffffff; // bit26=0, gpio_186
output, 0b1011=0xb
// send signals on digital out gpio_186
for (i=0;i<1000000;i++){
*(u32 *)((u32)B+(GPIO6_SETDATAOUT_OFFSET)) |= 0x04000000;
*(u32 *)((u32)B+(GPIO6_CLEARDATAOUT_OFFSET))|= 0x04000000;
}
printf("Burst sent on gpio_186\n");
close(fd);
/******************************************************************************************************************/
//SPI1 control - TX & RX - Polling method
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0) {printf("Could not open file\n"); return;}
B = (u32 *) mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
McSPI1_BASE & ~MAP_MASK);
if (B<=0) {printf("Mapping failed\n"); close(fd); return;}
// Init sequence pag 2886
//*(u32 *)((u32)B+McSPI1_IRQENABLE_OFFSET)|=0xfffc0000; // disable all
interrupts
*(u32 *)((u32)B+McSPI1_SYSCONFIG_OFFSET)|=0x00000002; // softreset
pag.2851,2886
printf("Wait for SPI1 ready...\n");
while ((*(u32 *)((u32)B+McSPI1_SYSSTATUS_OFFSET) && 0x00000001)==0);
if ( (*(u32 *)((u32)B+McSPI1_SYSSTATUS_OFFSET) && 0x00000001) != 1)
{printf("SPI1 not ready \n"); return;} // check McSPI1_SYSSTATUS bit0
enabled
// Mode selection - Polling mode
*(u32 *)((u32)B+McSPI1_CH0CONF_OFFSET)&=0xfffbffff; // pin 18, IS bit set to
0 for spi1_somi in rx mode
*(u32 *)((u32)B+McSPI1_CH0CONF_OFFSET)&=0xfffdffff; *(u32
*)((u32)B+McSPI1_CH0CONF_OFFSET)|=0x00010000; // pin 17,16 DPE1,0 = 0b01 for
simo in tx mode
*(u32 *)((u32)B+McSPI1_CH0CONF_OFFSET)&=0xffffcfff; // pin 12:13=0b00 ;
Master TX & RX pag.2855
//*(u32 *)((u32)B+McSPI1_CH0CONF_OFFSET)|=0x00002000; // pin 12:13=0b10 ;
Master Tx only pag.2856,2914-5
// Master Rx only pag.2856
;;;;;*(u32 *)((u32)B+McSPI1_CH0CONF_OFFSET)|=(0x8<<7); // set WL filed tp 9
bit word
*(u32 *)((u32)B+McSPI1_CH0CONF_OFFSET)|=(0x1<<6);// set bit 6 EPOL to 1
*(u32 *)((u32)B+McSPI1_CH0CONF_OFFSET)&=0xfffffffd;// set bit 1 POL to 0
*(u32 *)((u32)B+McSPI1_CH0CONF_OFFSET)&=0xfffffffe;// set bit 0 to 0 : data
latched on odd-numbered edges of the clk
// Clock init
*(u32 *)((u32)B+McSPI1_MODULCTRL_OFFSET)&=0xfffffffb; //set bit 2 to 0 ;
Enable clock and set Master mode pag.2913
//*(u32 *)((u32)B+McSPI1_CH0CONF_OFFSET)&=0xffffffc3; // pin 2:5 set to 0 ;
clock=48MHz ; default
// set here INPUTENABLE BIT on CONTROL_PADCONF register ; already done
*(u32 *)((u32)B+McSPI1_CH0CTRL_OFFSET)|=0x00000001;// set bit 0 to 1 ;
Enable bit
// Write operation - Polling method
*(u32 *)((u32)B+McSPI1_IRQSTATUS_OFFSET)|=0x00000001;// TX0_EMPTY=1 to reset
the status
*(u32 *)((u32)B+McSPI1_TX0_OFFSET)=0xf0f0f0f0;// Populate write register
with the info that you want to TX
printf("SPI1 writing busy...\n");
while(!(*(u32 *)((u32)B+McSPI1_TX0_OFFSET) && 0x1));// waits TX0_EMPTY=1 to
terminate writing
// Read operation - Polling method .... to do
close(fd);
printf("pointers to memory are ok\n") ;
return(0);
}
--
View this message in context: http://gumstix.8.n6.nabble.com/Direct-register-access-control-of-GPIO-and-SPI-1-ARM-interface-on-Overo-Water-Tobi-SOLVED-tp4965148.html
Sent from the Gumstix mailing list archive at Nabble.com.
|