選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

74 行
1.7KB

  1. #include "WS2812Serial.h"
  2. void WS2812Serial::begin()
  3. {
  4. if (!uart) return;
  5. if (!dma) dma = new DMAChannel;
  6. if (!dma) return;
  7. SIM_SCGC4 |= SIM_SCGC4_UART0;
  8. uint32_t divisor = BAUD2DIV(2400000);
  9. CORE_PIN1_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3);
  10. UART0_BDH = (divisor >> 13) & 0x1F;
  11. UART0_BDL = (divisor >> 5) & 0xFF;
  12. UART0_C4 = divisor & 0x1F;
  13. UART0_C1 = 0;
  14. UART0_PFIFO = 0;
  15. UART0_C2 = UART_C2_TE;
  16. UART0_C3 = UART_C3_TXINV;
  17. UART0_C5 = UART_C5_TDMAS;
  18. memset(drawBuffer, 0, numled * 3);
  19. }
  20. void WS2812Serial::show()
  21. {
  22. //UART0_D = 0xDB;
  23. //UART0_D = 0xDA;
  24. //UART0_D = 0xDB;
  25. const uint8_t *p = drawBuffer;
  26. const uint8_t *end = p + (numled * 3);
  27. uint8_t *fb = frameBuffer;
  28. while (p < end) {
  29. uint8_t b = *p++;
  30. uint8_t g = *p++;
  31. uint8_t r = *p++;
  32. uint32_t n=0;
  33. switch (config) {
  34. case WS2812_RGB: n = (r << 16) | (g << 8) | b; break;
  35. case WS2812_RBG: n = (r << 16) | (b << 8) | g; break;
  36. case WS2812_GRB: n = (g << 16) | (r << 8) | b; break;
  37. case WS2812_GBR: n = (g << 16) | (b << 8) | r; break;
  38. case WS2812_BRG: n = (b << 16) | (r << 8) | g; break;
  39. case WS2812_BGR: n = (b << 16) | (g << 8) | r; break;
  40. }
  41. //Serial.printf("n = %06X\n", n);
  42. const uint8_t *stop = fb + 8;
  43. do {
  44. uint8_t x = 0x92;
  45. if (!(n & 0x00800000)) x |= 0x01;
  46. if (!(n & 0x00400000)) x |= 0x04;
  47. if (!(n & 0x00200000)) x |= 0x20;
  48. n <<= 3;
  49. *fb++ = x;
  50. } while (fb < stop);
  51. }
  52. dma->sourceBuffer(frameBuffer, numled * 8);
  53. dma->destination(UART0_D);
  54. dma->transferSize(1);
  55. dma->transferCount(numled * 8);
  56. dma->disableOnCompletion();
  57. dma->triggerAtHardwareEvent(DMAMUX_SOURCE_UART0_TX);
  58. dma->enable();
  59. UART0_C2 = UART_C2_TE | UART_C2_TIE;
  60. }