AVR based brushless motor controller
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.

130 lines
3.2 KiB

14 years ago
  1. /***************************************************************************
  2. * Copyright (C) 09/2007 by Olaf Rempel *
  3. * razzor@kopf-tisch.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; version 2 of the License, *
  8. * *
  9. * This program is distributed in the hope that it will be useful, *
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  12. * GNU General Public License for more details. *
  13. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. ***************************************************************************/
  19. #include <avr/io.h>
  20. #include <avr/interrupt.h>
  21. #include <avr/wdt.h>
  22. #include "main.h"
  23. #include "blmc.h"
  24. extern struct blmc_ blmc;
  25. #define CMD_NONE 0x00
  26. #define CMD_SETPWM 0x10
  27. #define CMD_GETSTAT 0x20
  28. #define CMD_REBOOT 0x80
  29. ISR(TWI_vect)
  30. {
  31. static uint8_t cmd = CMD_NONE;
  32. switch (TWSR & 0xF8) {
  33. /* SLA + W received, ACK returned -> receive Data and ACK */
  34. case 0x60:
  35. cmd = CMD_NONE;
  36. TWCR |= (1<<TWINT) | (1<<TWEA);
  37. break;
  38. /* prev. SLA + W, data received, ACK returned -> receive Data and ACK */
  39. case 0x80:
  40. switch (cmd & 0xF0) {
  41. /* First bytes -> Command */
  42. case CMD_NONE:
  43. cmd = TWDR;
  44. break;
  45. /* set pwm */
  46. case CMD_SETPWM:
  47. setpwm(TWDR);
  48. cmd = CMD_NONE;
  49. break;
  50. /* set parameters */
  51. case CMD_REBOOT:
  52. if (TWDR == 0x42)
  53. wdt_enable(WDTO_15MS);
  54. cmd = CMD_NONE;
  55. break;
  56. /* rest invalid */
  57. default:
  58. cmd = CMD_NONE;
  59. break;
  60. }
  61. TWCR |= (1<<TWINT);
  62. break;
  63. /* SLA+R received, ACK returned -> send data */
  64. case 0xA8:
  65. /* prev. SLA+R, data sent, ACK returned -> send data */
  66. case 0xB8:
  67. switch (cmd & 0xF0) {
  68. /* get Current */
  69. case CMD_GETSTAT:
  70. switch (cmd++ & 0x0F) {
  71. case 0: TWDR = blmc.pwm - blmc.pwm_limit;
  72. break;
  73. case 1: TWDR = blmc.pwm;
  74. break;
  75. case 2: TWDR = (blmc.rpm >> 8);
  76. break;
  77. case 3: TWDR = (blmc.rpm & 0xFF);
  78. break;
  79. case 4: TWDR = (blmc.current >> 8);
  80. break;
  81. case 5: TWDR = (blmc.current & 0xFF);
  82. break;
  83. case 6: TWDR = (blmc.voltage >> 8);
  84. break;
  85. case 7: TWDR = (blmc.voltage & 0xFF);
  86. cmd = CMD_NONE;
  87. break;
  88. }
  89. break;
  90. /* rest invalid */
  91. default:
  92. cmd = CMD_NONE;
  93. break;
  94. }
  95. TWCR |= (1<<TWINT);
  96. break;
  97. /* STOP or repeated START */
  98. case 0xA0:
  99. /* Data transmitted, NACK returned */
  100. case 0xC0:
  101. TWCR |= (1<<TWINT) | (1<<TWEA);
  102. break;
  103. /* Illegal state -> reset Hardware */
  104. case 0xF8:
  105. TWCR |= (1<<TWINT) | (1<<TWSTO) | (1<<TWEA);
  106. break;
  107. }
  108. }