Hello!
I hope someone can help me with this issue since it is frustrating me for 1 week counting.
My goal is to establish a working communication between the MSP430 and 2 SPI slaves.
One slave is the DS1390 RTC which needs SPI Mode 1 or 3 ( CPOL don't care CPHA =1), the other is the A25L080O Flash which need SPI Mode 0 or 3 ( CPOL = CPHA either 0 or 1 ) so CPOL =CPHA =1 was the obvious choice for both.
I startet working with the RTC first and after setting the clock to certain values the read gave me erratic Data back. After starting contact with Tech Support I switched focus to the Flash (contact between Europe and USA is like 1 mail a Day) I encountered similar erratic Data. After some analysis I am up to the point were it seems like the whole SOMI line is 1 clock to late. Shifting everything 1 spot to the left gives me Data which suddenly gives me the correct expected Data.
So my conclusion to this point is: SIMO works correct since the slaves do what they are supposed to do. SOMI is 1 CLK off. For both devices.
Here is my code (sorry for the german names of variables and comments)
void SPI_init(void) //Funktion zur Initialisierung der SPI Schnittstelle { //CS leitungen für RTC Flash P2OUT |= (1<<7); //RTC P2OUT |= (1<<6); //FLASH UCB0CTL1 |= UCSWRST; //SPI - Schnittstelle anhalten (nötig für das Konfigurieren) P3SEL |= BIT1 + BIT2 + BIT3; //CLK, MOSI und MISO für UCB0 an Port 3 //SPI - Modus einstellen //UCSYNC = Synchronmodus ; UCMST = Mastermode ; UCMODE_0 = 3-pin SPI ; UCCKPH = Clockphase 1 ; UCCKPL = Clockpolarität 1 ; UCMSB = MSB zuerst ; UC7BIT = 7-bit Character UCB0CTL0 |= UCSYNC + UCMST + UCMODE_0 + UCCKPH + UCCKPL + UCMSB; //UCCKPL eingefügt. Flash benötigt CKPH und CKPL identisch (0 oder 1) ; RTC benötigt CKPH=1 während CKPL variabel ist; 10.3.2017 UCB0CTL1 |= UCSSEL_1; //Taktquelle einstellen 0 = keine ; 1 = ACLK ; 2 = SMCLK ; 3 = SMCLK //Teiler für den Takt einstellen UCB0BR0 = 0x08; // Teiler 8 UCB0BR1 = 0x00; //erweiterter Teiler (*256) UCB0CTL1 &= ~UCSWRST; //Schnittstellenhardware einschalten IE2 |= UCB0RXIE ; //USCIB0 Empfangs Interrupt Enable }
void SPI_send_byte(unsigned char DATA[]) { letztes_byte=0; // variable checking for last byte to send unsigned int i; CHIP_SELECT_RTC_ON; for(i=0;i<Anzahl_Bytes;i++) { transmit_ch=DATA[i]; if(i == Anzahl_Bytes-1) // last byte? letztes_byte = 1; IE2 |= UCB0TXIE; // enable transmit interrupt ---> jumps into transmit ISR if(i>=1) //coming out of receiving ISR Zeit[i-1]=(received_ch); //write received byte into array } }
and the transmit and receving ISR
#pragma vector = USCIAB0TX_VECTOR //Pragma-Anweisung für die USCIB0-Sende ISR __interrupt void USCIB0TX_ISR(void) //USCIB0-Sende ISR { UCB0TXBUF=transmit_ch; //Übergabe des Sendebyte an den Sendepuffer while(UCB0STAT & UCBUSY); //had to implement this wait or the msp would go ahaed wouldn't wait for the SPI to transmit and receive IE2 &= ~ UCB0TXIE; //Löschen des Interrupt Enable Bits }
#pragma vector = USCIAB0RX_VECTOR //Pragma-Anweisung für die USCIB0-Empfangs ISR __interrupt void USCIB0RX_ISR(void) //USCIB0-Empfangs ISR { received_ch=UCB0RXBUF; //Auslesen des Empfangspuffers if(letztes_byte == 1) P2OUT |= (1<<7); }
this is the version for only communicating with the RTC.
I hope I didn't mess up something with the ISR to cause the mess I am into or miss something in the SPI setup.
I controlled everything with a logic analyzer and all the timing of CS , CLK and SIMO are fine. Even the timing on SOMI looks fine only issue is the shift to the right which is occurring on both devices which makes me think it is an SPI issue.
For the Flash I tried the other configuration of CPOL = CPHA = 0 , but in this case the SIMO was off one bit late ?!?