esp.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #include "compiler.h"
  2. #include "common.h"
  3. #include "io.h"
  4. #include "console.h"
  5. #include "esp.h"
  6. #include "boardinfo_fpga.h"
  7. struct esplink_head __esplink_head esplink_head;
  8. static volatile __esplink struct esplink_timesync tsync;
  9. static volatile __esplink struct esplink_ota ota;
  10. volatile __esplink char board_info_esp[BOARDINFO_SIZE];
  11. IRQHANDLER(esp,0)
  12. {
  13. uint32_t irqstatus = ESP_CPU_IRQ;
  14. ESP_CPU_IRQ_CLR = irqstatus;
  15. if (irqstatus & (1 << EL_DIRQ_UNDERRUN)) {
  16. con_printf("[ESP] ESP link memory underrun!!\n");
  17. ESP_SPI_IRQ = (1 << EL_UIRQ_READY); /* Block writes, reinitialize! */
  18. return;
  19. }
  20. if (irqstatus & (1 << EL_DIRQ_TIME)) {
  21. if (tsync.set.update) {
  22. SYSCLOCK_TICK_HOLD = tsync.set.tick;
  23. SYSCLOCK_DATETIME = tsync.set.td;
  24. tsync.set.update = 0;
  25. do_write_rtc = true;
  26. } else {
  27. tsync.get.td = SYSCLOCK_DATETIME;
  28. tsync.get.tick = SYSCLOCK_TICK_HOLD;
  29. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_TIME;
  30. }
  31. }
  32. if (irqstatus & (1 << EL_DIRQ_BOARDINFO))
  33. do_update_boardinfo = true;
  34. if (irqstatus & (1 << EL_DIRQ_HELLO)) {
  35. con_printf("[ESP] Got hello, sending ready...\n");
  36. /* Hello, are you there? Yes, I'm here, and you can write data now */
  37. ESP_SPI_IRQ_SET = (1 << EL_UIRQ_READY)|(1 << EL_UIRQ_WREN);
  38. }
  39. /*
  40. * Check to see if we got hello after an OTA process was completed
  41. * or aborted; ESP will send EL_DIRQ_DONE to wake us up.
  42. */
  43. if (!(ESP_SPI_IRQ & (1 << EL_UIRQ_OTA))) {
  44. ota.data = NULL;
  45. ota.len = 0;
  46. }
  47. }
  48. void esp_ota(const void *data, size_t len)
  49. {
  50. mask_irq(ESP_IRQ);
  51. ota.data = data;
  52. ota.len = len;
  53. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_OTA;
  54. unmask_irq(ESP_IRQ);
  55. while (ota.data)
  56. waitfor(ESP_IRQ);
  57. }
  58. #define RINGBUF_BUF_SIZE 4096 /* Must be a power of 2 */
  59. static __esplink uint8_t rb_buf[EL_RB_COUNT][2][RINGBUF_BUF_SIZE];
  60. static __esplink struct esplink_ringbuf_desc rb_desc[EL_RB_COUNT];
  61. static volatile __esplink struct esplink_ptrs_dstr rb_dstr[EL_RB_COUNT];
  62. static volatile __esplink struct esplink_ptrs_ustr rb_ustr[EL_RB_COUNT];
  63. static void esplink_rb_init(void)
  64. {
  65. unsigned int i;
  66. for (i = 0; i < EL_RB_COUNT; i++) {
  67. rb_desc[i].dstr.start = rb_buf[i][0];
  68. rb_desc[i].dstr.size = RINGBUF_BUF_SIZE;
  69. rb_desc[i].ustr.start = rb_buf[i][1];
  70. rb_desc[i].ustr.size = RINGBUF_BUF_SIZE;
  71. }
  72. esplink_head.rb.desc = rb_desc;
  73. esplink_head.rb.dstr = (void *)rb_dstr;
  74. esplink_head.rb.ustr = (void *)rb_ustr;
  75. esplink_head.rb.count = EL_RB_COUNT;
  76. }
  77. /*
  78. * Read and write from ring buffers. These are atomic only; on failure
  79. * returns the amount of data/space available, but does NOT advance
  80. * any pointers nor copy any data.
  81. */
  82. size_t esp_rb_read(enum esplink_ringbuf_user ring, void *data, size_t len)
  83. {
  84. const size_t size = rb_desc[ring].dstr.size;
  85. const size_t sizemask = size - 1;
  86. const uint8_t * const base = rb_desc[ring].dstr.start;
  87. size_t head = rb_ustr[ring].head;
  88. size_t tail = rb_dstr[ring].tail;
  89. size_t avail = (head - tail) & sizemask;
  90. uint8_t *p = data;
  91. size_t xlen = len;
  92. if (!len)
  93. return 0;
  94. if (avail < xlen)
  95. return avail;
  96. if (tail + xlen > size) {
  97. size_t left = size - tail;
  98. memcpy(p, base + tail, left);
  99. p += left;
  100. xlen -= left;
  101. tail = 0;
  102. }
  103. memcpy(p, base + tail, xlen);
  104. tail = (tail + xlen) & sizemask;
  105. rb_dstr[ring].tail = tail;
  106. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_RINGBUF;
  107. return len;
  108. }
  109. size_t esp_rb_write(enum esplink_ringbuf_user ring,
  110. const void *data, size_t len)
  111. {
  112. const size_t size = RINGBUF_BUF_SIZE;
  113. const size_t sizemask = size - 1;
  114. uint8_t * const base = rb_desc[ring].ustr.start;
  115. size_t tail = rb_ustr[ring].tail;
  116. size_t head = rb_dstr[ring].head;
  117. size_t avail = (tail - head - 1) & sizemask;
  118. const uint8_t *p = data;
  119. size_t xlen = len;
  120. if (!len)
  121. return 0;
  122. if (avail < xlen)
  123. return avail;
  124. if (head + xlen > size) {
  125. size_t left = size - head;
  126. memcpy(base + head, p, left);
  127. p += left;
  128. xlen -= left;
  129. head = 0;
  130. }
  131. memcpy(base + head, p, xlen);
  132. head = (head + xlen) & sizemask;
  133. rb_dstr[ring].head = head;
  134. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_RINGBUF;
  135. return len;
  136. }
  137. /*
  138. * Faster/simpler versions for reading/writing a single byte at a time;
  139. * esp_rb_getc() returns -1 if the ring is empty.
  140. *
  141. * esp_rb_putc() returns -1 on failure, otherwise the number of
  142. * bytes still free in the ring (a nonnegative number.)
  143. */
  144. __hot int esp_rb_getc(enum esplink_ringbuf_user ring)
  145. {
  146. const size_t size = RINGBUF_BUF_SIZE;
  147. const size_t sizemask = size - 1;
  148. const uint8_t * const base = rb_desc[ring].dstr.start;
  149. size_t head = rb_ustr[ring].head;
  150. size_t tail = rb_dstr[ring].tail;
  151. int data;
  152. if (tail == head)
  153. return -1; /* Buffer empty */
  154. data = base[tail];
  155. tail = (tail + 1) & sizemask;
  156. rb_dstr[ring].tail = tail;
  157. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_RINGBUF;
  158. return data;
  159. }
  160. __hot int esp_rb_putc(enum esplink_ringbuf_user ring, uint8_t data)
  161. {
  162. const size_t size = RINGBUF_BUF_SIZE;
  163. const size_t sizemask = size - 1;
  164. uint8_t * const base = rb_desc[ring].ustr.start;
  165. size_t tail = rb_ustr[ring].tail;
  166. size_t head = rb_dstr[ring].head;
  167. int avail = (tail - head - 1) & sizemask;
  168. if (avail--) {
  169. base[head] = data;
  170. head = (head + 1) & sizemask;
  171. rb_dstr[ring].head = head;
  172. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_RINGBUF;
  173. }
  174. return avail;
  175. }
  176. __hot enum ringbuf_status esp_rb_status(enum esplink_ringbuf_user ring)
  177. {
  178. const size_t size = RINGBUF_BUF_SIZE;
  179. const size_t sizemask = size - 1;
  180. const size_t utail = rb_ustr[ring].tail;
  181. const size_t dhead = rb_ustr[ring].head;
  182. const size_t uhead = rb_dstr[ring].head;
  183. const size_t dtail = rb_dstr[ring].tail;
  184. enum ringbuf_status status = RB_CONNECTED;
  185. if (dhead != dtail)
  186. status |= RB_RXDATA;
  187. if ((utail - uhead - 1) & sizemask)
  188. status |= RB_TXFREE;
  189. return status;
  190. }
  191. void esp_init(void)
  192. {
  193. static char __dram_data esp_signature[] = "Hej tomtebuggar slå i glasen!";
  194. ESP_CPU_IRQ = 0;
  195. ESP_SPI_IRQ = 0;
  196. memset(&esplink_head, 0, sizeof esplink_head);
  197. esplink_head.hlen = sizeof esplink_head;
  198. esplink_head.board.cfg = SYS_BOARDCFG;
  199. memcpy(esplink_head.signature, esp_signature, sizeof esp_signature);
  200. esplink_head.board_info = &board_info_raw;
  201. esplink_head.tsync = &tsync;
  202. esplink_head.ota = &ota;
  203. esplink_rb_init();
  204. esplink_head.magic = ESPLINK_HEAD_MAGIC;
  205. ESP_SPI_IRQ = (1 << EL_UIRQ_READY);
  206. unmask_irq(ESP_IRQ);
  207. }