2
0

esp.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #include "compiler.h"
  2. #include "common.h"
  3. #include "io.h"
  4. #include "console.h"
  5. #include "esp.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 = RINGBUF_BUF_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. /*
  134. * Faster/simpler versions for reading/writing a single byte at a time;
  135. * esp_rb_getc() returns -1 if the ring is empty.
  136. *
  137. * esp_rb_putc() returns -1 on failure, otherwise the number of
  138. * bytes still free in the ring (a nonnegative number.)
  139. */
  140. __hot int esp_rb_getc(enum esplink_ringbuf_user ring)
  141. {
  142. const size_t size = RINGBUF_BUF_SIZE;
  143. const size_t sizemask = size - 1;
  144. const uint8_t * const base = rb_desc[ring].dstr.start;
  145. size_t head = rb_ustr[ring].head;
  146. size_t tail = rb_dstr[ring].tail;
  147. int data;
  148. if (tail == head)
  149. return -1; /* Buffer empty */
  150. data = base[tail];
  151. tail = (tail + 1) & sizemask;
  152. rb_dstr[ring].tail = tail;
  153. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_RINGBUF;
  154. return data;
  155. }
  156. __hot int esp_rb_putc(enum esplink_ringbuf_user ring, uint8_t data)
  157. {
  158. const size_t size = RINGBUF_BUF_SIZE;
  159. const size_t sizemask = size - 1;
  160. uint8_t * const base = rb_desc[ring].ustr.start;
  161. size_t tail = rb_ustr[ring].tail;
  162. size_t head = rb_dstr[ring].head;
  163. int avail = (tail - head - 1) & sizemask;
  164. if (avail--) {
  165. base[head] = data;
  166. head = (head + 1) & sizemask;
  167. rb_dstr[ring].head = head;
  168. ESP_SPI_IRQ_SET = 1 << EL_UIRQ_RINGBUF;
  169. }
  170. return avail;
  171. }
  172. __hot enum ringbuf_status esp_rb_status(enum esplink_ringbuf_user ring)
  173. {
  174. const size_t size = RINGBUF_BUF_SIZE;
  175. const size_t sizemask = size - 1;
  176. const size_t utail = rb_ustr[ring].tail;
  177. const size_t dhead = rb_ustr[ring].head;
  178. const size_t uhead = rb_dstr[ring].head;
  179. const size_t dtail = rb_dstr[ring].tail;
  180. enum ringbuf_status status = RB_CONNECTED;
  181. if (dhead != dtail)
  182. status |= RB_RXDATA;
  183. if ((utail - uhead - 1) & sizemask)
  184. status |= RB_TXFREE;
  185. return status;
  186. }
  187. void esp_init(void)
  188. {
  189. static char __dram_data esp_signature[] = "Hej tomtebuggar slå i glasen!";
  190. ESP_CPU_IRQ = 0;
  191. ESP_SPI_IRQ = 0;
  192. memset(&esplink_head, 0, sizeof esplink_head);
  193. esplink_head.hlen = sizeof esplink_head;
  194. esplink_head.board.cfg = SYS_BOARDCFG;
  195. memcpy(esplink_head.signature, esp_signature, sizeof esp_signature);
  196. esplink_head.tsync = &tsync;
  197. esplink_head.ota = &ota;
  198. esplink_rb_init();
  199. esplink_head.magic = ESPLINK_HEAD_MAGIC;
  200. ESP_SPI_IRQ = (1 << EL_UIRQ_READY);
  201. unmask_irq(ESP_IRQ);
  202. }