rtc.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /*
  2. * Read/write DS3231M RTC
  3. */
  4. #include "fw.h"
  5. #include "console.h"
  6. #include "io.h"
  7. static inline uint32_t i2c_wait(void)
  8. {
  9. uint32_t rdata;
  10. while ((rdata = I2C_RDATA) & I2C_BUSY)
  11. pause();
  12. return rdata;
  13. }
  14. static void i2c_send(uint8_t byte, uint8_t ctl)
  15. {
  16. i2c_wait();
  17. I2C_WDATA = (byte << 8) | I2C_NAK | ctl;
  18. }
  19. static bool i2c_acked(void)
  20. {
  21. return !(i2c_wait() & I2C_NAK);
  22. }
  23. static int i2c_recv(uint8_t ctl)
  24. {
  25. uint32_t rdata;
  26. i2c_wait();
  27. I2C_WDATA = (~0xff) | ctl;
  28. rdata = i2c_wait();
  29. return rdata >> 8;
  30. }
  31. #define RTC_REGS 19
  32. #define RTC_ADDR 0x68
  33. #define RTC_WCMD ((RTC_ADDR << 1)+0)
  34. #define RTC_RCMD ((RTC_ADDR << 1)+1)
  35. void read_rtc(void)
  36. {
  37. uint8_t rtc_regs[RTC_REGS];
  38. int i;
  39. i2c_set_speed(400);
  40. /* Synchronize I2C */
  41. i2c_send(0xff, I2C_P);
  42. i2c_send(RTC_WCMD, 0);
  43. if (!i2c_acked()) {
  44. con_printf("No RTC detected at I2C address 0x%02x\n", RTC_ADDR);
  45. i2c_send(0xff, I2C_P);
  46. return;
  47. }
  48. i2c_send(0, I2C_SR);
  49. i2c_send(RTC_RCMD, 0);
  50. con_printf("RTC register content:\n");
  51. for (i = 0; i < RTC_REGS-1; i++) {
  52. rtc_regs[i] = i2c_recv(0);
  53. con_printf("%02x ", rtc_regs[i]);
  54. }
  55. rtc_regs[i] = i2c_recv(I2C_NAK | I2C_P);
  56. con_printf("%02x\n", rtc_regs[i]);
  57. }