muse.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. YOUR LICENSE
  3. */
  4. #include <string.h>
  5. #include <esp_log.h>
  6. #include <esp_types.h>
  7. #include <esp_system.h>
  8. #include <freertos/FreeRTOS.h>
  9. #include <freertos/task.h>
  10. #include "driver/rmt.h"
  11. #include "globdefs.h"
  12. #include "monitor.h"
  13. #include "targets.h"
  14. /////////////////////////////////////////////////////////////////
  15. //*********************** NeoPixels ***************************
  16. ////////////////////////////////////////////////////////////////
  17. #define NUM_LEDS 1
  18. #define LED_RMT_TX_GPIO 22
  19. #define BITS_PER_LED_CMD 24
  20. #define LED_BUFFER_ITEMS ((NUM_LEDS * BITS_PER_LED_CMD))
  21. // These values are determined by measuring pulse timing with logic analyzer and adjusting to match datasheet.
  22. #define T0H 14 // 0 bit high time
  23. #define T1H 52 // 1 bit high time
  24. #define TL 52 // low time for either bit
  25. // sets a color based on RGB from 0..255 and a brightness in % from 0..100
  26. #define RGB(R,G,B,BR) (((G*BR)/100) << 16) | (((R*BR)/100) << 8) | ((B*BR)/100)
  27. #define RED RGB(255,0,0,10)
  28. #define GREEN RGB(0,255,0,10)
  29. #define BLUE RGB(0,0,255,10)
  30. #define WHITE RGB(255,255,255,10)
  31. #define YELLOW RGB(255,118,13,10)
  32. struct led_state {
  33. uint32_t leds[NUM_LEDS];
  34. };
  35. static int rmt_channel;
  36. void ws2812_control_init(void);
  37. void ws2812_write_leds(struct led_state new_state);
  38. ///////////////////////////////////////////////////////////////////
  39. static const char TAG[] = "muse";
  40. static void (*battery_handler_chain)(float value, int cells);
  41. static void battery_svc(float value, int cells);
  42. static bool init(void);
  43. static void set_battery_led(float value);
  44. const struct target_s target_muse = { .model = "muse", .init = init };
  45. static bool init(void) {
  46. battery_handler_chain = battery_handler_svc;
  47. battery_handler_svc = battery_svc;
  48. ws2812_control_init();
  49. float value = battery_value_svc();
  50. set_battery_led(value);
  51. ESP_LOGI(TAG, "Initializing for Muse %f", value);
  52. return true;
  53. }
  54. #define VGREEN 4.0
  55. #define VRED 3.6
  56. static void set_battery_led(float value) {
  57. struct led_state new_state;
  58. if (value > VGREEN) new_state.leds[0] = GREEN;
  59. else if (value < VRED) new_state.leds[0] = RED;
  60. else new_state.leds[0] = YELLOW;
  61. ws2812_write_leds(new_state);
  62. }
  63. static void battery_svc(float value, int cells) {
  64. set_battery_led(value);
  65. ESP_LOGI(TAG, "Called for battery service with %f", value);
  66. if (battery_handler_chain) battery_handler_chain(value, cells);
  67. }
  68. // This is the buffer which the hw peripheral will access while pulsing the output pin
  69. rmt_item32_t led_data_buffer[LED_BUFFER_ITEMS];
  70. void setup_rmt_data_buffer(struct led_state new_state);
  71. void ws2812_control_init(void)
  72. {
  73. rmt_channel = RMT_NEXT_TX_CHANNEL();
  74. rmt_config_t config;
  75. config.rmt_mode = RMT_MODE_TX;
  76. config.channel = rmt_channel;
  77. config.gpio_num = LED_RMT_TX_GPIO;
  78. config.mem_block_num = 3;
  79. config.tx_config.loop_en = false;
  80. config.tx_config.carrier_en = false;
  81. config.tx_config.idle_output_en = true;
  82. config.tx_config.idle_level = 0;
  83. config.clk_div = 2;
  84. ESP_ERROR_CHECK(rmt_config(&config));
  85. ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));
  86. ESP_LOGI(TAG, "LED wth ws2812 using gpio %d and channel %d", LED_RMT_TX_GPIO, rmt_channel);
  87. }
  88. void ws2812_write_leds(struct led_state new_state) {
  89. setup_rmt_data_buffer(new_state);
  90. rmt_write_items(rmt_channel, led_data_buffer, LED_BUFFER_ITEMS, false);
  91. }
  92. void setup_rmt_data_buffer(struct led_state new_state)
  93. {
  94. for (uint32_t led = 0; led < NUM_LEDS; led++) {
  95. uint32_t bits_to_send = new_state.leds[led];
  96. uint32_t mask = 1 << (BITS_PER_LED_CMD - 1);
  97. for (uint32_t bit = 0; bit < BITS_PER_LED_CMD; bit++) {
  98. uint32_t bit_is_set = bits_to_send & mask;
  99. led_data_buffer[led * BITS_PER_LED_CMD + bit] = bit_is_set ?
  100. (rmt_item32_t){{{T1H, 1, TL, 0}}} :
  101. (rmt_item32_t){{{T0H, 1, TL, 0}}};
  102. mask >>= 1;
  103. }
  104. }
  105. }