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.

MSP430F5438 RTC Write Problem: Data is not changed properly

Other Parts Discussed in Thread: MSP430F5438

Hi,  we are setting the RTC to synch with the date of a PC. We get the correct serial data from the computer on the UART port and then convert the data to BCD to store the time. Somehow , even though we are changing the register with the correct value, the registry does not store the correct day.

 

For example, if I put 0x23 on the RTCDAY register value will be changed to 0x22. This would happen to me with the RTCHOUR register but somehow setting the RTCM0 and RTCM1 got it fixed.

 

This is the snippet of code that takes the received data and stores on the register.

 

void update_time(){
  
  char time_updating[]="Updating Time";
  ClearDisplay();
 
  writeToPos(0x04, time_updating);
    
  char rtc_registers[7] = { 0 };
 
  /*CALL THE FUNCTION AT CONTROL.H*/
  update_time_from_PC( rtc_registers, 7 );
 
  unsigned char year_low = rtc_registers[0];
  unsigned char month = rtc_registers[1];
  unsigned char day = rtc_registers[2];
  unsigned char dow = rtc_registers[3];
  unsigned char hour = rtc_registers[4];
  unsigned char min = rtc_registers[5];
  unsigned char sec = rtc_registers[6];
 
  RTCCTL01|=RTCHOLD+RTCBCD+RTCMODE+RTCTEVIE;
 
  RTCTIM0=0x0000;
  RTCTIM1=0x0000;
  RTCDATE=0x0000;
  RTCYEAR = 0x0000;
  RTCMON = 0x00;
  RTCDAY = 0x00;
  RTCDOW = 0x00;
  RTCHOUR = 0x00;
  RTCMIN = 0x00;
  RTCSEC = 0x00;
 
 
 
  year_low = bcd(year_low);
 
 
  RTCYEAR = 0x2000+year_low;
 
  month = bcd(month);
  RTCMON = month ;
 
 
  day = bcd(day);
  RTCDAY =  day ;
 
  dow = bcd(dow);
  RTCDOW = dow;
 
 
 
 
  hour = bcd(hour);
  RTCHOUR = hour ;
 
  min = bcd(min);
  RTCMIN = min;
 
  sec = bcd(sec);
  RTCSEC = sec;
 
  RTCCTL01&=~RTCHOLD;
}

 

I tried clearing all the values before storing them but still it doesn't work.

Thanks for your help.

 

 

 

 

  • I don't know exactly what's going on, but I'd check the values you set to RTCCTL01.
    The datasheet lists both registers separately as RTCCTL0 and RTCCTL1. So it might be possible that you're assigning the wrong constants to the combined register.
    Check RTCBCD: is it 0x80 or 0x8000? If it is the first, then it is meant for use with 8-bit RTCCTL1 register instead of teh 16 bit RTCCTL01 register,. same for the other bits.
    I can't compare for you, since I wrote my header file smayself based on the users guide, when there were none for the mspgcc compiler.

    Also, after setting RTCBCD, most time registers are automatically cleared to 0 (except for the month, which is set to 1), so there is no need to set them manually. Setting RTCMON (and RTCDAY) to 0, however, is an invalid operation and may cause erratic behavior of the RTC. These values are 1-based.

    One question: why do you use BCD mode at all? In most cases, you'll need the full numerical value and not single digits of the time/date. So you can skip the BCD conversion, leave the RTC in hexadecimal mode and just be happy.

  • I've also ran into a similar problem.

    I'm writing code for MSP430F5438 using CCS 5

    This is my code (similar code to msp430x54xA_RTC_02.c example in slac375a.zip):

    #include <msp430x54x.h>

    void main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop Watchdog Timer
      P1DIR |= BIT0;                            // Set P1.0 as output

      // Initialize LFXT1
      P7SEL |= 0x03;                            // Select XT1
      UCSCTL6 &= ~(XT1OFF);                     // XT1 On
      UCSCTL6 |= XCAP_3;                        // Internal load cap

      // Loop until XT1,XT2 & DCO fault flag is cleared
      do
      {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
                                                // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                      // Clear fault flags
      }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag

      // Configure RTC_A
      RTCCTL01 |= RTCTEVIE + RTCRDYIE + RTCHOLD + RTCMODE;
                                                // RTC enable, RTC hold
                                                // enable RTC read ready interrupt
                                                // enable RTC time event interrupt

      RTCYEAR = 2010;
      RTCMON = 4;
      RTCDAY = 05;
      RTCDOW = 01;
      RTCHOUR = 10;
      RTCMIN = 32;
      RTCSEC = 5; // this changes RTCHOUR

      RTCCTL01 &= ~(RTCHOLD);

    }

    I step through the code while looking at the RTC registers in the memory browser and I see that when the RTCSEC=5 is executed the RTCHOUR is set to 0

    (In my real code is is set to 33!)

    If I change the order of the assignments and set RTCHOUR after setting RTCMIN&RTCSEC it seems to work OK, but it's not very confidence inspiring when the example code from TI have strange problems like this... At the very least the documentation should warn about the order of assignments to the RTC registers.

     

     

  • No, I was wrong, it does not work.

    When I change the order to set RTCHOUR after RTCSEC then setting RTCSEC puts garbage in RTCYEAR.

    What the HELL is going on here?

    Nadav

  • Nadav Popplewell said:
    What the HELL is going on here?

    See the 54xx device errata sheet. On teh 54xx (non-A model), the RTC requires "carefully aligned code" to allow proper writes.
    The available RTC library takes care of this. If you don't follow the procedure strictly, writes to one register will alter the contents of others.
    THis is because all registers of the RTC are always 'active' and 'counting' even if this counting causes no actual change. CPU writes interfere with this internal updates, causing address or data bus collisions.

    It's similar to the problem of missing port interrupts, if an interrupt appears while the CPU is accessing the ports IFG register. THen the hardware cannot update the IFG register and set the flag for the new interrupt.
    The RTC with its continuous internal register updates faces a similar problem.

  • Hi Jens-Michael,

    Thanks for your reply,

    I've read the errata document and it says that you need to get RTC_Workaround.zip from the Code Examples page in www.ti.com/msp430, but I can't find it.

    There is a link to a Real-Time-Clock Libary but clicking on it results in an error page:

    Sorry! We couldn't find your page.

    Do you know where I can find this code?

    Thanks,

    Nadav

  • Nadav Popplewell said:
    Do you know where I can find this code?

    On my HD :)
    No, seriosly, the code has been moved into the 54xx code examples zip file. And this zip file has been updated and changed its name. Maybe in teh errata document there is the old name.

    Search for slac166p.zip (If 'p' is the latest version. It's the latest I have.)

    I really hate TI's eway to do handle document revisions. It should work the 'linux' way: the most recent version is available through the generic name, while theis and all previous versions are available through their 'versioned' names too.

    But on Ti website, the old revisions are removed and the current one is only accessible through its 'versioned' name, breaking many links here and there when a new version comes out.

**Attention** This is a public forum