MPM controlled 16ch RGB LED dimmer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
4.9KB

  1. /***************************************************************************
  2. * mpm comms *
  3. * *
  4. * Copyright (C) 2011 - 2012 by Olaf Rempel *
  5. * razzor AT kopf MINUS tisch DOT de *
  6. * *
  7. * This program is free software; you can redistribute it and/or modify *
  8. * it under the terms of the GNU General Public License as published by *
  9. * the Free Software Foundation; version 2 of the License, *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * You should have received a copy of the GNU General Public License *
  17. * along with this program; if not, write to the *
  18. * Free Software Foundation, Inc., *
  19. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  20. ***************************************************************************/
  21. #include <avr/io.h>
  22. #include <avr/interrupt.h>
  23. #include <avr/wdt.h>
  24. #include "rgb16mpm.h"
  25. #define CMD_WAIT 0x00
  26. #define CMD_SWITCH_MODE 0x01
  27. #define CMD_GET_VERSION 0x02
  28. #define CMD_GET_CHIPINFO 0x03 /* bootloader / mpmboot */
  29. #define CMD_READ_MEMORY 0x11 /* bootloader / mpmboot */
  30. #define CMD_WRITE_MEMORY 0x12 /* bootloader / mpmboot */
  31. #define CMD_WRITE_COLOR 0x81
  32. #define CMD_WRITE_RAW_COLOR 0x82
  33. #define CMD_READ_RAW_COLOR 0x83
  34. #define CMD_WRITE_CONFIG 0x81
  35. #define UART_CALC_BAUDRATE(baudRate) (((uint32_t)F_CPU) / (((uint32_t)baudRate)*16) -1)
  36. const static uint8_t versioninfo[16] = "rgb16mpm v0.99";
  37. static uint8_t rx_cmd;
  38. static uint16_t rx_bcnt = 0xFF;
  39. static uint16_t rx_length;
  40. static uint8_t tx_cmd;
  41. static uint8_t tx_cause;
  42. static uint16_t tx_length;
  43. static uint16_t tx_bcnt;
  44. ISR(USART_RXC_vect)
  45. {
  46. uint8_t data = UDR;
  47. sei();
  48. if (rx_bcnt == 0xFF) {
  49. /* MPM address stored in TWI address register by bootloader */
  50. if (data == TWAR) {
  51. UCSRA &= ~(1<<MPCM);
  52. rx_bcnt = 0;
  53. }
  54. } else {
  55. if (rx_bcnt == 0) {
  56. rx_cmd = data;
  57. } else if ((rx_bcnt == 1) || (rx_bcnt == 2)) {
  58. rx_length = (rx_length << 8) | data;
  59. } else if ((rx_bcnt -3) < rx_length) {
  60. // TODO: get data
  61. }
  62. if ((rx_bcnt -2) == rx_length) {
  63. /* enable RS485 TX */
  64. PORTD |= (1<<RXTX);
  65. /* first byte */
  66. tx_cmd = rx_cmd;
  67. UDR = rx_cmd;
  68. /* prepare header */
  69. tx_bcnt = 1;
  70. tx_cause = 0;
  71. tx_length = 0;
  72. if (tx_cmd == CMD_GET_VERSION) {
  73. tx_length = sizeof(versioninfo);
  74. }
  75. /* enable interrupt */
  76. UCSRB |= (1<<UDRIE);
  77. }
  78. rx_bcnt++;
  79. }
  80. }
  81. ISR(USART_UDRE_vect)
  82. {
  83. /* enable IRQs again, but prevent multiple UDRE IRQs */
  84. UCSRB &= ~(1<<UDRIE);
  85. sei();
  86. if ((tx_bcnt < 4) || (tx_bcnt -4) < tx_length) {
  87. uint16_t pos = (tx_bcnt -4);
  88. uint8_t data = 0xFF;
  89. if (tx_bcnt == 1) {
  90. data = tx_cause;
  91. } else if (tx_bcnt == 2) {
  92. data = (tx_length >> 8);
  93. } else if (tx_bcnt == 3) {
  94. data = (tx_length & 0xFF);
  95. } else if (tx_cmd == CMD_GET_VERSION) {
  96. data = versioninfo[pos];
  97. } else {
  98. data = 0xAA;
  99. }
  100. UDR = data;
  101. /* re-enable for next round */
  102. UCSRB |= (1<<UDRIE);
  103. }
  104. tx_bcnt++;
  105. }
  106. ISR(USART_TXC_vect, ISR_NOBLOCK)
  107. {
  108. /* disable RS485 TX */
  109. PORTD &= ~(1<<RXTX);
  110. /* enable MP mode again */
  111. UCSRA |= (1<<MPCM);
  112. rx_bcnt = 0xFF; // FIXME: cli?
  113. #if !(STANDALONE)
  114. if (tx_cmd == CMD_SWITCH_MODE) { // FIXME: check mode
  115. wdt_enable(WDTO_15MS);
  116. }
  117. #endif /* !(STANDALONE) */
  118. }
  119. void mpm_init(void)
  120. {
  121. PORTD &= ~(1<<RXTX);
  122. DDRD |= (1<<RXTX);
  123. /* USART config */
  124. /* Multi Drop Mode, 9n1 */
  125. UCSRA = (1<<MPCM);
  126. UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<RXCIE) | (1<<TXCIE) | (1<<UCSZ2);
  127. UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
  128. #if (STANDALONE)
  129. OSCCAL = OSCCAL_VALUE;
  130. UBRRH = (UART_CALC_BAUDRATE(BAUDRATE)>>8) & 0xFF;
  131. UBRRL = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF);
  132. /* MPM address stored in TWI address register */
  133. TWAR = MPM_ADDRESS;
  134. #endif /* (STANDALONE) */
  135. }