This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTC doen't work

Other Parts Discussed in Thread: MSP430F2274

I'm trying to control a RTC M41T94 via SPI with a MSP430F2274 microcontroller, but I cannot set the internal registers of this component. I've made a more complete code, but, for testing, I'm using the code below:

#include "msp430f2274.h"

void Iniciar();
void SetRTC(char byte, int endereco);
char GetRTC(int endereco);


void main(){
WDTCTL = WDTPW + WDTHOLD;
unsigned char valor = 0;
P1DIR = 0x30; //LEDs
P1OUT = 0x30;

Iniciar();

__delay_cycles(250);
SetRTC(0x11,0x09);

while(1){
__delay_cycles(250);
valor = GetRTC(0x09);
}

}

void Iniciar(){
P4SEL &= ~(0x02);
P4OUT |= 0x02;//Seta o SS de forma que passe a estar em low.
P4DIR |= 0x02;

UCB0CTL1 |= UCSWRST; //Desativa SPI
UCB0CTL0 = UCCKPL + UCMSB + UCMST + UCSYNC + UCMODE_0; //sincronizado, master mode, MSB como primeiro bit

UCB0CTL1 = UCSWRST + UCSSEL_2; // Use SMCLK, keep RESET
UCB0BR0 = 0x03; // Initial SPI clock must be <400kHz
UCB0BR1 = 0x00; // f_UCxCLK = 1MHz/3 = 333kHz

P3SEL |= 0x0E;//sel clk, somi, simo
P3DIR |= 0x0A;//dir clk, simo
P3REN |= 0x04;//ren somi
P3OUT |= 0x04;//out somi

UC0IFG &= ~UCB0RXIFG;
UC0IE |= UCB0TXIE+UCB0RXIE;
UCB0CTL1 &= ~UCSWRST; //Reativa SPI
}

void SetRTC(char byte, int endereco){
int gie = __get_SR_register() & GIE; //backup das interrupções atuais

__disable_interrupt();

P4OUT &= ~(0x02);//Habilita o CS

while (!(UC0IFG & UCB0TXIFG)); //delay pro TX ficar operacional
UCB0TXBUF = endereco; //Transferência do byte inicial

while (!(UC0IFG & UCB0TXIFG)); //delay pro TX ficar operacional
UCB0TXBUF = byte; //Transferência do byte

while (UCB0STAT & UCBUSY);

P4OUT |= 0x02;//desabilita o CS

__bis_SR_register(gie); //recover das interrupções
}

char GetRTC(int endereco){
char retorno;
int gie = __get_SR_register() & GIE;

__disable_interrupt();
P4OUT &= ~(0x02);//Habilita o CS

while (!(IFG2 & UCB0TXIFG));
UCB0TXBUF = (0x80 | endereco);//Para o MSB ser 1, ou seja, para a operação ser de leitura

UC0IFG &= ~UCB0RXIFG; //certeza de que o buffer de recebimento está limpo
while (!(IFG2 & UCB0RXIFG));
retorno = UCB0RXBUF;

while (UCB0STAT & UCBUSY);

P4OUT |= 0x02;//desabilita o CS

__bis_SR_register(gie); // Restore original GIE state

return retorno;
}

In my IAR workbench, there is a breakpoint in the "__delay_cycles" inside the "while". When I use the "Locals" window to watch the "valor" variable, it seems to be always 0x00 or 0xFF, never 0x11. I flash the LEDs because sometimes is hard to fix bad connections in the USB development stick. It's possible that the problem is in hardware, not in software, but I want to be sure about the software before trying something in the board.

Thank you

  • GetRTC() is fetching the Rx data too early, and it isn't running the SPI to fetch the second byte. The simplest fix for this is to insert a UCBUSY wait before clearing UCB0RXIFG, and then feeding the SPI a dummy byte:

    UCB0TXBUF = (0x80 | endereco);//Para o MSB ser 1, ou seja, para a operação ser de leitura
    while (UCB0STAT & UCBUSY)/*EMPTY*/;  // Allow the Tx byte to complete

    UC0IFG &= ~UCB0RXIFG; //certeza de que o buffer de recebimento está limpo

    UCB0TXBUF = 0xFF;                                      // Dummy Tx byte to run the clock

    ------

    Unsolicited:

    UC0IE |= UCB0TXIE+UCB0RXIE;

    This enables the Tx and Rx interrupts,  but I don't see an ISR for either. This hasn't caused you trouble yet since your entire program runs with interrupts disabled, but as soon as you enable interrupts you'll have trouble. My experience is that using interrupts for an SPI master is rarely useful, since most SPI slaves are pretty fast.

  • There may be other error in code? It's still not working

  • Bruce McKenney47378 said:
    My experience is that using interrupts for an SPI master is rarely useful, since most SPI slaves are pretty fast.

    If you already have to wait for the result of the operation (and in most cases you will), using interrupts makes no sense at all, no matter with which module.
    But if your application allows a background transfer, and the baudrate is rather slow, then it might be useful. Personally, I’d go for a DMA transfer then, if the number of bytes is known. (Mainly used for the 512 byte sector transfer from and to SD card)

  • Does anybody know if there is other error in the code?

  • Some months ago the RTC has begun to work. I'm sorry, I forgot to post that. Before, when I was writing in the RTC's registers, I've used 0x00 as header in SPI writing and when reading I've used 0x80. So I sent (0x00 | register address) and after the data for writing and (0x80 | register address) and after the data for reading. This RTC, differently from other SPI devices I used, requires 0x00 as the header of reading and 0x80 as the header of writing. Thanks everybody

**Attention** This is a public forum