Repo for ESP32 Weather Station Development
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
9.4KB

  1. #include "esp32_ucglib_hal.h"
  2. static spi_device_handle_t spi_hdl;
  3. static ucg_esp32_hal_t pins;
  4. static uint8_t* buffer_1 = 0;
  5. static uint8_t* buffer_2 = 0;
  6. static uint8_t* buffer_3 = 0;
  7. int16_t ucg_esp32_hal(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *data) {
  8. //ESP_LOGI("hal", "spi_byte_cb: Received a msg: %d, arg: %d, arg_ptr: %p",
  9. // msg, arg, data);
  10. switch (msg) {
  11. case UCG_COM_MSG_POWER_UP:
  12. //ESP_LOGI("hal", "UCG_COM_MSG_POWER_UP");
  13. /* "data" is a pointer to ucg_com_info_t structure with the following information: */
  14. /* ((ucg_com_info_t *)data)->serial_clk_speed value in nanoseconds */
  15. /* ((ucg_com_info_t *)data)->parallel_clk_speed value in nanoseconds */
  16. /* "arg" is not used */
  17. /* This message is sent once at the uC startup and for power up. */
  18. /* setup i/o or do any other setup */
  19. ;
  20. buffer_1 = (uint8_t*) heap_caps_malloc(1, MALLOC_CAP_DMA);
  21. buffer_2 = (uint8_t*) heap_caps_malloc(1, MALLOC_CAP_DMA);
  22. buffer_3 = (uint8_t*) heap_caps_malloc(1, MALLOC_CAP_DMA);
  23. pins.clk = GPIO_NUM_18;
  24. pins.cs = GPIO_NUM_17;
  25. pins.dc = GPIO_NUM_2;
  26. pins.mosi = GPIO_NUM_23;
  27. pins.reset = GPIO_NUM_14;
  28. gpio_config_t gp_config;
  29. gp_config.intr_type = GPIO_INTR_DISABLE;
  30. gp_config.mode = GPIO_MODE_OUTPUT;
  31. gp_config.pin_bit_mask = ((1ULL << pins.reset) | (1ULL << pins.cs) | (1ULL << pins.dc));
  32. gp_config.pull_down_en = GPIO_PULLDOWN_ENABLE;
  33. gp_config.pull_up_en = GPIO_PULLUP_DISABLE;
  34. gpio_config(&gp_config);
  35. spi_bus_config_t* bus_config;
  36. bus_config = heap_caps_calloc(1, sizeof(spi_bus_config_t), MALLOC_CAP_8BIT);
  37. bus_config->mosi_io_num = pins.mosi;
  38. bus_config->miso_io_num = -1;
  39. bus_config->sclk_io_num = pins.clk;
  40. bus_config->quadwp_io_num = -1;
  41. bus_config->quadhd_io_num = -1;
  42. bus_config->max_transfer_sz = 4094;
  43. bus_config->flags = 0;
  44. bus_config->intr_flags = 0;
  45. esp_err_t err = spi_bus_initialize(VSPI_HOST, bus_config, 1);
  46. if (err != ESP_OK) {
  47. ESP_LOGE("hal", "Could not initialize spi bus...");
  48. switch (err) {
  49. case ESP_ERR_INVALID_ARG:
  50. ESP_LOGE("hal", "ESP_ERR_INVALID_ARG");
  51. break;
  52. case ESP_ERR_INVALID_STATE:
  53. ESP_LOGE("hal", "ESP_ERR_INVALID_STATE");
  54. break;
  55. case ESP_ERR_NO_MEM:
  56. ESP_LOGE("hal", "ESP_ERR_NO_MEM");
  57. break;
  58. default:
  59. ESP_LOGE("hal", "Unknown err!");
  60. }
  61. }
  62. ESP_LOGI("hal", "successfully init bus!");
  63. spi_device_interface_config_t* dev_config;
  64. dev_config = heap_caps_calloc(1, sizeof(spi_device_interface_config_t), MALLOC_CAP_8BIT);
  65. dev_config->address_bits = 0;
  66. dev_config->command_bits = 0;
  67. dev_config->dummy_bits = 0;
  68. dev_config->mode = 0;
  69. dev_config->duty_cycle_pos = 0;
  70. dev_config->cs_ena_posttrans = 0;
  71. dev_config->cs_ena_pretrans = 0;
  72. dev_config->clock_speed_hz = SPI_MASTER_FREQ_40M;
  73. dev_config->spics_io_num = pins.cs;
  74. dev_config->queue_size = 200;
  75. dev_config->flags = 0;
  76. dev_config->pre_cb = NULL;
  77. dev_config->post_cb = NULL;
  78. err = spi_bus_add_device(VSPI_HOST, dev_config, &spi_hdl);
  79. if (err != ESP_OK) {
  80. ESP_LOGE("hal", "Could not initialize spi bus...");
  81. switch (err) {
  82. case ESP_ERR_INVALID_ARG:
  83. ESP_LOGE("hal", "ESP_ERR_INVALID_ARG");
  84. break;
  85. case ESP_ERR_INVALID_STATE:
  86. ESP_LOGE("hal", "ESP_ERR_INVALID_STATE");
  87. break;
  88. case ESP_ERR_NO_MEM:
  89. ESP_LOGE("hal", "ESP_ERR_NO_MEM");
  90. break;
  91. default:
  92. ESP_LOGE("hal", "Unknown err!");
  93. }
  94. }
  95. ESP_LOGI("hal", "successfully init bus device!");
  96. break;
  97. case UCG_COM_MSG_POWER_DOWN:
  98. //ESP_LOGI("hal", "UCG_COM_MSG_POWER_DOWN");
  99. /* "data" and "arg" are not used*/
  100. /* This message is sent for a power down request */
  101. spi_bus_remove_device(spi_hdl);
  102. spi_bus_free(HSPI_HOST);
  103. heap_caps_free(buffer_1);
  104. heap_caps_free(buffer_2);
  105. heap_caps_free(buffer_3);
  106. break;
  107. case UCG_COM_MSG_DELAY:
  108. //ESP_LOGI("hal", "UCG_COM_MSG_DELAY");
  109. /* "data" is not used */
  110. /* "arg" contains the number of microseconds for the delay */
  111. /* By receiving this message, the following code should delay by */
  112. /* "arg" microseconds. One microsecond is 0.000001 second */
  113. //vTaskDelay(arg / portTICK_PERIOD_MS / 100);
  114. break;
  115. case UCG_COM_MSG_CHANGE_RESET_LINE:
  116. //ESP_LOGI("hal", "UCG_COM_MSG_CHANGE_RESET_LINE");
  117. /* "data" is not used */
  118. /* "arg" = 1: set the reset output line to 1 */
  119. /* "arg" = 0: set the reset output line to 0 */
  120. gpio_set_level(pins.reset, arg);
  121. break;
  122. case UCG_COM_MSG_CHANGE_CD_LINE:
  123. //ESP_LOGI("hal", "UCG_COM_MSG_CHANGE_CD_LINE");
  124. /* "ucg->com_status" bit 0 contains the old level for the CD line */
  125. /* "data" is not used */
  126. /* "arg" = 1: set the command/data (a0) output line to 1 */
  127. /* "arg" = 0: set the command/data (a0) output line to 0 */
  128. gpio_set_level(pins.dc, arg);
  129. break;
  130. case UCG_COM_MSG_CHANGE_CS_LINE:
  131. //ESP_LOGI("hal", "UCG_COM_MSG_CHANGE_CS_LINE");
  132. /* "ucg->com_status" bit 1 contains the old level for the CS line */
  133. /* "data" is not used */
  134. /* "arg" = 1: set the chipselect output line to 1 */
  135. /* "arg" = 0: set the chipselect output line to 0 */
  136. gpio_set_level(pins.cs, arg);
  137. break;
  138. case UCG_COM_MSG_SEND_BYTE:
  139. //ESP_LOGI("hal", "UCG_COM_MSG_SEND_BYTE");
  140. /* "data" is not used */
  141. /* "arg" contains one byte, which should be sent to the display */
  142. /* The current status of the CD line is available */
  143. /* in bit 0 of u8g->com_status */
  144. ;
  145. *buffer_1 = (uint8_t) arg;
  146. spi_transaction_t transaction;
  147. transaction.addr = 0;
  148. transaction.cmd = 0;
  149. transaction.length = 8;
  150. transaction.rxlength = 0;
  151. transaction.tx_buffer = buffer_1;
  152. transaction.rx_buffer = NULL;
  153. transaction.flags = SPI_TRANS_USE_RXDATA ;
  154. spi_device_transmit(spi_hdl, &transaction);
  155. break;
  156. case UCG_COM_MSG_REPEAT_1_BYTE:
  157. {
  158. ESP_LOGW("hal", "UCG_COM_MSG_REPEAT_1_BYTE");
  159. /* "data[0]" contains one byte */
  160. /* repeat sending the byte in data[0] "arg" times */
  161. /* The current status of the CD line is available */
  162. /* in bit 0 of u8g->com_status */
  163. //spi_transaction_t transaction;
  164. //transaction.length = 8;
  165. //transaction.tx_buffer = data[0];
  166. //transaction.flags = SPI_TRANS_USE_TXDATA;
  167. //int i;
  168. //for (i = 0; i < arg; i++) {
  169. // spi_device_polling_transmit(spi_hdl, &transaction);
  170. //}
  171. break;
  172. }
  173. case UCG_COM_MSG_REPEAT_2_BYTES:
  174. {
  175. ESP_LOGW("hal", "UCG_COM_MSG_REPEAT_2_BYTES");
  176. // spi_transaction_t transaction1;
  177. // transaction.flags = SPI_TRANS_USE_TXDATA;
  178. // transaction.length = 8;
  179. // transaction.tx_buffer = data[0];
  180. // spi_transaction_t transaction2;
  181. // transaction2.flags = SPI_TRANS_USE_TXDATA;
  182. // transaction2.length = 8;
  183. // transaction2.tx_buffer = data[1];
  184. // int i;
  185. // for (i = 0; i < arg; i++) {
  186. // spi_device_polling_transmit(spi_hdl, &transaction1);
  187. // spi_device_polling_transmit(spi_hdl, &transaction2);
  188. // }
  189. /* "data[0]" contains first byte */
  190. /* "data[1]" contains second byte */
  191. /* repeat sending the two bytes "arg" times */
  192. /* The current status of the CD line is available */
  193. /* in bit 0 of u8g->com_status */
  194. break;
  195. }
  196. case UCG_COM_MSG_REPEAT_3_BYTES:
  197. {
  198. //ESP_LOGI("hal", "UCG_COM_MSG_REPEAT_3_BYTES");
  199. /* "data[0]" contains first byte */
  200. /* "data[1]" contains second byte */
  201. /* "data[2]" contains third byte */
  202. /* repeat sending the three bytes "arg" times */
  203. /* The current status of the CD line is available */
  204. /* in bit 0 of u8g->com_status */
  205. buffer_3[0] = data[0];
  206. buffer_3[1] = data[1];
  207. buffer_3[2] = data[2];
  208. spi_transaction_t transaction;
  209. transaction.addr = 0;
  210. transaction.cmd = 0;
  211. transaction.length = 3*8;
  212. transaction.rxlength = 0;
  213. transaction.tx_buffer = buffer_3;
  214. transaction.rx_buffer = NULL;
  215. transaction.flags = SPI_TRANS_USE_RXDATA ;
  216. int i;
  217. for (i = 0; i < arg; i++) {
  218. spi_device_transmit(spi_hdl, &transaction);
  219. }
  220. // spi_transaction_t transaction1;
  221. // transaction1.flags = SPI_TRANS_USE_TXDATA ;
  222. // transaction1.length = 8;
  223. // transaction1.tx_buffer = &data[0];
  224. // spi_transaction_t transaction2;
  225. // transaction2.flags = SPI_TRANS_USE_TXDATA ;
  226. // transaction2.length = 8;
  227. // transaction2.tx_buffer = &data[1];
  228. // spi_transaction_t transaction3;
  229. // transaction3.flags = SPI_TRANS_USE_TXDATA ;
  230. // transaction3.length = 8;
  231. // transaction3.tx_buffer = &data[2];
  232. // int i;
  233. // for (i = 0; i < arg; i++) {
  234. // spi_device_polling_transmit(spi_hdl, &transaction1);
  235. // spi_device_polling_transmit(spi_hdl, &transaction2);
  236. // spi_device_polling_transmit(spi_hdl, &transaction3);
  237. // }
  238. break;
  239. }
  240. case UCG_COM_MSG_SEND_STR:
  241. {
  242. ESP_LOGW("hal", "UCG_COM_MSG_SEND_STR");
  243. /* "data" is an array with "arg" bytes */
  244. /* send "arg" bytes to the display */
  245. spi_transaction_t transaction1;
  246. transaction1.flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA ;
  247. transaction1.length = 8*arg;
  248. transaction1.tx_buffer = &data[0];
  249. spi_device_polling_transmit(spi_hdl, &transaction1);
  250. break;
  251. }
  252. case UCG_COM_MSG_SEND_CD_DATA_SEQUENCE:
  253. {
  254. //ESP_LOGW("hal", "UCG_COM_MSG_SEND_CD_DATA_SEQUENCE");
  255. /* "data" is a pointer to two bytes, which contain the cd line */
  256. /* status and display data */
  257. /* "arg" contains the number of these two byte tuples which need to */
  258. /* be analysed and sent. Bellow is a example sequence */
  259. /* The content of bit 0 in u8g->com_status is undefined for this message */
  260. while (arg > 0) {
  261. if (*data != 0) {
  262. if (*data == 1) {
  263. /* set CD (=D/C=A0) line to low */
  264. } else {
  265. /* set CD (=D/C=A0) line to high */
  266. }
  267. }
  268. data++;
  269. /* send *data to the display */
  270. data++;
  271. arg--;
  272. }
  273. break;
  274. }
  275. }
  276. return 1;
  277. }