led_spi.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include "led_spi.h"
  2. #include "configuration.h"
  3. #include <HardwarePWM.h>
  4. /* Private defines */
  5. #define LED_NUM 4
  6. #define LED_REFRESH_MS 3
  7. #define PinSet(pin) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, ((uint16_t)1<<(pin)))
  8. #define PinRes(pin) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, ((uint16_t)1<<(pin)))
  9. #define PIN_CLK 14
  10. #define PIN_DOUT 13
  11. #define PIN_LOAD 12
  12. #define PIN_OUTE 0
  13. /* Private typedefs */
  14. typedef enum t_led_pos {
  15. pos_led1 = 0x1,
  16. pos_led2 = 0x2,
  17. pos_led3 = 0x4,
  18. pos_led4 = 0x8
  19. } led_pos_t;
  20. typedef enum t_segment {
  21. seg_A = 0x01,
  22. seg_B = 0x02,
  23. seg_C = 0x04,
  24. seg_D = 0x08,
  25. seg_E = 0x10,
  26. seg_F = 0x20,
  27. seg_G = 0x40,
  28. seg_DP = 0x80
  29. } segment_t;
  30. /* LED Symbol map:
  31. A
  32. F B
  33. G
  34. E C
  35. D DP
  36. */
  37. typedef enum t_led_symb {
  38. sym_Blank = 0x0,
  39. sym_0 = (uint8_t)(seg_A | seg_B | seg_C | seg_D | seg_E | seg_F),
  40. sym_1 = (uint8_t)(seg_B | seg_C),
  41. sym_2 = (uint8_t)(seg_A | seg_B | seg_G | seg_E | seg_D),
  42. sym_3 = (uint8_t)(seg_A | seg_B | seg_G | seg_C | seg_D),
  43. sym_4 = (uint8_t)(seg_F | seg_G | seg_B | seg_C),
  44. sym_5 = (uint8_t)(seg_A | seg_F | seg_G | seg_C | seg_D),
  45. sym_6 = (uint8_t)(seg_A | seg_F | seg_G | seg_E | seg_D | seg_C),
  46. sym_7 = (uint8_t)(seg_A | seg_B | seg_C),
  47. sym_8 = (uint8_t)(seg_A | seg_B | seg_C | seg_D | seg_E | seg_F | seg_G),
  48. sym_9 = (uint8_t)(seg_A | seg_B | seg_C | seg_D | seg_G | seg_F),
  49. sym_DP = seg_DP
  50. } led_symb_t;
  51. /* Private variables */
  52. static const led_pos_t led_pos[LED_NUM] = {
  53. pos_led1, pos_led2, pos_led3, pos_led4
  54. };
  55. static const led_symb_t led_dig[10] = {
  56. sym_0, sym_1, sym_2, sym_3, sym_4, sym_5, sym_6, sym_7, sym_8, sym_9
  57. };
  58. static led_symb_t led_bufer[LED_NUM] = {sym_Blank, sym_Blank, sym_Blank, sym_Blank};
  59. static Timer ledTimer;
  60. static uint8_t hw_pwm_pins[1] = {PIN_OUTE};
  61. static HardwarePWM OE_pwm(hw_pwm_pins, 1);
  62. static uint32 MaxDuty, DutyStep;
  63. /* Private functions */
  64. void LED_writeData (led_pos_t pos, led_symb_t data) {
  65. //PinRes(PIN_LOAD); // down latch
  66. // software spi
  67. uint8_t i;
  68. uint16_t sdata = (pos << 8) | data;
  69. for (i = 16; i != 0; i--) {
  70. PinRes(PIN_CLK); // prepare CLK
  71. if (sdata & 0x8000) {
  72. // if msb bit 1
  73. PinSet(PIN_DOUT); // MOSI = 1
  74. } else {
  75. // if msb bit 0
  76. PinRes(PIN_DOUT); // MOSI = 0
  77. }
  78. asm("nop;");
  79. PinSet(PIN_CLK); // lock CLK
  80. sdata <<= 1;
  81. }
  82. asm("nop;");
  83. PinSet(PIN_LOAD); // up latch
  84. asm("nop;");
  85. PinRes(PIN_CLK);
  86. PinRes(PIN_LOAD);
  87. }
  88. void LED_ShowLed(void) {
  89. static uint8_t cnt = 0;
  90. LED_writeData(led_pos[cnt], sym_Blank);
  91. cnt ++;
  92. if (cnt >= LED_NUM) {
  93. cnt = 0;
  94. }
  95. LED_writeData(led_pos[cnt], led_bufer[cnt]);
  96. }
  97. /* Exported functions */
  98. void LED_Init (void) {
  99. Serial.println("BIG LED SPI init!");
  100. /* pinMode(PIN_OUTE, OUTPUT);
  101. PinRes(PIN_OUTE); // output enable
  102. */
  103. MaxDuty = OE_pwm.getMaxDuty();
  104. DutyStep = MaxDuty / LedBrightMax;
  105. LED_SetBright(LedBrightMiddl);
  106. /* prepare soft spi */
  107. pinMode(PIN_DOUT, OUTPUT);
  108. pinMode(PIN_CLK, OUTPUT);
  109. pinMode(PIN_LOAD, OUTPUT);
  110. PinRes(PIN_CLK);
  111. PinRes(PIN_LOAD);
  112. /* Start timer for refresh leds */
  113. ledTimer.initializeMs(LED_REFRESH_MS, LED_ShowLed).start();
  114. }
  115. /**
  116. * @brief Show two Bin number to LED
  117. *
  118. * @param hbin High/Left Bin value 0..99
  119. * @param lbin Low/Right Bin Value 0..99
  120. */
  121. void LED_ShowBin(uint8_t hbin, uint8_t lbin) {
  122. uint8_t a = hbin / 10;
  123. uint8_t b = hbin % 10;
  124. uint8_t c = lbin / 10;
  125. uint8_t d = lbin % 10;
  126. if (a > 9) { a = 9; }
  127. if (b > 9) { b = 9; }
  128. if (c > 9) { c = 9; }
  129. if (d > 9) { d = 9; }
  130. led_bufer[0] = led_dig[a];
  131. led_bufer[1] = led_dig[b];
  132. led_bufer[2] = led_dig[c];
  133. led_bufer[3] = led_dig[d];
  134. }
  135. /**
  136. * @brief Set value 0..9 in single led
  137. *
  138. * @param pos Led num 0..3
  139. * @param bin Bin value 0..9
  140. */
  141. void LED_ShowBinPos(uint8_t pos, uint8_t bin) {
  142. if (pos >= LED_NUM) { return; }
  143. if (bin > 9) { bin = 9; }
  144. led_bufer[pos] = led_dig[bin];
  145. }
  146. /**
  147. * @brief On semicolon
  148. */
  149. void LED_SemicolonOn(void) {
  150. led_bufer[1] = led_symb_t((uint8_t)led_bufer[1] | (uint8_t)sym_DP);
  151. led_bufer[2] = led_symb_t((uint8_t)led_bufer[2] | (uint8_t)sym_DP);
  152. }
  153. /**
  154. * @brief Off semicolon
  155. */
  156. void LED_SemicolonOFF(void) {
  157. led_bufer[1] = led_symb_t((uint8_t)led_bufer[1] & ~((uint8_t)sym_DP));
  158. led_bufer[2] = led_symb_t((uint8_t)led_bufer[2] & ~((uint8_t)sym_DP));
  159. }
  160. /**
  161. * @brief Set LED bright.
  162. *
  163. * @param bright Percent value 0..100
  164. */
  165. void LED_SetBright(uint8_t bright) {
  166. if (bright > LedBrightMax) { bright = LedBrightMax;}
  167. bright = LedBrightMax - bright;
  168. uint32 new_duty = DutyStep * bright; //MaxDuty * bright / LedBrightMax;
  169. OE_pwm.setDutyChan(0, bright);
  170. }