We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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!!
Doesn't look readable.
You forgot to tag it as code.
You forgot to use comments, to actually document your code. Magic constants doesn't help you.
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