Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: SPI Issue

2005-07-15 by Angel Sanchez

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 
command
>   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
> }

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.