2
0

esp.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include "compiler.h"
  2. #include "common.h"
  3. #include "io.h"
  4. #include "console.h"
  5. #include "esplink.h"
  6. struct esplink_head __esplink_head esplink_head;
  7. static volatile __esplink struct esplink_timesync tsync;
  8. static volatile __esplink struct esplink_ota ota;
  9. IRQHANDLER(esp,0)
  10. {
  11. uint32_t irqstatus = ESP_CPU_IRQ;
  12. ESP_CPU_IRQ_CLR = irqstatus;
  13. if (irqstatus & (1 << EL_DIRQ_UNDERRUN)) {
  14. con_printf("[ESP] ESP link memory underrun!!\n");
  15. ESP_SPI_IRQ = (1 << EL_UIRQ_READY); /* Block writes, reinitialize! */
  16. return;
  17. }
  18. if (irqstatus & (1 << EL_DIRQ_TIME)) {
  19. if (tsync.set.update) {
  20. SYSCLOCK_TICK_HOLD = tsync.set.tick;
  21. SYSCLOCK_DATETIME = tsync.set.td;
  22. tsync.set.update = 0;
  23. do_write_rtc = true;
  24. } else {
  25. tsync.get.td = SYSCLOCK_DATETIME;
  26. tsync.get.tick = SYSCLOCK_TICK_HOLD;
  27. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_TIME;
  28. }
  29. }
  30. if (irqstatus & (1 << EL_DIRQ_HELLO)) {
  31. con_printf("[ESP] Got hello, sending ready...\n");
  32. /* Hello, are you there? Yes, I'm here, and you can write data now */
  33. ESP_SPI_IRQ_SET = (1 << EL_UIRQ_READY)|(1 << EL_UIRQ_WREN);
  34. }
  35. /*
  36. * Check to see if we got hello after an OTA process was completed
  37. * or aborted; ESP will send EL_DIRQ_DONE to wake us up.
  38. */
  39. if (!(ESP_SPI_IRQ & (1 << EL_UIRQ_OTA))) {
  40. ota.data = NULL;
  41. ota.len = 0;
  42. }
  43. }
  44. void esp_ota(const void *data, size_t len)
  45. {
  46. mask_irq(ESP_IRQ);
  47. ota.data = data;
  48. ota.len = len;
  49. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_OTA;
  50. unmask_irq(ESP_IRQ);
  51. while (ota.data)
  52. waitfor(ESP_IRQ);
  53. }
  54. #define RINGBUF_BUF_SIZE 4096 /* Must be a power of 2 */
  55. static __esplink uint8_t rb_buf[EL_RB_COUNT][2][RINGBUF_BUF_SIZE];
  56. static __esplink struct esplink_ringbuf_desc rb_desc[EL_RB_COUNT];
  57. static volatile __esplink struct esplink_ptrs_dstr rb_dstr[EL_RB_COUNT];
  58. static volatile __esplink struct esplink_ptrs_ustr rb_ustr[EL_RB_COUNT];
  59. static void esplink_rb_init(void)
  60. {
  61. unsigned int i;
  62. for (i = 0; i < EL_RB_COUNT; i++) {
  63. rb_desc[i].dstr.start = rb_buf[i][0];
  64. rb_desc[i].dstr.size = RINGBUF_BUF_SIZE;
  65. rb_desc[i].ustr.start = rb_buf[i][1];
  66. rb_desc[i].ustr.size = RINGBUF_BUF_SIZE;
  67. }
  68. esplink_head.rb.desc = rb_desc;
  69. esplink_head.rb.dstr = (void *)rb_dstr;
  70. esplink_head.rb.ustr = (void *)rb_ustr;
  71. esplink_head.rb.count = EL_RB_COUNT;
  72. }
  73. /*
  74. * Read and write from ring buffers. These are atomic only; on failure
  75. * returns the amount of data/space available, but does NOT advance
  76. * any pointers nor copy any data.
  77. */
  78. size_t esp_rb_read(enum esplink_ringbuf_user ring, void *data, size_t len)
  79. {
  80. const size_t size = rb_desc[ring].dstr.size;
  81. const size_t sizemask = size - 1;
  82. const uint8_t * const base = rb_desc[ring].dstr.start;
  83. size_t head = rb_ustr[ring].head;
  84. size_t tail = rb_dstr[ring].tail;
  85. size_t avail = (head - tail) & sizemask;
  86. uint8_t *p = data;
  87. size_t xlen = len;
  88. if (!len)
  89. return 0;
  90. if (avail < xlen)
  91. return avail;
  92. if (tail + xlen > size) {
  93. size_t left = size - tail;
  94. memcpy(p, base + tail, left);
  95. p += left;
  96. xlen -= left;
  97. tail = 0;
  98. }
  99. memcpy(p, base + tail, xlen);
  100. tail = (tail + xlen) & sizemask;
  101. rb_dstr[ring].tail = tail;
  102. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_RINGBUF;
  103. return len;
  104. }
  105. size_t esp_rb_write(enum esplink_ringbuf_user ring,
  106. const void *data, size_t len)
  107. {
  108. const size_t size = rb_desc[ring].ustr.size;
  109. const size_t sizemask = size - 1;
  110. uint8_t * const base = rb_desc[ring].ustr.start;
  111. size_t tail = rb_ustr[ring].tail;
  112. size_t head = rb_dstr[ring].head;
  113. size_t avail = (tail - head - 1) & sizemask;
  114. const uint8_t *p = data;
  115. size_t xlen = len;
  116. if (!len)
  117. return 0;
  118. if (avail < xlen)
  119. return avail;
  120. if (head + xlen > size) {
  121. size_t left = size - head;
  122. memcpy(base + head, p, left);
  123. p += left;
  124. xlen -= left;
  125. head = 0;
  126. }
  127. memcpy(base + head, p, xlen);
  128. head = (head + xlen) & sizemask;
  129. rb_dstr[ring].head = head;
  130. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_RINGBUF;
  131. return len;
  132. }
  133. void esp_init(void)
  134. {
  135. static char __dram_data esp_signature[] = "Hej tomtebuggar slå i glasen!";
  136. ESP_CPU_IRQ = 0;
  137. ESP_SPI_IRQ = 0;
  138. memset(&esplink_head, 0, sizeof esplink_head);
  139. esplink_head.hlen = sizeof esplink_head;
  140. esplink_head.board.cfg = SYS_BOARDCFG;
  141. memcpy(esplink_head.signature, esp_signature, sizeof esp_signature);
  142. esplink_head.tsync = &tsync;
  143. esplink_head.ota = &ota;
  144. esplink_rb_init();
  145. esplink_head.magic = ESPLINK_HEAD_MAGIC;
  146. ESP_SPI_IRQ = (1 << EL_UIRQ_READY);
  147. unmask_irq(ESP_IRQ);
  148. }