2
0

esp.c 7.0 KB

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