hal_ws2812.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #include "hal_ws2812.h"
  2. #include "bsp_gpio.h"
  3. #include "nrf_gpio.h"
  4. #include "usr_config.h"
  5. //#include "bsp_time.h"
  6. #include "system.h"
  7. #include "hal_ble_client.h"
  8. #include "drv_pwm.h"
  9. #include "nrf_delay.h"
  10. #include "hal_imu.h"
  11. #define WS2812_FLASH_ALWAYS 1 //是否一直刷新
  12. #define WS2812_ENABLE 0
  13. #define WS2812_DISABLE 1
  14. #define WS2812_DISPLAY_NUMBER 4
  15. #define ONE_WS2812_LIGHT_TIME (3*4*8*4*0.125) //us
  16. //高位先发,按照GRB的顺序发送数据
  17. //50us以上reset
  18. //#define WS_L 0,0x8000,0x8000,0x8000
  19. //#define WS_H 0,0,0,0x8000
  20. static pwm_values_common_t led_color_seq_values[3][4*8] = {0};
  21. static nrf_pwm_sequence_t *led_color_seq = NULL;
  22. static const uint16_t WS_H[4] = {0,0,0,0x8000};
  23. static const uint16_t WS_L[4] = {0,0x8000,0x8000,0x8000};
  24. static uint8_t reflash = 1 ;
  25. struct WS_t{
  26. uint8_t onoff;
  27. uint32_t color; //颜色
  28. };
  29. static struct WS_t m_wsled[MEMBER_NUM_OF_WS2812] = {0};
  30. /**
  31. @brief 设置灯的时序
  32. @param color - [in] 灯的颜色
  33. @return 无
  34. */
  35. static void WS2812_DisplayDot(uint32_t col)
  36. {
  37. uint32_t col_r = (col & 0x00FF0000) >> 16;
  38. uint32_t col_g = (col & 0x0000FF00) >> 8;
  39. uint32_t col_b = col & 0x000000FF;
  40. uint32_t t = 0x80;
  41. uint32_t index = 0;
  42. for(int i=0;i<8;i++)
  43. {
  44. index = i*4;
  45. if(col_g & t){
  46. led_color_seq_values[0][index+0] = WS_H[0];
  47. led_color_seq_values[0][index+1] = WS_H[1];
  48. led_color_seq_values[0][index+2] = WS_H[2];
  49. led_color_seq_values[0][index+3] = WS_H[3];
  50. }else{
  51. led_color_seq_values[0][index+0] = WS_L[0];
  52. led_color_seq_values[0][index+1] = WS_L[1];
  53. led_color_seq_values[0][index+2] = WS_L[2];
  54. led_color_seq_values[0][index+3] = WS_L[3];
  55. }
  56. index = i*4;
  57. if(col_r & t){
  58. led_color_seq_values[1][index+0] = WS_H[0];
  59. led_color_seq_values[1][index+1] = WS_H[1];
  60. led_color_seq_values[1][index+2] = WS_H[2];
  61. led_color_seq_values[1][index+3] = WS_H[3];
  62. }else{
  63. led_color_seq_values[1][index+0] = WS_L[0];
  64. led_color_seq_values[1][index+1] = WS_L[1];
  65. led_color_seq_values[1][index+2] = WS_L[2];
  66. led_color_seq_values[1][index+3] = WS_L[3];
  67. }
  68. index = i*4;
  69. if(col_b & t){
  70. led_color_seq_values[2][index+0] = WS_H[0];
  71. led_color_seq_values[2][index+1] = WS_H[1];
  72. led_color_seq_values[2][index+2] = WS_H[2];
  73. led_color_seq_values[2][index+3] = WS_H[3];
  74. }else{
  75. led_color_seq_values[2][index+0] = WS_L[0];
  76. led_color_seq_values[2][index+1] = WS_L[1];
  77. led_color_seq_values[2][index+2] = WS_L[2];
  78. led_color_seq_values[2][index+3] = WS_L[3];
  79. }
  80. t = t>>1;
  81. }
  82. }
  83. void WS2812_SetColor(uint8_t n,uint32_t color)
  84. {
  85. if(n>=MEMBER_NUM_OF_WS2812) return;
  86. m_wsled[n].color = color;
  87. reflash = 1;
  88. }
  89. void WS2812_Start(uint8_t n,uint32_t color)
  90. {
  91. if(n>=MEMBER_NUM_OF_WS2812) return;
  92. if(m_wsled[n].onoff>0) return;
  93. m_wsled[n].onoff = 1;
  94. m_wsled[n].color = color;
  95. reflash = 1;
  96. }
  97. void WS2812_Resum(uint8_t n)
  98. {
  99. if(n>=MEMBER_NUM_OF_WS2812) return;
  100. if(m_wsled[n].onoff>0) return;
  101. m_wsled[n].onoff = 1;
  102. reflash = 1;
  103. }
  104. void WS2812_Stop(uint8_t n)
  105. {
  106. if(n>=MEMBER_NUM_OF_WS2812) return;
  107. if(m_wsled[n].onoff==0) return;
  108. m_wsled[n].onoff = 0;
  109. reflash = 1;
  110. }
  111. static void hal_WS2812_Process(void)
  112. {
  113. int i;
  114. static uint8_t state = 0;
  115. switch(state){
  116. case 0:{
  117. if(reflash>0){ reflash = 0;
  118. for(i=MEMBER_NUM_OF_WS2812-1;i>0;i--){ //显示优先级最高的灯
  119. if(m_wsled[i].onoff>0){ //SEGGER_RTT_printf(0,"hal_WS2812_Process->play[%d]\n",i);
  120. WS2812_DisplayDot(m_wsled[i].color);
  121. break;
  122. }
  123. }
  124. if(i==0) nrf_gpio_pin_write(PIN_RGB_ENABLE,WS2812_DISABLE); //无灯显示,关闭电源
  125. else{
  126. nrf_gpio_pin_write(PIN_RGB_ENABLE,WS2812_ENABLE); //打开灯电源
  127. state = 1;
  128. }
  129. }
  130. break;}
  131. case 1:{
  132. PWM_SetSimplePwmPlayBack(led_color_seq, WS2812_DISPLAY_NUMBER, PWM_FLAG_STOP);
  133. #if WS2812_FLASH_ALWAYS
  134. if(reflash>0) state = 0;
  135. #else
  136. state = 0;
  137. #endif
  138. break;}
  139. default:state = 0;break;
  140. }
  141. }
  142. #if DEBUG_LEDRUN
  143. void WS2812_Test(void)
  144. {
  145. static uint8_t flag = 0;
  146. if(flag==0){ flag = 1;
  147. WS2812_SetColor(WS2812_TEST,WS2812_COLOR_BLACK);
  148. }else if(flag==1){ flag = 2;
  149. WS2812_SetColor(WS2812_TEST,WS2812_COLOR_RED);
  150. }else if(flag==2){ flag = 3;
  151. WS2812_SetColor(WS2812_TEST,WS2812_COLOR_GREEN);
  152. }else if(flag==3){ flag = 4;
  153. WS2812_SetColor(WS2812_TEST,WS2812_COLOR_BLUE);
  154. }else if(flag==4){ flag = 5;
  155. WS2812_SetColor(WS2812_TEST,WS2812_COLOR_ORANGE);
  156. }else if(flag==5){ flag = 6;
  157. WS2812_SetColor(WS2812_TEST,WS2812_COLOR_WHITE);
  158. }else if(flag==6){ flag = 7;
  159. WS2812_Stop(WS2812_TEST);
  160. }else if(flag==7){ flag = 0;
  161. WS2812_Resum(WS2812_TEST);
  162. }
  163. }
  164. #endif
  165. void WS2812_Initialize(void)
  166. {
  167. PWM_SetBaseClock(NRF_PWM_CLK_8MHz);
  168. PWM_SetChannels(PIN_RGB_DAT, NRF_DRV_PWM_PIN_NOT_USED, NRF_DRV_PWM_PIN_NOT_USED, NRF_DRV_PWM_PIN_NOT_USED);
  169. PWM_SetDutyCycleThreshold(3); //static uint16_t led_pwm_cycle_time = 3; //1 -> 0.125us
  170. PWM_Initialize();
  171. led_color_seq = PWM_SetComSequence(led_color_seq_values[0], PWM_SEQUENCE_VALUES_LEN(led_color_seq_values),0,0);
  172. nrf_gpio_cfg_output(PIN_RGB_ENABLE);nrf_gpio_pin_write(PIN_RGB_ENABLE,WS2812_ENABLE);
  173. // #if WS2812_FLASH_ALWAYS
  174. // Process_Start(50,"hal_WS2812_Process",hal_WS2812_Process);
  175. // #else
  176. // Process_Start(5,"hal_WS2812_Process",hal_WS2812_Process);
  177. // #endif
  178. Process_Start(5,"hal_WS2812_Process",hal_WS2812_Process);
  179. #if DEBUG_LEDRUN
  180. Process_Start(500,"WS2812_Test",WS2812_Test);
  181. WS2812_Start(WS2812_TEST,WS2812_COLOR_BLACK);
  182. #endif
  183. }