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.

167 lines
5.4KB

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "sdkconfig.h"
  4. #include "esp_log.h"
  5. #include "freertos/FreeRTOS.h"
  6. #include "freertos/task.h"
  7. #include "u8g2_esp32_hal.h"
  8. static const char *TAG = "u8g2_hal";
  9. static const unsigned int I2C_TIMEOUT_MS = 1000;
  10. static i2c_cmd_handle_t handle_i2c; // I2C handle.
  11. static u8g2_esp32_hal_t u8g2_esp32_hal; // HAL state data.
  12. #undef ESP_ERROR_CHECK
  13. #define ESP_ERROR_CHECK(x) do { esp_err_t rc = (x); if (rc != ESP_OK) { ESP_LOGE("err", "esp_err_t = %d", rc); assert(0 && #x);} } while(0);
  14. /*
  15. * Initialze the ESP32 HAL.
  16. */
  17. void u8g2_esp32_hal_init(u8g2_esp32_hal_t u8g2_esp32_hal_param) {
  18. u8g2_esp32_hal = u8g2_esp32_hal_param;
  19. } // u8g2_esp32_hal_init
  20. /*
  21. * HAL callback function as prescribed by the U8G2 library. This callback is invoked
  22. * to handle I2C communications.
  23. */
  24. uint8_t u8g2_esp32_i2c_byte_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
  25. //ESP_LOGD(TAG, "i2c_cb: Received a msg: %d, arg_int: %d, arg_ptr: %p", msg, arg_int, arg_ptr);
  26. switch(msg) {
  27. case U8X8_MSG_BYTE_SET_DC: {
  28. if (u8g2_esp32_hal.dc != U8G2_ESP32_HAL_UNDEFINED) {
  29. gpio_set_level(u8g2_esp32_hal.dc, arg_int);
  30. }
  31. break;
  32. }
  33. case U8X8_MSG_BYTE_INIT: {
  34. if (u8g2_esp32_hal.sda == U8G2_ESP32_HAL_UNDEFINED ||
  35. u8g2_esp32_hal.scl == U8G2_ESP32_HAL_UNDEFINED) {
  36. break;
  37. }
  38. i2c_config_t conf;
  39. conf.mode = I2C_MODE_MASTER;
  40. ESP_LOGI(TAG, "sda_io_num %d", u8g2_esp32_hal.sda);
  41. conf.sda_io_num = u8g2_esp32_hal.sda;
  42. conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
  43. ESP_LOGI(TAG, "scl_io_num %d", u8g2_esp32_hal.scl);
  44. conf.scl_io_num = u8g2_esp32_hal.scl;
  45. conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
  46. ESP_LOGI(TAG, "clk_speed %d", I2C_MASTER_FREQ_HZ);
  47. conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
  48. ESP_LOGI(TAG, "i2c_param_config %d", conf.mode);
  49. ESP_ERROR_CHECK(i2c_param_config(I2C_MASTER_NUM, &conf));
  50. ESP_LOGI(TAG, "i2c_driver_install %d", I2C_MASTER_NUM);
  51. ESP_ERROR_CHECK(i2c_driver_install(I2C_MASTER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0));
  52. break;
  53. }
  54. case U8X8_MSG_BYTE_SEND: {
  55. uint8_t* data_ptr = (uint8_t*)arg_ptr;
  56. ESP_LOG_BUFFER_HEXDUMP(TAG, data_ptr, arg_int, ESP_LOG_VERBOSE);
  57. while( arg_int > 0 ) {
  58. ESP_ERROR_CHECK(i2c_master_write_byte(handle_i2c, *data_ptr, ACK_CHECK_EN));
  59. data_ptr++;
  60. arg_int--;
  61. }
  62. break;
  63. }
  64. case U8X8_MSG_BYTE_START_TRANSFER: {
  65. uint8_t i2c_address = u8x8_GetI2CAddress(u8x8);
  66. handle_i2c = i2c_cmd_link_create();
  67. ESP_LOGD(TAG, "Start I2C transfer to %02X.", i2c_address>>1);
  68. ESP_ERROR_CHECK(i2c_master_start(handle_i2c));
  69. ESP_ERROR_CHECK(i2c_master_write_byte(handle_i2c, i2c_address | I2C_MASTER_WRITE, ACK_CHECK_EN));
  70. break;
  71. }
  72. case U8X8_MSG_BYTE_END_TRANSFER: {
  73. ESP_LOGD(TAG, "End I2C transfer.");
  74. ESP_ERROR_CHECK(i2c_master_stop(handle_i2c));
  75. ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, handle_i2c, I2C_TIMEOUT_MS / portTICK_RATE_MS));
  76. i2c_cmd_link_delete(handle_i2c);
  77. break;
  78. }
  79. }
  80. return 0;
  81. } // u8g2_esp32_i2c_byte_cb
  82. /*
  83. * HAL callback function as prescribed by the U8G2 library. This callback is invoked
  84. * to handle callbacks for GPIO and delay functions.
  85. */
  86. uint8_t u8g2_esp32_gpio_and_delay_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
  87. ESP_LOGD(TAG, "gpio_and_delay_cb: Received a msg: %d, arg_int: %d, arg_ptr: %p", msg, arg_int, arg_ptr);
  88. switch(msg) {
  89. // Initialize the GPIO and DELAY HAL functions. If the pins for DC and RESET have been
  90. // specified then we define those pins as GPIO outputs.
  91. case U8X8_MSG_GPIO_AND_DELAY_INIT: {
  92. uint64_t bitmask = 0;
  93. if (u8g2_esp32_hal.dc != U8G2_ESP32_HAL_UNDEFINED) {
  94. bitmask = bitmask | (1ull<<u8g2_esp32_hal.dc);
  95. }
  96. if (u8g2_esp32_hal.reset != U8G2_ESP32_HAL_UNDEFINED) {
  97. bitmask = bitmask | (1ull<<u8g2_esp32_hal.reset);
  98. }
  99. if (u8g2_esp32_hal.cs != U8G2_ESP32_HAL_UNDEFINED) {
  100. bitmask = bitmask | (1ull<<u8g2_esp32_hal.cs);
  101. }
  102. if (bitmask==0) {
  103. break;
  104. }
  105. gpio_config_t gpioConfig;
  106. gpioConfig.pin_bit_mask = bitmask;
  107. gpioConfig.mode = GPIO_MODE_OUTPUT;
  108. gpioConfig.pull_up_en = GPIO_PULLUP_DISABLE;
  109. gpioConfig.pull_down_en = GPIO_PULLDOWN_ENABLE;
  110. gpioConfig.intr_type = GPIO_INTR_DISABLE;
  111. gpio_config(&gpioConfig);
  112. break;
  113. }
  114. // Set the GPIO reset pin to the value passed in through arg_int.
  115. case U8X8_MSG_GPIO_RESET:
  116. if (u8g2_esp32_hal.reset != U8G2_ESP32_HAL_UNDEFINED) {
  117. gpio_set_level(u8g2_esp32_hal.reset, arg_int);
  118. }
  119. break;
  120. // Set the GPIO client select pin to the value passed in through arg_int.
  121. case U8X8_MSG_GPIO_CS:
  122. if (u8g2_esp32_hal.cs != U8G2_ESP32_HAL_UNDEFINED) {
  123. gpio_set_level(u8g2_esp32_hal.cs, arg_int);
  124. }
  125. break;
  126. // Set the Software I²C pin to the value passed in through arg_int.
  127. case U8X8_MSG_GPIO_I2C_CLOCK:
  128. if (u8g2_esp32_hal.scl != U8G2_ESP32_HAL_UNDEFINED) {
  129. gpio_set_level(u8g2_esp32_hal.scl, arg_int);
  130. // printf("%c",(arg_int==1?'C':'c'));
  131. }
  132. break;
  133. // Set the Software I²C pin to the value passed in through arg_int.
  134. case U8X8_MSG_GPIO_I2C_DATA:
  135. if (u8g2_esp32_hal.sda != U8G2_ESP32_HAL_UNDEFINED) {
  136. gpio_set_level(u8g2_esp32_hal.sda, arg_int);
  137. // printf("%c",(arg_int==1?'D':'d'));
  138. }
  139. break;
  140. // Delay for the number of milliseconds passed in through arg_int.
  141. case U8X8_MSG_DELAY_MILLI:
  142. vTaskDelay(arg_int/portTICK_PERIOD_MS);
  143. break;
  144. }
  145. return 0;
  146. } // u8g2_esp32_gpio_and_delay_cb