Skip to content

Commit

Permalink
Fixed RTC on non-uno boards, second try. Cannot work when there is no…
Browse files Browse the repository at this point in the history
… xtal.
  • Loading branch information
robbederks committed Oct 31, 2019
1 parent 933c757 commit 606f1d9
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 59 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.5.8
v1.5.9
8 changes: 8 additions & 0 deletions board/board_declarations.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,11 @@ struct board {

// ********************* Globals **********************
uint8_t usb_power_mode = USB_POWER_NONE;

// ************ Board function prototypes *************
bool board_has_gps(void);
bool board_has_gmlan(void);
bool board_has_obd(void);
bool board_has_lin(void);
bool board_has_rtc(void);
bool board_has_relay(void);
3 changes: 3 additions & 0 deletions board/boards/uno.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ void uno_init(void) {
// Initialize harness
harness_init();

// Initialize RTC
rtc_init();

// Enable CAN transcievers
uno_enable_can_transcievers(true);

Expand Down
116 changes: 61 additions & 55 deletions board/drivers/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,72 +22,78 @@ uint16_t from_bcd(uint8_t value){
}

void rtc_init(void){
// Initialize RTC module and clock if not done already.
if((RCC->BDCR & RCC_BDCR_MASK) != RCC_BDCR_OPTIONS){
puts("Initializing RTC\n");
// Reset backup domain
RCC->BDCR |= RCC_BDCR_BDRST;
if(board_has_rtc()){
// Initialize RTC module and clock if not done already.
if((RCC->BDCR & RCC_BDCR_MASK) != RCC_BDCR_OPTIONS){
puts("Initializing RTC\n");
// Reset backup domain
RCC->BDCR |= RCC_BDCR_BDRST;

// Disable write protection
PWR->CR |= PWR_CR_DBP;
// Disable write protection
PWR->CR |= PWR_CR_DBP;

// Clear backup domain reset
RCC->BDCR &= ~(RCC_BDCR_BDRST);
// Clear backup domain reset
RCC->BDCR &= ~(RCC_BDCR_BDRST);

// Set RTC options
RCC->BDCR = RCC_BDCR_OPTIONS | (RCC->BDCR & (~RCC_BDCR_MASK));
// Set RTC options
RCC->BDCR = RCC_BDCR_OPTIONS | (RCC->BDCR & (~RCC_BDCR_MASK));

// Enable write protection
PWR->CR &= ~(PWR_CR_DBP);
// Enable write protection
PWR->CR &= ~(PWR_CR_DBP);
}
}
}

void rtc_set_time(timestamp_t time){
puts("Setting RTC time\n");

// Disable write protection
PWR->CR |= PWR_CR_DBP;
RTC->WPR = 0xCA;
RTC->WPR = 0x53;

// Enable initialization mode
RTC->ISR |= RTC_ISR_INIT;
while((RTC->ISR & RTC_ISR_INITF) == 0){}

// Set time
RTC->TR = (to_bcd(time.hour) << RTC_TR_HU_Pos) | (to_bcd(time.minute) << RTC_TR_MNU_Pos) | (to_bcd(time.second) << RTC_TR_SU_Pos);
RTC->DR = (to_bcd(time.year - YEAR_OFFSET) << RTC_DR_YU_Pos) | (time.weekday << RTC_DR_WDU_Pos) | (to_bcd(time.month) << RTC_DR_MU_Pos) | (to_bcd(time.day) << RTC_DR_DU_Pos);

// Set options
RTC->CR = 0U;

// Disable initalization mode
RTC->ISR &= ~(RTC_ISR_INIT);

// Wait for synchronization
while((RTC->ISR & RTC_ISR_RSF) == 0){}

// Re-enable write protection
RTC->WPR = 0x00;
PWR->CR &= ~(PWR_CR_DBP);
if(board_has_rtc()){
puts("Setting RTC time\n");

// Disable write protection
PWR->CR |= PWR_CR_DBP;
RTC->WPR = 0xCA;
RTC->WPR = 0x53;

// Enable initialization mode
RTC->ISR |= RTC_ISR_INIT;
while((RTC->ISR & RTC_ISR_INITF) == 0){}

// Set time
RTC->TR = (to_bcd(time.hour) << RTC_TR_HU_Pos) | (to_bcd(time.minute) << RTC_TR_MNU_Pos) | (to_bcd(time.second) << RTC_TR_SU_Pos);
RTC->DR = (to_bcd(time.year - YEAR_OFFSET) << RTC_DR_YU_Pos) | (time.weekday << RTC_DR_WDU_Pos) | (to_bcd(time.month) << RTC_DR_MU_Pos) | (to_bcd(time.day) << RTC_DR_DU_Pos);

// Set options
RTC->CR = 0U;

// Disable initalization mode
RTC->ISR &= ~(RTC_ISR_INIT);

// Wait for synchronization
while((RTC->ISR & RTC_ISR_RSF) == 0){}

// Re-enable write protection
RTC->WPR = 0x00;
PWR->CR &= ~(PWR_CR_DBP);
}
}

timestamp_t rtc_get_time(void){
// Wait until the register sync flag is set
while((RTC->ISR & RTC_ISR_RSF) == 0){}

// Read time and date registers. Since our HSE > 7*LSE, this should be fine.
uint32_t time = RTC->TR;
uint32_t date = RTC->DR;

// Parse values
timestamp_t result;
result.year = from_bcd((date & (RTC_DR_YT | RTC_DR_YU)) >> RTC_DR_YU_Pos) + YEAR_OFFSET;
result.month = from_bcd((date & (RTC_DR_MT | RTC_DR_MU)) >> RTC_DR_MU_Pos);
result.day = from_bcd((date & (RTC_DR_DT | RTC_DR_DU)) >> RTC_DR_DU_Pos);
result.weekday = ((date & RTC_DR_WDU) >> RTC_DR_WDU_Pos);
result.hour = from_bcd((time & (RTC_TR_HT | RTC_TR_HU)) >> RTC_TR_HU_Pos);
result.minute = from_bcd((time & (RTC_TR_MNT | RTC_TR_MNU)) >> RTC_TR_MNU_Pos);
result.second = from_bcd((time & (RTC_TR_ST | RTC_TR_SU)) >> RTC_TR_SU_Pos);
if(board_has_rtc()){
// Wait until the register sync flag is set
while((RTC->ISR & RTC_ISR_RSF) == 0){}

// Read time and date registers. Since our HSE > 7*LSE, this should be fine.
uint32_t time = RTC->TR;
uint32_t date = RTC->DR;

// Parse values
result.year = from_bcd((date & (RTC_DR_YT | RTC_DR_YU)) >> RTC_DR_YU_Pos) + YEAR_OFFSET;
result.month = from_bcd((date & (RTC_DR_MT | RTC_DR_MU)) >> RTC_DR_MU_Pos);
result.day = from_bcd((date & (RTC_DR_DT | RTC_DR_DU)) >> RTC_DR_DU_Pos);
result.weekday = ((date & RTC_DR_WDU) >> RTC_DR_WDU_Pos);
result.hour = from_bcd((time & (RTC_TR_HT | RTC_TR_HU)) >> RTC_TR_HU_Pos);
result.minute = from_bcd((time & (RTC_TR_MNT | RTC_TR_MNU)) >> RTC_TR_MNU_Pos);
result.second = from_bcd((time & (RTC_TR_ST | RTC_TR_SU)) >> RTC_TR_SU_Pos);
}
return result;
}
3 changes: 0 additions & 3 deletions board/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,9 +727,6 @@ int main(void) {
// init board
current_board->init();

// Initialize RTC
rtc_init();

// panda has an FPU, let's use it!
enable_fpu();

Expand Down

0 comments on commit 606f1d9

Please sign in to comment.