Sample code/C/SPI

From GumstixDocsWiki

Jump to: navigation, search

Contents

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 - kumpf@mit.edu (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)));
	}
	
}
Personal tools