This is the driver of my filesystem. It is working
I hope that you understand my 'spanglish'
regards
Angel Sanchez
//********************************************************************
*****
// AUMAT SL
// Libreria de Utilidades
// (c) 2005
/** @file
@brief Control de Dispositivo: Atmel DataFlash
AT45xxx \n
Interfase SCI
@version 1.0
@date Marzo-2005
@author Angel Sanchez Pelegrin
@bug
@warning
@todo
Este modulo se debera de implemantar en funcion del Hardware
especifico.
Debe suministar las siguientes funciones:
- _spiWriteControl
- _spiWriteData
- _spiReadData
- _spiBusyDelay
- _spiInit
Se incluye a traves de un '#include' en el fichero \a FsDcbAT45.c por
lo que
las funciones tienen el atributo \a static.
APORTA ACCESO SPI A TRAVES DE CONTROLADOR SPI PHILIPS LPC210x
UN SOLO DISPOSITIVO
Notas de Implantacion:
El CS se efectua mediante una linea de I/O
La linea SEL0 (SEL1) debe estar unida a Vcc
*/
#include "Hard.h"
//*** Declaraciones
*********************************************************
// #define SPI_MODE1
///< Modo SPI usado
//*** Variables Locales
*****************************************************
//********************************************************************
******
/** @brief Seleciona dispositivo
// @param dcbPtr Ptr a informacion DCB especifica de AT45
Actua sobre la linea CS del dispositivo para permitir acceso al mismo
**********************************************************************
****/
static void _spiSelect (FsDcb *dcbPtr)
{
if (((DcbEspAT45*)dcbPtr->devEsp)->cs == 0)
IO0CLR = SPISEL0;
else
IO0CLR = SPISEL1;
}
//********************************************************************
******
/** @brief Deseleciona dispositivo
// @param dcbPtr Ptr a informacion DCB especifica de AT45
Actua sobre la linea CS del dispositivo para impedir acceso al mismo
**********************************************************************
****/
static void _spiDeselect (FsDcb *dcbPtr)
{
if (((DcbEspAT45*)dcbPtr->devEsp)->cs == 0)
IO0SET = SPISEL0;
else
IO0SET = SPISEL1;
}
//********************************************************************
******
/** @brief Obten un Byte del dispositivo
@return Byte obtenido
El dispositivo se supone seleccionado, y al salir, lo deja
seleccionado
**********************************************************************
****/
static Uint8 _getByte (void)
{
Uint8 dummy, data;
S0SPDR = 0;
// Genera Clock
while ((S0SPSR & 0x80) == 0) ; // Espera dato
data = S0SPDR;
dummy = S0SPSR;
// Borra flag
return data;
}
//********************************************************************
******
/** @brief Envia un Byte al dispositivo
@param data Byte a enviar
El dispositivo se supone seleccionado, y al salir, lo deja
seleccionado
**********************************************************************
****/
static void _putByte (Uint8 data)
{
Uint8 dummy;
S0SPDR = data;
// Envia Byte
while ((S0SPSR & 0x80) == 0) ; // Espera a
enviado
dummy = S0SPSR;
// Borra flag
}
//********************************************************************
******
/** @brief Escribe control
@param dcbPtr Ptr a informacion DCB especifica de AT45
@param data Ptr a informacion de control
@param len Longitud de los datos
Inicio de dialogo con Dispositivo:
- Selecciona
- Envia buffer Byte a Byte
**********************************************************************
****/
static void _spiWriteControl (FsDcb *dcbPtr, Uint8 *data, Uint16 len)
{
_spiSelect (dcbPtr);
while (len--)
_putByte (*data++);
}
//********************************************************************
******
/** @brief Escribe datos
@param dcbPtr Ptr a informacion DCB especifica de AT45
@param data Ptr a datos a enviar
@param len Longitud de los datos
Envio de paquete de datos al dispositivo. Efectua:
- Envio de buffer Byte a Byte
- Deselecciona
**********************************************************************
****/
static void _spiWriteData (FsDcb *dcbPtr, Uint8 *data, Uint16 len)
{
while (len--)
_putByte (*data++);
_spiDeselect (dcbPtr);
}
//********************************************************************
******
/** @brief Lee datos
@param dcbPtr Ptr a informacion DCB especifica de AT45
@param data Ptr a buffer de deposito
@param len Longitud de los datos
Obtencion de paquete de datos del dispositivo. Efectua:
- Obtencion datos con tamanno especificado
- Deselecciona
**********************************************************************
****/
static void _spiReadData (FsDcb *dcbPtr, Uint8 *data, Uint16 len)
{
while (len--)
*data++ = _getByte ();
_spiDeselect (dcbPtr);
}
//********************************************************************
******
/** @brief Obten registro Status
@param dcbPtr Ptr a informacion DCB especifica de AT45
**********************************************************************
****/
static Uint8 _spiGetStatus (FsDcb *dcbPtr)
{
Uint8 status;
_spiSelect (dcbPtr);
_putByte (STATUS_COMMAND); //
Solicita Status
status = _getByte (); //
Obten resultado
_spiDeselect (dcbPtr);
return status;
}
//********************************************************************
******
/** @brief Espera fin de operacion
@param dcbPtr Ptr a informacion DCB especifica de AT45
Empleada para detectar fin de ejecucion de operacion en dispositivo.
Efectua:
- Ejecuta un ligero retaro, con el fin de no bloquear el
sistema
- Obten status
- Repite las anteriores mientras el flag de BUSY siga activo
**********************************************************************
****/
static void _spiBusyDelay (FsDcb *dcbPtr)
{
Uint8 status;
do {
// NutSleep (5);
// Cede control a otros threads
_spiSelect (dcbPtr);
_putByte (STATUS_COMMAND);
// Solicita Status
status = _getByte ();
// Obten resultado
_spiDeselect (dcbPtr);
} while ((status & FLASH_BUSY) == 0); // Espara a no-Busy
}
//********************************************************************
******
/** @brief Inicializa interfase
@param dcbPtr Ptr a informacion DCB especifica de AT45
Inicializacion Hardware del Interfase SCI
**********************************************************************
****/
static void _spiInit (FsDcb *dcbPtr)
{
PINSEL0 = (PINSEL0 & ~0x0000ff00) | 0x00005500; //
Control por SPI
IO0DIR |= (SPISEL0|SPISEL1);
// Lineas a salida
IO0SET = SPISEL0|SPISEL1;
// Disable
S0SPCCR = 8;
S0SPCR = 0x20;
}
--- In lpc2000@yahoogroups.com, "slavidian" <slavidian@y...> wrote:
> Hello,
>
> I have created a simple driver to read the status register of an
SPI
> EEPROM using the LPC2106 as master. I posted the short code
below.
> MOSI and SCK signals appear on the scope, but nothing comes out of
> the slave MISO port on the EEPROM (Status Register contents should
be
> seen). SSEL is pulled up with a 10k resistor and is attached to
> nothing. Instead GPIO simulates the chip select as recommended on
> this forum (not in the errata). I have tried different EEPROMs and
> configured SPCR accordingly, so this is not the problem. Either
the
> signals coming from the lpc2106 are garbage or I am missing
something.
>
> Please help!
>
>
>
> #define SPIF_DONE 0x80
>
> void main (void)
> {
> char i;
>
> VPBDIV=0x1; //pclk = cclk (14.7456 mhz)
>
> PINSEL0 = 0x00005500; //Enable SPI pins
> IODIR = 0x00000400; //Configure P0.10 as output
> IOSET = 0x00000400; //P0.10 high (substitute for SSEL)
> SPCCR = 0x000000FE; //divider = 254; must be
multiple of 2
> SPCR = 0x00000020; //SPI Master; Mode 0,0 (chpa,
cpol)
>
> IOCLR = 0x00000400; //Enable Chipselect
> asm("NOP"); //Give GPIO time
> SPDR = 0x00000005; //Send ReadStatusRegister
commandShow quoted textHide quoted text
> while(!(SPSR & SPIF_DONE)); //Poll until send/recv complete
> IOSET = 0x00000400; //Disable Chipselect
> i = SPDR; //Read the Stat Reg transfered in
> Write(i); //Display Stat Reg contents
> }