backlight_led.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. Copyright 2016 Ralf Schmitt <ralf@bunkertor.net>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include <avr/interrupt.h>
  15. #include <avr/io.h>
  16. #include <stdbool.h>
  17. #include <util/delay.h>
  18. #include <stdint.h>
  19. #include "backlight_led.h"
  20. #include "quantum.h"
  21. // #include "led.h"
  22. #define T1H 900
  23. #define T1L 600
  24. #define T0H 400
  25. #define T0L 900
  26. #define RES 6000
  27. #define NS_PER_SEC (1000000000L)
  28. #define CYCLES_PER_SEC (F_CPU)
  29. #define NS_PER_CYCLE (NS_PER_SEC / CYCLES_PER_SEC)
  30. #define NS_TO_CYCLES(n) ((n) / NS_PER_CYCLE)
  31. void send_bit_d4(bool bitVal)
  32. {
  33. if(bitVal) {
  34. asm volatile (
  35. "sbi %[port], %[bit] \n\t"
  36. ".rept %[onCycles] \n\t"
  37. "nop \n\t"
  38. ".endr \n\t"
  39. "cbi %[port], %[bit] \n\t"
  40. ".rept %[offCycles] \n\t"
  41. "nop \n\t"
  42. ".endr \n\t"
  43. ::
  44. [port] "I" (_SFR_IO_ADDR(PORTD)),
  45. [bit] "I" (4),
  46. [onCycles] "I" (NS_TO_CYCLES(T1H) - 2),
  47. [offCycles] "I" (NS_TO_CYCLES(T1L) - 2));
  48. } else {
  49. asm volatile (
  50. "sbi %[port], %[bit] \n\t"
  51. ".rept %[onCycles] \n\t"
  52. "nop \n\t"
  53. ".endr \n\t"
  54. "cbi %[port], %[bit] \n\t"
  55. ".rept %[offCycles] \n\t"
  56. "nop \n\t"
  57. ".endr \n\t"
  58. ::
  59. [port] "I" (_SFR_IO_ADDR(PORTD)),
  60. [bit] "I" (4),
  61. [onCycles] "I" (NS_TO_CYCLES(T0H) - 2),
  62. [offCycles] "I" (NS_TO_CYCLES(T0L) - 2));
  63. }
  64. }
  65. void send_bit_d6(bool bitVal)
  66. {
  67. if(bitVal) {
  68. asm volatile (
  69. "sbi %[port], %[bit] \n\t"
  70. ".rept %[onCycles] \n\t"
  71. "nop \n\t"
  72. ".endr \n\t"
  73. "cbi %[port], %[bit] \n\t"
  74. ".rept %[offCycles] \n\t"
  75. "nop \n\t"
  76. ".endr \n\t"
  77. ::
  78. [port] "I" (_SFR_IO_ADDR(PORTD)),
  79. [bit] "I" (6),
  80. [onCycles] "I" (NS_TO_CYCLES(T1H) - 2),
  81. [offCycles] "I" (NS_TO_CYCLES(T1L) - 2));
  82. } else {
  83. asm volatile (
  84. "sbi %[port], %[bit] \n\t"
  85. ".rept %[onCycles] \n\t"
  86. "nop \n\t"
  87. ".endr \n\t"
  88. "cbi %[port], %[bit] \n\t"
  89. ".rept %[offCycles] \n\t"
  90. "nop \n\t"
  91. ".endr \n\t"
  92. ::
  93. [port] "I" (_SFR_IO_ADDR(PORTD)),
  94. [bit] "I" (6),
  95. [onCycles] "I" (NS_TO_CYCLES(T0H) - 2),
  96. [offCycles] "I" (NS_TO_CYCLES(T0L) - 2));
  97. }
  98. }
  99. void show(void)
  100. {
  101. _delay_us((RES / 1000UL) + 1);
  102. }
  103. void send_value(uint8_t byte, enum Device device)
  104. {
  105. for(uint8_t b = 0; b < 8; b++) {
  106. if(device == Device_STATELED) {
  107. send_bit_d4(byte & 0b10000000);
  108. }
  109. if(device == Device_PCBRGB) {
  110. send_bit_d6(byte & 0b10000000);
  111. }
  112. byte <<= 1;
  113. }
  114. }
  115. void send_color(uint8_t r, uint8_t g, uint8_t b, enum Device device)
  116. {
  117. send_value(g, device);
  118. send_value(r, device);
  119. send_value(b, device);
  120. }