📄 lpc2000_spi.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 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; version 2 ** of the License. * ** 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. ** ** As a special exception, if other files instantiate templates or ** use macros or inline functions from this file, or you compile this ** file and link it with other works to produce a work based on this file, ** this file does not by itself cause the resulting work to be covered ** by the GNU General Public License. However the source code for this ** file must still be made available in accordance with section (3) of ** the GNU General Public License. ** ** This exception does not invalidate any other reasons why a work based ** on this file might be covered by the GNU General Public License. ** ** (c)2005 Martin Thomas *\*****************************************************************************//*****************************************************************************/#include "interfaces/lpc2000_spi.h"#include "interfaces/sd.h"#include "config.h"
#include "../app_config.h"
#define SD_SPI_WIDTH 8
/*****************************************************************************/#ifndef HW_ENDPOINT_LPC2000_SPINUM#error "HW_ENDPOINT_LPC2000_SPINUM has to be defined in config.h"#endif
#ifndef SD_SPI_CLK_DIV
#define SD_SPI_CLK_DIV 1
#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 1#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
//for LPC23xx
#define SPI_IODIR FIO0DIR#define SPI_SCK_PIN 15 /* Clock P0.17 out */#define SPI_MISO_PIN 17 /* from Card P0.18 in */#define SPI_MOSI_PIN 18 /* to Card P0.19 out *//* Card-Select P0.20 - GPIO out during startup Function 03 during normal operation */#define SPI_SS_PIN 16 #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 1/* 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"#endif
void SDSPIInit(void)
{
if_spiSetSpeed(SD_SPI_CLK_DIV);
}
esint8 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(SD_SPI_CLK_DIV); // 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 SSP/*static 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){
unsigned char i;
unsigned short buf[20];
SPIMasterEnable(SD_SPI,SPI_RIS_FIRST,SPI_SAM_FIRST,250,0,0,SD_SPI_WIDTH - 1);
for (i=0;i<20;i++)
buf[i] = 0xFFFF;
Setb(SD_CS_PRTS,SD_CS_PIN);
Orb(SD_CS_DPRT,SD_CS_PIN); //set SD_CS pin as output
SPIMasterTransfer(SD_SPI,20,buf);
}/*****************************************************************************/void if_spiSetSpeed(euint8 speed){ SPIMasterEnable(SD_SPI,SPI_RIS_FIRST,SPI_SAM_FIRST,speed,0,0,SD_SPI_WIDTH - 1);}/*****************************************************************************/euint8 if_spiSend(hwInterface *iface, euint8 outgoing){ unsigned char buf[1];
buf[0] = outgoing;
Clrb(SD_CS_PRTC,SD_CS_PIN);
SPIMasterTransfer2(SD_SPI,1,buf);
Setb(SD_CS_PRTS,SD_CS_PIN);
return (buf[0]);
}/*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -