Sample code/C/SPI

From GumstixDocsWiki

< Sample
code

Jump to: navigation,
search

Contents

1 Kernel/Driver-based SPI C
Code

2 A note on the drivers -
chip select and interrupt lines

3 Direct Register Access SPI
C Code

4 Direct Register Access SPI
C Code For The PXA270

Kernel/Driver-based SPI C Code

Look here: Sample_code/C/SPI/kernel

A note on the drivers - chip select and interrupt
lines

Part of the SSP physical protocol is that several SSP devices may share the
same 3 wire bus. In order to determine which device is being accessed chip
select lines are used. Where the SSP peripheral can request an interrupt, a
further line is required.

As I understand it the Intel pxa-255 allows all General Purpose Input Output
(GPIO) lines to be either I/O, special purpose or interrupt inputs.

When drivers are made will they assign chip select and interrupt input lines?
I am looking at interfacing the MCP2515 can controller to gumstix, and this can
only buffer 2 incoming messages before overrunning, thus making it very
necessary to respond to interrupts (to read the messages, and get them in the
SSP FIFO before overrun).

Ideally each peripheral would have an chip select and interrupt line
assigned.

Direct Register Access SPI C Code

/**************************************************************************
* SPI Sample code. (Direct Regsiter Access via /dev/mem) *
* *
* This code is fairly straight-forward and does not require extra *
* kernel modules to obtain SPI communication via the NSSP Pins *
* on the GumStix. Comments have been included for alternate *
* bit configurations where appropriate. The pxa255 supports *
* Motorola SPI, TexasInstruments SSP, and Microwire. *
* *
* See the "SPIsetConReg()" function below for more information. *
* This example is currently set for: *
* 1.6Mbit/sec, SPI, 8-bit-data, idle=low *
* GPIO Pins: *
* 81 to NSSPClk *
* 82 to NSSPSFRM *
* 83 to NSSPTXD *
* 84 to NSSPRXD *
* Enjoy! *
* *
**************************************************************************/

* Created by: Ernest Earon *
* Modified by: Adam Kumpf - [email-masked] (July 2006) *
* Tweaks by: Chuck Kamas (March 2007) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
**************************************************************************/

// ---- Include Files ----------------------------------------------------
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>

//------------------------------------------------------------------------
// ---- Memory Location Definitions -------------------------------------
//------------------------------------------------------------------------
// See the Intel(r) PXA255 Processor Developer's Manual
#define GPIO_BASE_OFFSET 0x40E00000
#define SPIDirROff 0x00000014
#define SPIAfROff 0x00000068

// Register definitions in the PXA255 manual in byte locations
#define NSSPCR0_BL 0x41400000
#define NSSPCR1_BL 0x00000004
#define NSSSR_BL 0x00000008
#define NSSITR_BL 0x0000000C
#define NSSDR_BL 0x00000010
#define NSST0_BL 0x00000028
#define NSSPSP_BL 0x0000002C

// Register definitions in word locations
#define NSSPCR0 0x41400000
#define NSSPCR1 0x00000001
#define NSSSR 0x00000002
#define NSSITR 0x00000003
#define NSSDR 0x00000004
#define NSST0 0x0000000a
#define NSSPSP 0x0000000b

//--------------------------------------------------------------------
// ---- Function Prototypes -----------------------------------------
//--------------------------------------------------------------------
int SPIinit(int ClockDivider); // initialise the SPI stuff
int SPIsetConReg(int ClockDivider); // set the control registers for SPI
void SPIsetFunc(void); // set alternate functions of pins to NSSP
void SPIsetDir(void); // set the appropriate directions
int SPI_TxRx(int b); // Write a byte and read a byte

//----------------------------------------------------------------
// ---- Global Variables -----------------------------------------
//----------------------------------------------------------------
unsigned int* PXm_map;
unsigned int* CR_map;

int gpio_fd;

//***************************************************************************

//***************************************************************************
/**
*
* Main
*/
int main(int argc, char *argv[])
{
int i = 0;

// SPI Datarate Settings...
// ClockDivider = 0 ~ 1.62 Mbit/sec
// ClockDivider = 4 ~ 480 Kbit/sec
// ClockDivider = 8 ~ 300 Kbit/sec
// ClockDivider = 16 ~ 170 Kbit/sec
int ClockDivider = 0;

// start the main routine
printf("\n\n");
printf(" ------------------------------------------\n");
printf(" | SPI Sample |\n");
printf(" ------------------------------------------\n");
printf(" | Direct Register Access SPI Sample |\n");
printf(" ------------------------------------------\n");

printf(" -> Msg<- Initializing SPI port\n");
int result = SPIinit(ClockDivider); // Initialize NSSP / SPI Port
printf(" -> Msg<- Result of SPI Init = %d\n",result);

printf(" -> Msg<- Sending test characters....\n");
for(i=0; i<0x0200; i++){
int rx = SPI_TxRx(i & 0xffff); // Transmit/Receive via NSSP/SPI port
printf("0x%04x(0x%04x) \n",i & 0xffff,rx);
fflush(stdout);
usleep(40000);
}
printf("\n");

printf(" -> Msg<- Closing NSSP/SPI Port\n");
close(gpio_fd);
printf(" -> Msg<- done.\n\n");

return 1;
}

//***************************************************************************
/**
*
* SPI Initialization
*/
int SPIinit (int ClockDivider)
{
gpio_fd = open("/dev/mem",O_RDWR | O_SYNC);

if (gpio_fd < 0)
return -1;

PXm_map = (unsigned int*) mmap(NULL, 4096UL,
PROT_READ | PROT_WRITE, MAP_SHARED, gpio_fd,
GPIO_BASE_OFFSET & ~4095UL
);

if (PXm_map <= 0)
return -2;

SPIsetDir(); // set the pin directions for 81,82,83,84

SPIsetFunc(); // set the alternate functions of pins 81,82,83,84:

return SPIsetConReg(ClockDivider); // Set the nssp function to support motorola SPI
}

//***************************************************************************
/**
*
* SPI Transmit / Receive. (they happen at the same time)
*/
int SPI_TxRx(int b) // send and receive a byte through the SPI
{
unsigned int* volatile Reg_FIFO;
unsigned int* volatile Reg_Status;
int q;

Reg_FIFO = (unsigned int *)(CR_map + NSSDR);
Reg_Status = (unsigned int *)(CR_map + NSSSR);

q = (*Reg_FIFO) & 0xffff; //
q = (*Reg_FIFO) & 0xffff; //

while(((*Reg_Status) & 32) == 0); // wait for TX FIFO to be at/below threshold
while((*Reg_Status) & 16); // wait for SSP to not be Busy

*Reg_FIFO = (unsigned int)b; // Set the Tx Value

for(q=0;q<50;q++); // just a tiny delay so Tx will start to go...

while(((*Reg_Status) & 64) == 0); // wait for RX FIFO to be at/above threshold
while((*Reg_Status) & 16); // wait for SSP to not be Busy

return (*Reg_FIFO) & 0xffff; // return the Rx Value
}

//***************************************************************************
/**
*
* SPI Configuration Setup: EDIT THIS!!  :)
*
* 0 <= ClockDivider <= 255
* BitRate = 3.6864x106 / (2 x (ClockDivider + 1))
*/
int SPIsetConReg (int ClockDivider) // set the control registers for SPI
{
int gpio_fd = open("/dev/mem",O_RDWR | O_SYNC);
unsigned int* volatile Reg;

ClockDivider = ClockDivider & 0xff;

if (gpio_fd < 0)
return -1;

CR_map = (unsigned int*) mmap(NULL, 4096UL,
PROT_READ | PROT_WRITE, MAP_SHARED, gpio_fd,
NSSPCR0 & ~4095UL
);

if (CR_map <= 0)
return -2;

Reg = (unsigned int *)(CR_map + NSSPCR1);
(*Reg) = 0x40000000;
// -----------CR1 Bit Definitions ------------
// bit 5 = Microwire TxSize (0=8-bit,1=16-bit);
// bit 4 = Clock Phase (0=1:0.5, 1=0.5:1)
// bit 3 = Clock Polarity Setting (0=idle_is_low, 1=idle_is_high)
//*Reg |= 1 << 5; // example, this is how you would set bit 5 for 16-bit Microwire

Reg = (unsigned int *)(CR_map + 0); // this will also enable the SPI
// -----------CR0 Bit Definitions ------------
// bit 15:8 = clockrate divider
// bit 7 = SSP Enable
// bit 6 = Select External Clock (0=internal)
// bit 5:4 = frame format (0=Motorola, 1=TexInst, 2=Natl.Microwire)
// bit 3:0 = data bits - 1 (ex. 0x7 = 8-data-bits, 0xf = 16-data-bits)

*Reg = 0x07; // 16-data-bits,Motorola format (use 0x07 for 8-data-bits,Motorola)
*Reg |= ClockDivider << 8;
*Reg |= 1 << 7; // Enable SPI
printf(" -> Msg<- SPIsetConReg: CR0 = 0x%04x\n",(*Reg));
return 1;
}

void SPIsetFunc (void)
{
// map offset:
// pins 81-84 are in 6th AF reg (AFR 5)
// byte position is 5 * bytes per unit + AF Reg Offset = 5 * 4 + 0x54 = 104
// 104 bytes to words = 104/4 = 26 --> 26 <--
unsigned int* volatile pGPAF = (PXm_map + 26);
//Set 81 to NSSPClk
// 82 to NSSPSFRM
// 83 to NSSPTXD
// 84 to NSSPRXD
// What pins do we set to 1s?

// what pins do we set to 0s?
*pGPAF = 596;
}

void SPIsetDir (void)
{
// map offset:
// pins 81-84 are in 3rd Dir reg (DirR 2)
// byte position is 2 * bytes per unit + Dir Reg Offset = 2 * 4 + 0xC = 20
// 104 bytes to words = 20/4 = 5 --> 5 <--
unsigned int* volatile pGPD = (PXm_map + 5);
//Set 81 to out bit 17 1
// 82 to out 18 1
// 83 to out 19 1
// 84 to in 20 0
*pGPD = 0xE0000;
}

Direct Register Access SPI C Code For The
PXA270

/**************************************************************************
* Modified from the PXA255 Version *
* Modifications made by Rich Ketcham and Dante Sanchez (January 2008) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
**************************************************************************/

//------------------------------------------------------------------------
// ---- Include Files ----------------------------------------------------
//------------------------------------------------------------------------
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>

#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>

//------------------------------------------------------------------------
// ---- Memory Location Definitions -------------------------------------
//------------------------------------------------------------------------

//PXA270 Register Summary is on pg 507
#define MAP_SIZE 4096
#define MAP_MASK ( MAP_SIZE - 1 )

#define PXA270_GAFR0_L 0x40E00054 //pg 1016
#define PXA270_GAFR0_U 0x40E00058 //pg 1017

#define PXA270_GAFR1_L 0x40E0005C //pg 1017
#define PXA270_GAFR1_U 0x40E00060 //pg 1018

#define PXA270_GAFR2_L 0x40E00064 //pg 1018
#define PXA270_GAFR2_U 0x40E00068 //pg 1019

#define PXA270_GPDR0 0x40E0000C //pg 1004
#define PXA270_GPDR1 0x40E00010 //pg 1004
#define PXA270_GPDR2 0x40E00014 //pg 1005

#define PXA270_GPCR1 0x40E00028 //pg 1009
#define PXA270_GPCR2 0x40E0002C //pg 1009

#define PXA270_GPSR1 0x40E0001C //pg 1007
#define PXA270_GPSR2 0x40E00020 //pg 1007

#define GPIO_BASE_OFFSET 0x40E00000 //Beginning of GPIO. Look for this register (GPIO0) on page 1004 of the 270 manual.
#define NSSPCR0 0x41700000 //NSSP Control Register 0. Look for this register (SSCR0) on page 479 of the 270 manual.

#define PXA270_SSCR0_1 0x41000000 // pg 479
#define PXA270_SSCR0_2 0x41700000 // pg 479
#define PXA270_SSCR0_3 0x41900000 // pg 479

#define PXA270_SSCR1_1 0x41000004 // pg 484
#define PXA270_SSCR1_2 0x41700004 // pg 484
#define PXA270_SSCR1_3 0x41900004 // pg 484

#define PXA270_SSSR_2 0x41700008 //pg 497 SSP 2 Status Register
#define PXA270_SSDR_2 0x41700010 //pg 501 SSP 2 Data Read/Write Register

#define PXA270_CCCR 0x41300000 // page 173
#define PXA270_CKEN 0x41300004 // page 176
#define PXA270_OSCC 0x41300008 // page 177

//----------------------------------------------------------------
//-------PXA270 Bit Masks-----------------------------------------
//----------------------------------------------------------------
//SSSR - Status Register
#define TNF 0x4 //TX FIFO Not Full 0 = TX FIFO is full 1 = TX FIFO is not full
#define RNE 0x8 //RX FIFO Not Empty, 0 = RX FIFO is empty, 1 = RX FIFO is not empty
#define BSY 0x10 // 0 = means the SSP port is idle or disabled 1 = SSP port is actively transmitting or receiving data
#define ROR (0x1 << 7) //RX FIFO Over-Run
#define RFL 0xF000 //TX FIFO Level -- TFL is the number of valid entries crrently in the TX FIFO
#define TFL 0xF00 //TX FIFO Level -- TFL is the number of valid entries crrently in the TX FIFO

//SSCR0 Defines - Control Register
#define SSCR0_MASK 0x47200000
#define DSS (0xF)
#define FRF (0x3 << 4)
#define SSE (0x1 << 7)
#define EDSS (0x1 << 20)
#define RIM (0x1 << 22)
#define TIM (0x1 << 23)

//SSCR1 Defines - Control Register
#define SSCR1_MASK 0x10308020
#define RIE (0x1 << 0)
#define TIE (0x1 << 1)
#define LBM (0x1 << 2)
#define SPO (0x1 << 3) //Clock polarity
#define SPH (0x1 << 4) //Clock phase
#define RWOT (0x1 << 23) // Receive Without Transmit 0 = Transmit/Receive Mode 1 = Receive Without Transmit Mode
#define TTE (0x1 << 30)
#define TTELP (0x1 << 31) //TXD Tristate Enable on Last Phase

// GPDR2 - GPIO Control
#define GPIO75 (0x1 << 11) //GPIO 75

//----------------------------------------------------------------
// ---- Global Variables -----------------------------------------
//----------------------------------------------------------------
typedef unsigned int u32;
void *map, *regaddr;

//--------------------------------------------------------------------
// ---- Function Prototypes -----------------------------------------
//--------------------------------------------------------------------

static void putmem(u32 addr, u32 val); //Write to a memory location
static u32 getmem(u32 addr);//Get register address
void init(int fd, int var);//Initialize the mem file descriptor and memory map for the LED

int SPIinit(int fd, int ClockDivider); // initialise the SPI stuff
int SPIsetConReg(int fd, int ClockDivider); // set the control registers for SPI
void SPIsetFunc(void); // set alternate functions of pins to NSSP
void SPIsetDir(void); // set the appropriate directions
u32 SPI_TxRx(int fd, int b); // Write a byte and read a byte
void ChipSelect(int fd, short select); //Use this for the chip select

//--------------------------------------------------------------------
// ---- Main Function -----------------------------------------------
//--------------------------------------------------------------------

int main( int argc, char **argv )
{
unsigned int i;
int fd = open("/dev/mem", O_RDWR | O_SYNC);

if (fd<0) {
perror("open(\"/dev/mem\")");
exit(1);
}

// SPI Datarate Settings...
// ClockDivider = 0 ~ 1.62 Mbit/sec
// ClockDivider = 4 ~ 480 Kbit/sec
// ClockDivider = 8 ~ 300 Kbit/sec
// ClockDivider = 16 ~ 170 Kbit/sec
int ClockDivider = 0;

// start the main routine
printf("\n\n");
printf(" ------------------------------------------\n");
printf(" | SPI Sample |\n");
printf(" ------------------------------------------\n");
printf(" | Direct Register Access SPI Sample |\n");
printf(" ------------------------------------------\n");

printf(" -> Msg<- Initializing SPI port\n");
int result = SPIinit(fd, ClockDivider); // Initialize NSSP / SPI Port
printf(" -> Msg<- Result of SPI Init = %d\n",result);
printf(" -> Msg<- Sending test characters....\n");
for(i=0; i<0x200; i++){
int rx = SPI_TxRx(fd, i & 0xffff); // Transmit/Receive via NSSP/SPI port
printf("0x%04x(0x%04x) \n",i & 0xffff,rx);
fflush(stdout);
usleep(40000);
}
printf("\n");

printf(" -> Msg<- Closing NSSP/SPI Port\n");
close(fd);
printf(" -> Msg<- done.\n\n");

munmap(0,MAP_SIZE);

return 0;
}

//--------------------------------------------------------------------
// ---- Functions ---------------------------------------------------
//--------------------------------------------------------------------

//**************************************************************************//
//init - Initialize the mem map
//**************************************************************************//
void init(int fd, int var)
{
map = mmap(0,
MAP_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
var & ~MAP_MASK
);
if (map == (void*)-1 ) {
perror("mmap()");
exit(1);
}
}
//**************************************************************************//
//putmem - Write val to the register located at addr.
//**************************************************************************//
static void putmem(u32 addr, u32 val)
{
regaddr = map + (addr & MAP_MASK);
*(u32*) regaddr = val;
}

//**************************************************************************//
//getmem - Get the register address
//**************************************************************************//
static u32 getmem(u32 addr)
{
u32 val;

regaddr = map + (addr & MAP_MASK);
val = *(u32*) regaddr;
return val;
}
//**************************************************************************//
//SPIinit- Initialize the SPI
//**************************************************************************//
int SPIinit (int fd, int ClockDivider)
{
init(fd,GPIO_BASE_OFFSET);
SPIsetDir(); // set the pin directions for pins 11, 13, 14 , and 19
SPIsetFunc(); // set the alternate functions for pins 11, 13, 14 , and 19
return SPIsetConReg(fd, ClockDivider); // Set the nssp function to support motorola SPI
}

//**************************************************************************//
//SPI Transmit / Receive. (they happen at the same time)
//**************************************************************************//
u32 SPI_TxRx(int fd, int b) // send and receive a byte through the SPI
{
//------------Wait until all of the TX packets are sent ----//
while(((getmem(PXA270_SSSR_2) & TFL) >> 8 ) & 0x0F); //Wait for TX to finish
while(!((getmem(PXA270_SSSR_2) & TNF) >> 2 ) & 0x0F); //Wait for the TX to not be full

//ChipSelect On
ChipSelect(fd, 0x1);
init(fd,NSSPCR0);

putmem(PXA270_SSDR_2, b); // Set the TX Value

//ChipSelect Off
ChipSelect(fd,0x0);
init(fd,NSSPCR0);

//------------Wait until all of the TX packets are sent ----//
// 0 = TX FIFO is full 1 = TX FIFO is not full
while(!(getmem(PXA270_SSSR_2) & TNF) >> 2);
//Wait for the port to finish and to receive something
while(((getmem(PXA270_SSSR_2) & BSY) >> 4) || !((getmem(PXA270_SSSR_2) & RNE) >> 3 ));

return getmem(PXA270_SSDR_2) & 0xffff;
}

//**************************************************************************//
// SPI Configuration Setup: EDIT THIS!!  :)
//
// 0 <= ClockDivider <= 255
// BitRate = 3.6864x106 / (2 x (ClockDivider + 1))
//**************************************************************************//
int SPIsetConReg (int fd, int ClockDivider) // set the control registers for SPI
{
// Clock Disable
init(fd,PXA270_CCCR);
int CKEN = getmem(PXA270_CKEN);
CKEN &= ~(1<<3); // SSP2 Unit Clock Enable
putmem(PXA270_CKEN, CKEN);

//Control Register 0
init(fd,NSSPCR0);

//---------------Control Register 0-----------------------------------------//
int sscr0 = getmem(PXA270_SSCR0_2); // Get mem location
sscr0 |= (TIM|RIM);// Do not generate interrupts for FIFO over/under runs
sscr0 &= ~(0xF);//Clear the DSS bits
sscr0 |= DSS;//Set the data size
sscr0 &= ~EDSS;//Clear the EDSS bit
sscr0 &= ~FRF; //Clear the frame format bits (Our FRF should be 0b00 anyway)
int ClockRate = 590000;// ~550 KHz
int SCR = ( (13000000/ClockRate)-1);
sscr0 |= (SCR << 8);
putmem(PXA270_SSCR0_2, sscr0); // Put value in mem location

//---------------Control Register 1-----------------------------------------//
int sscr1 = getmem(PXA270_SSCR1_2);
sscr1 = 0; //Reset Control Register 1
sscr1 &= ~(0x3c00); //Clear fifo levels (RFT gets 0 and TFT is & with 1111 which will equal 0).
sscr1 |= ( (8-1) << 10);//Set RX fifo levels
sscr1 &= ~LBM;//Disable
sscr1 &= ~TIE;//Disable
sscr1 &= ~RIE;//Disable
sscr1 &= ~SPO;//Polarity
sscr1 &= ~SPH;//Phase
putmem(PXA270_SSCR1_2, sscr1); // Put value in mem location

//---------------Control Register 0-----------------------------------------//
sscr0 = getmem(PXA270_SSCR0_2); // Get mem location
sscr0 |= SSE;
putmem(PXA270_SSCR0_2, sscr0); // Put value in mem location printf(" -> Msg<- SPIsetConReg: CR0 = 0x%04x\n",(getmem(PXA270_SSCR0_2)));

//---------------Clock Enable-----------------------------------------//
init(fd,PXA270_CCCR);
CKEN = getmem(PXA270_CKEN);
CKEN |= (1<<3); // SSP2 Unit Clock Enable
putmem(PXA270_CKEN, CKEN);
CKEN = getmem(PXA270_CKEN);
printf("Now Clocks enabled = 0x%x\n", CKEN);

init(fd,NSSPCR0); //Reset the map

return 1;
}

//**************************************************************************//
//SPIsetFunc - Set the alternative function registers
//
//**************************************************************************//
void SPIsetFunc (void)
{
//---------------Alternate Function Register 0 L----------------------------//
//For pins 11,13, and 14: //
//AF(0-10)[0-21] = X --> Don't care //
//AF11[22-23] = 0x2 = 0b10 //
//AF12[24-25] = X //
//AF13[26-27] = 0x1 = 0b1 //
//AF14[28-29] = 0x2 = 0b10 //
//--------------------------------------------------------------------------//
int i = getmem(PXA270_GAFR0_L);
i &= 0xC33FFFFF; // Bit Mask --> 0b 11 00 00 11 00 11 11 11 11 11 11 11 11 11 11 11
i |= 0x24800000; //0b 10 01 00 10 00 00 00 00 00 00 00 00 00 00 00
putmem(PXA270_GAFR0_L, i);
printf("PXA270_GAFR0_L = 0x%X\n",getmem(PXA270_GAFR0_L));

//---------------Alternate Function Register 0 U----------------------------//
//For pin 19: //
//AF(16-18)[0-5] = X --> Don't care //
//AF19[6-7] = 0b1 //
//Everything Else = X //
//--------------------------------------------------------------------------//
i = getmem(PXA270_GAFR0_U);
i &= 0xFFFFFF3F;//0b11 11 11 11 11 11 11 11 11 11 11 11 00 11 11 11
i |= 0x40; // 0b 01 00 00 00
putmem(PXA270_GAFR0_U, i);
printf("PXA270_GAFR0_U = 0x%X\n",getmem(PXA270_GAFR0_U));

//---------------Alternate Function Register 2 L----------------------------//
//Set GPIO75 as GPIO //
//--------------------------------------------------------------------------//
i = getmem(PXA270_GAFR2_L);
i &= ~(0x3 << 22);
putmem(PXA270_GAFR2_L, i);
printf("PXA270_GAFR2_L = 0x%X\n",getmem(PXA270_GAFR0_U));

}

//**************************************************************************//
//SPIsetDir - Set the gpio direction registers
//
//**************************************************************************//
void SPIsetDir (void)
{
//---------------Direction Register 0-----------------------------------//
//For the SPI, we are concerned with the following pins: //
// Pin 11 = PD11[11] = SSPRXD2 = Input = 0 //
// Pin 13 = PD13[13] = SSPTXD2 = Output = 1 //
// Pin 14 = PD14[14] = SSPSFRM2 = Output = 1 //
// Pin 19 = PD19[19] = SSPSCLK2 = Output = 1 //
// //
// PD[0-10] = X --> Don't care. //
// PD11[11] = 0 //
// PD12[12] = X //
// PD13[13] = 1 //
// PD14[14] = 0 //
// PD[15-18]= X //
// PD19[19] = 0 //
// Everything Else = X //
//----------------------------------------------------------------------//

int i = getmem(PXA270_GPDR0);
i &= 0xFFF797FF;//0b111111111111 0 1111 00 1 0 11111111111 -- > Bit Mask, set pins (11,13,14,19) to zero
i |= 0x2000;//Set 11, 14, and 19 to 0 and 13 to 1
putmem(PXA270_GPDR0, i);

//---------------Direction Register 2---------------------------------------//
//Set GPIO75 as an output to be used as a chip select //
//--------------------------------------------------------------------------//
int gpdr2 = getmem(PXA270_GPDR2);
gpdr2 |= GPIO75; //Set GPIO 75 as an output
putmem(PXA270_GPDR2,gpdr2);
}

//**************************************************************************//
//ChipSelect - Select the chip
//select = 1, then the chip select is set to 0 volts
//select = 0, then the chip select is set to 3.3 volts
//**************************************************************************//
void ChipSelect(int fd, short select)
{
if(select){
init(fd,GPIO_BASE_OFFSET);
int gpcr2=getmem(PXA270_GPCR2);
//printf("CS ON\n");
putmem(PXA270_GPCR2,(gpcr2 |= (0x1 << 11)));
}else{
init(fd,GPIO_BASE_OFFSET);
int gpsr2=getmem(PXA270_GPSR2);
//printf("CS OFF\n");
putmem(PXA270_GPSR2,(gpsr2 |= (0x1 << 11)));
}

}

Retrieved from "http://docwiki.gumstix.org/index.php/Sample_code/C/SPI"

Category:
Programming

Views

Article

Discussion

View
source

History

Personal tools

Log
in / create account

Navigation

Main Page

Recent
changes

Random page

Help

resources

gumstix.com

Mailing list

FAQ

Search

Toolbox

What
links here

Related
changes

Upload file

Special
pages

Printable
version

Permanent
link

This page was last modified 07:24, 7 October 2008.

This page has been accessed 10,338 times.

Content is available under Attribution-ShareAlike 2.5.

Privacy
policy

About
GumstixDocsWiki

Disclaimers