⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpc2000_spi.c

📁 Philips LPC2138 Demo Application with Keil C
💻 C
字号:
/*****************************************************************************\*              efs - General purpose Embedded Filesystem library              **          --------------------- -----------------------------------          **                                                                             ** Filename : lpc2000_spi.c                                                     ** Description : This file contains the functions needed to use efs for        **               accessing files on an SD-card connected to an LPC2xxx.        **                                                                             ** This library is free software; you can redistribute it and/or               ** modify it under the terms of the GNU Lesser General Public                  ** License as published by the Free Software Foundation; either                ** version 2.1 of the License, or (at your option) any later version.          **                                                                             ** This library 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           ** Lesser General Public License for more details.                             **                                                                             **                                                    (c)2005 Martin Thomas    **                                                                             *\*****************************************************************************//*****************************************************************************/#include "LPC2000_regs.h"#include "lpc2000_spi.h"#include "sd.h"#include "config.h"/*****************************************************************************/#ifndef HW_ENDPOINT_LPC2000_SPINUM#error "HW_ENDPOINT_LPC2000_SPINUM has to be defined in config.h"#endif#if ( HW_ENDPOINT_LPC2000_SPINUM == 0 )// LPC213x ### SPI0 ###// SP0SPCR  Bit-Definitions#define CPHA    3#define CPOL    4#define MSTR    5// SP0SPSR  Bit-Definitions#define SPIF	7#define SPI_IODIR      IODIR0#define SPI_SCK_PIN    4   /* Clock       P0.4  out */#define SPI_MISO_PIN   5   /* from Card   P0.5  in  */#define SPI_MOSI_PIN   6   /* to Card     P0.6  out */#define SPI_SS_PIN	   7   /* Card-Select P0.7 - GPIO out */#define SPI_PINSEL     	  PINSEL0#define SPI_SCK_FUNCBIT   8#define SPI_MISO_FUNCBIT  10#define SPI_MOSI_FUNCBIT  12#define SPI_SS_FUNCBIT    14#define SPI_PRESCALE_REG  S0SPCCR#define SPI_PRESCALE_MIN  8#define SELECT_CARD()   IOCLR0 = (1<<SPI_SS_PIN)#define UNSELECT_CARD()	IOSET0 = (1<<SPI_SS_PIN)#elif ( HW_ENDPOINT_LPC2000_SPINUM == 1 )// LPC213x ### SSP ### ("SPI1")// SSPCR0  Bit-Definitions#define CPOL    6#define CPHA    7// SSPCR1  Bit-Defintions#define SSE     1#define MS      2#define SCR     8// SSPSR  Bit-Definitions#define TNF     1#define RNE     2#define BSY		4#define SPI_IODIR      IODIR0#define SPI_SCK_PIN    17   /* Clock       P0.17  out */#define SPI_MISO_PIN   18   /* from Card   P0.18  in  */#define SPI_MOSI_PIN   19   /* to Card     P0.19  out *//* Card-Select P0.20 - GPIO out during startup   Function 03 during normal operation */#define SPI_SS_PIN	   20   #define SPI_PINSEL     PINSEL1#define SPI_SCK_FUNCBIT   2#define SPI_MISO_FUNCBIT  4#define SPI_MOSI_FUNCBIT  6#define SPI_SS_FUNCBIT    8#define SPI_PRESCALE_REG  SSPCPSR/// TODO: too fast on prototyp wires #define SPI_PRESCALE_MIN  2#define SPI_PRESCALE_MIN  4/* only needed during init: */#define SELECT_CARD()   IOCLR0 = (1<<SPI_SS_PIN)#define UNSELECT_CARD()	IOSET0 = (1<<SPI_SS_PIN)#else#error "Invalid Interface-Number"#endifesint8 if_initInterface(hwInterface* file, eint8* opts){	euint32 sc;		if_spiInit(file); /* init at low speed */		if(sd_Init(file)<0)	{		DBG((TXT("Card failed to init, breaking up...\n")));		return(-1);	}	if(sd_State(file)<0){		DBG((TXT("Card didn't return the ready state, breaking up...\n")));		return(-2);	}		// file->sectorCount=4; /* FIXME ASAP!! */		sd_getDriveSize(file, &sc);	file->sectorCount = sc/512;	if( (sc%512) != 0) {		file->sectorCount--;	}	DBG((TXT("Drive Size is %lu Bytes (%lu Sectors)\n"), sc, file->sectorCount));		 /* increase speed after init */#if ( HW_ENDPOINT_LPC2000_SPINUM == 1 )	SSPCR0 = ((8-1)<<0) | (0<<CPOL);#endif	if_spiSetSpeed(SPI_PRESCALE_MIN);	// if_spiSetSpeed(100); /* debug - slower */		DBG((TXT("Init done...\n")));	return(0);}/*****************************************************************************/ esint8 if_readBuf(hwInterface* file,euint32 address,euint8* buf){	return(sd_readSector(file,address,buf,512));}/*****************************************************************************/esint8 if_writeBuf(hwInterface* file,euint32 address,euint8* buf){	return(sd_writeSector(file,address, buf));}/*****************************************************************************/ esint8 if_setPos(hwInterface* file,euint32 address){	return(0);}/*****************************************************************************/ // Utility-functions which does not toogle CS.// Only needed during card-init. During init// the automatic chip-select is disabled for SSPstatic euint8 my_if_spiSend(hwInterface *iface, euint8 outgoing){	euint8 incoming;	// SELECT_CARD(); // not here!	#if ( HW_ENDPOINT_LPC2000_SPINUM == 0 )	S0SPDR = outgoing;	while( !(S0SPSR & (1<<SPIF)) ) ;	incoming = S0SPDR;#endif#if ( HW_ENDPOINT_LPC2000_SPINUM == 1 )	while( !(SSPSR & (1<<TNF)) ) ;	SSPDR = outgoing;	while( !(SSPSR & (1<<RNE)) ) ;	incoming = SSPDR;#endif	// UNSELECT_CARD(); // not here!	return(incoming);}/*****************************************************************************/ void if_spiInit(hwInterface *iface){	euint8 i; 	// setup GPIO	SPI_IODIR |= (1<<SPI_SCK_PIN)|(1<<SPI_MOSI_PIN)|(1<<SPI_SS_PIN);	SPI_IODIR &= ~(1<<SPI_MISO_PIN);		// set Chip-Select high - unselect card	UNSELECT_CARD();	// reset Pin-Functions		SPI_PINSEL &= ~( (3<<SPI_SCK_FUNCBIT) | (3<<SPI_MISO_FUNCBIT) |		(3<<SPI_MOSI_FUNCBIT) | (3<<SPI_SS_FUNCBIT) );#if ( HW_ENDPOINT_LPC2000_SPINUM == 0 )	DBG((TXT("spiInit for SPI(0)\n")));	SPI_PINSEL |= ( (1<<SPI_SCK_FUNCBIT) | (1<<SPI_MISO_FUNCBIT) |		(1<<SPI_MOSI_FUNCBIT) );	// enable SPI-Master	S0SPCR = (1<<MSTR)|(0<<CPOL); // TODO: check CPOL#endif#if ( HW_ENDPOINT_LPC2000_SPINUM == 1 )	DBG((TXT("spiInit for SSP/SPI1\n")));	// setup Pin-Functions - keep automatic CS disabled during init	SPI_PINSEL |= ( (2<<SPI_SCK_FUNCBIT) | (2<<SPI_MISO_FUNCBIT) |		(2<<SPI_MOSI_FUNCBIT) | (0<<SPI_SS_FUNCBIT) );	// enable SPI-Master - slowest speed	SSPCR0 = ((8-1)<<0) | (0<<CPOL) | (0x20<<SCR); //  (0xff<<SCR);	SSPCR1 = (1<<SSE);#endif		// low speed during init	if_spiSetSpeed(254); 	/* Send 20 spi commands with card not selected */	for(i=0;i<21;i++)		my_if_spiSend(iface,0xff);#if ( HW_ENDPOINT_LPC2000_SPINUM == 0 )	// SPI0 does not offer automatic CS for slaves on LPC2138 	// ( the SSEL-Pin is input-only )	// SELECT_CARD();#endif#if ( HW_ENDPOINT_LPC2000_SPINUM == 1 )	// enable automatic slave CS for SSP	SSPCR1 &= ~(1<<SSE); // disable interface	SPI_PINSEL |= ( (2<<SPI_SCK_FUNCBIT) | (2<<SPI_MISO_FUNCBIT) |		(2<<SPI_MOSI_FUNCBIT) | (2<<SPI_SS_FUNCBIT) );	SSPCR1 |= (1<<SSE); // enable interface#endif	}/*****************************************************************************/void if_spiSetSpeed(euint8 speed){	speed &= 0xFE;	if ( speed < SPI_PRESCALE_MIN  ) speed = SPI_PRESCALE_MIN ;	SPI_PRESCALE_REG = speed;}/*****************************************************************************/euint8 if_spiSend(hwInterface *iface, euint8 outgoing){	euint8 incoming;#if ( HW_ENDPOINT_LPC2000_SPINUM == 0 )	SELECT_CARD();	S0SPDR = outgoing;	while( !(S0SPSR & (1<<SPIF)) ) ;	incoming = S0SPDR;	UNSELECT_CARD();#endif#if ( HW_ENDPOINT_LPC2000_SPINUM == 1 )	// SELECT_CARD();  // done by hardware	while( !(SSPSR & (1<<TNF)) ) ;	SSPDR = outgoing;	while( !(SSPSR & (1<<RNE)) ) ;	incoming = SSPDR;	// UNSELECT_CARD();  // done by hardware#endif		return(incoming);}/*****************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -