Hi
I have been working on LPC2148 for a project. I have tried to get the spi0 working.
Currently the code compiles without a problem but is not responding as it is supposed to. I would like to know if there is any problem with the code in terms of SPI.
#include <lpc214x.h> //Includes LPC2148 register definitions
void spi_init(); void spi_send(char p); char spi_receive();
int main(void) { char p; int i=0; PINSEL0 = (1<<8)|(1<<10)|(1<<12)|(1<<14); // Enable UART1 Rx and Tx pins PINSEL1 = 0x00000000; PINSEL2 = 0x00000000; IO0DIR = (1<<14); IO0CLR |=(1<<14); IO1DIR = (1<<19) | (1<<18) | (1<<17) | (1<<16); spi_init();
while (1) { spi_send('0'); while(p!='0') { p=spi_receive(); }
spi_send('x'); while(p!='x') { p=spi_receive(); }
spi_send('f'); while(p!='f') { p=spi_receive(); }
spi_send('f'); while(p!='f') { p=spi_receive(); } i+=1; p='o'; switch(i%4) { case 1: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<19); break; case 2: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<18); break; case 3: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<17); break; case 0: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<16); break;
} } } void spi_init() { S0SPCR|=(1<<5); S0SPCCR=0x60;
} void spi_send(char p) { int value; value=(int)p; S0SPDR = value; while (!(S0SPSR & 0x80)); } char spi_receive() { char p; while (!(S0SPSR & 0x80)); p=(char)S0SPDR; return p; }
Thanks for the help!!
I apologize for the inconvenience...here is the code with comments:
The code sends a predefined data and on getting the same data back ,changes the state of its pins .LPC2148 acts as a master to a device which relays the same data sent to it.
#include <lpc214x.h> //Includes LPC2148 register definitions void spi_init(); //To define SPI void spi_send(char p); char spi_receive(); int main(void) { char p; int i=0; PINSEL0 = (1<<8)|(1<<10)|(1<<12)|(1<<14); // Enable MISO MOSI SCK and Slave Select PINSEL1 = 0x00000000; PINSEL2 = 0x00000000; IO0DIR = (1<<14); IO0CLR |=(1<<14); //Keep slave select as negetive always IO1DIR = (1<<19) | (1<<18) | (1<<17) | (1<<16); spi_init(); //Initialize spi while (1) { spi_send('0'); //Send a character and receive the same character while(p!='0') { p=spi_receive(); } spi_send('x'); while(p!='x') { p=spi_receive(); } spi_send('f'); while(p!='f') { p=spi_receive(); } spi_send('f'); while(p!='f') { p=spi_receive(); } i+=1; p='o'; switch(i%4) //change state of pin when the given configuration is sent { case 1: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<19); break; case 2: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<18); break; case 3: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<17); break; case 0: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<16); break; } } } void spi_init() { S0SPCR|=(1<<5); //Master mode S0SPCCR=0x60; //12500 Hz clock } void spi_send(char p) { int value; value=(int)p; S0SPDR = value; while (!(S0SPSR & 0x80)); //checks for data flag to go off } char spi_receive() { char p; while (!(S0SPSR & 0x80)); //waits till data is received. p=(char)S0SPDR; return p; }
---------------------------------- STARTUP CODE (startup_LPC17xx.s) ---------------------------------- Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main MOV R0,#0 MSR CONTROL, R0 LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP
---------------------------- EXECUTE USER CODE FUNCTION ---------------------------- void execUserCode( void ) { __disable_irq( ); SCB -> VTOR = ( USER_FLASH_START & 0x1FFFFF80 ); bootJump( USER_FLASH_START ); // User Flash start is the position of the vector table for the app }
----------------------------------- BOOT JUMP TO APPLICATION FUNCTION ----------------------------------- __asm void bootJump( U32 address ) { LDR SP, [R0] LDR PC, [R0, #4] }
Thank you for your answer
I use flash magic to program the MCU and load the value of the flash start and all...
I haven't used any of the above code for UART and it works.So I feel that is not the solution. Is there something else wrong with the code?or am i forgetting to initialize something important?
I have tried to loop back MOSI and MISO and test.
The code appears to be working sometimes based on the led signals... This is what I could infer:
1)code is sending a character 2)Code is receiving a character 3)The received character is not 0xff or the looped back character but something else.
Is there a specific clock i need to use for spi?I use 12Mhz and use 1/8 th for spi. Should I initialize anything for loopback or receive?
The datasheet says read the S0SPSR to clear register before receiving data...how do I do that?
Here is the code for your reference
#include <lpc214x.h> //Includes LPC2148 register definitions void spi_init(); //To define SPI void spi_send(char p); char spi_receive(); int main(void) { char p='l'; int i=0,j=0,k=0; for(j=0;j<12000;j++) { for(k=0;k<1000;k++); } PINSEL0 = (1<<8)|(1<<10)|(1<<12)|(1<<14); // Enable MISO MOSI SCK and Slave Select PINSEL1 = 0x00000000; PINSEL2 = 0x00000000; IO0DIR = (1<<14); IO0SET |=(1<<14); //Keep slave select as negetive always IO1DIR = (1<<19) | (1<<18) | (1<<17) | (1<<16); spi_init(); //Initialize spi while (1) { spi_send('0'); //Send a character and receive the same character while(p!='0') { p=spi_receive(); if(p==(char)0xff) { IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); //to check if no data is received without interrupt flag } } while(p=='0') { IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); //if data is received properly IO1SET=(1<<19)|(1<<17)|(1<<16); while(1); } } } void spi_init() { S0SPCR|=0x20; //Master Mode S0SPCCR=0x8; } void spi_send(char p) { IO0CLR |=(1<<14); S0SPDR = p; while ((!S0SPSR & 0x80)); S0SPSR &=~ 0x80; IO0SET |=(1<<14); } char spi_receive() { char p; IO0CLR |=(1<<14); S0SPDR=0xff; IO1SET=(1<<18)|(1<<17)|(1<<16); //to check if function is entered while ((!S0SPSR & 0x80)); p=S0SPDR; IO1SET=(1<<19)|(1<<17)|(1<<16); //to check if data is received return p; IO0SET |=(1<<14); }
Any help is gratefully appreciated.
Thank You