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.
 
 
 

249 lines
6.9 KiB

  1. /***************************************************************************
  2. * Copyright (C) 11/2014 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/pgmspace.h>
  22. #include "event.h"
  23. #include "pwm.h"
  24. #include "target.h"
  25. /* *********************************************************************** */
  26. #if (PWM_TIM_16BIT)
  27. #define PWM_TABLE_SIZE 128
  28. #define PWM_TABLE_GET(x) pgm_read_word(&pwmtable16[x])
  29. const uint16_t pwmtable16[PWM_TABLE_SIZE] PROGMEM =
  30. {
  31. 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5,
  32. 6, 6, 7, 8, 9, 9, 10, 11, 12, 14, 15, 16, 18, 20, 22, 24, 26,
  33. 28, 31, 34, 37, 40, 44, 48, 53, 58, 63, 69, 75, 82, 90, 98,
  34. 107, 116, 127, 139, 151, 165, 180, 196, 214, 234, 255, 278,
  35. 303, 331, 361, 394, 430, 469, 511, 557, 608, 663, 723, 789,
  36. 860, 938, 1023, 1116, 1217, 1327, 1447, 1578, 1721, 1877,
  37. 2047, 2232, 2434, 2655, 2895, 3157, 3443, 3755, 4095, 4466,
  38. 4870, 5311, 5792, 6316, 6888, 7511, 8191, 8932, 9741, 10623,
  39. 11584, 12633, 13776, 15023, 16383, 17866, 19483, 21246, 23169,
  40. 25267, 27553, 30047, 32767, 35733, 38967, 42494, 46340, 50534,
  41. 55108, 60096, 65535
  42. };
  43. #else
  44. #define PWM_TABLE_SIZE 32
  45. #define PWM_TABLE_GET(x) pgm_read_byte(&pwmtable8[x])
  46. const uint8_t pwmtable8[PWM_TABLE_SIZE] PROGMEM =
  47. {
  48. 0, 0, 1, 1, 1, 2, 2, 3,
  49. 4, 5, 6, 7, 9, 10, 12, 15,
  50. 18, 22, 26, 31, 37, 44, 53, 63,
  51. 75, 90, 107, 127, 151, 180, 214, 255
  52. };
  53. #endif
  54. static uint8_t pwm_index[2];
  55. static uint8_t pwm_setpoint[2];
  56. static uint8_t pwm_setpoint_save[2];
  57. /* *********************************************************************** */
  58. void pwm_event_handler(struct event_entry *event)
  59. {
  60. uint8_t channel = event->num;
  61. if (event->type == EVENT_TYPE_PWM_COMMAND)
  62. {
  63. switch (event->value)
  64. {
  65. case EVENT_VALUE_PWM_KEEP:
  66. pwm_setpoint[channel] = pwm_index[channel];
  67. break;
  68. /* increment PWM */
  69. case EVENT_VALUE_PWM_INC:
  70. if (pwm_setpoint[channel] < (PWM_TABLE_SIZE -1))
  71. {
  72. pwm_setpoint[channel]++;
  73. }
  74. break;
  75. /* decrement PWM */
  76. case EVENT_VALUE_PWM_DEC:
  77. if (pwm_setpoint[channel] > 0)
  78. {
  79. pwm_setpoint[channel]--;
  80. }
  81. break;
  82. /* fade to min */
  83. case EVENT_VALUE_PWM_FADE_MIN:
  84. pwm_setpoint[channel] = 0;
  85. break;
  86. /* fade to max */
  87. case EVENT_VALUE_PWM_FADE_MAX:
  88. pwm_setpoint[channel] = (PWM_TABLE_SIZE -1);
  89. break;
  90. case EVENT_VALUE_PWM_TOGGLE:
  91. if (pwm_setpoint[channel] > 5)
  92. {
  93. pwm_setpoint_save[channel] = pwm_setpoint[channel];
  94. pwm_setpoint[channel] = 0;
  95. }
  96. else
  97. {
  98. pwm_setpoint[channel] = pwm_setpoint_save[channel];
  99. }
  100. break;
  101. default:
  102. break;
  103. }
  104. PWM_TIM_ENABLE();
  105. }
  106. else if (event->type == EVENT_TYPE_PWM_VALUE)
  107. {
  108. if (event->value < PWM_TABLE_SIZE)
  109. {
  110. pwm_setpoint[event->num] = event->value;
  111. }
  112. else
  113. {
  114. pwm_setpoint[event->num] = (PWM_TABLE_SIZE -1);
  115. }
  116. PWM_TIM_ENABLE();
  117. }
  118. } /* pwm_event_handler */
  119. static void pwm_update(uint8_t channel)
  120. {
  121. if ((pwm_setpoint[channel] > pwm_index[channel]) &&
  122. (pwm_index[channel] < (PWM_TABLE_SIZE -1))
  123. )
  124. {
  125. pwm_index[channel]++;
  126. /* setpoint reached, notify others */
  127. if (pwm_index[channel] == pwm_setpoint[channel])
  128. {
  129. event_queue(EVENT_TYPE_PWM_STATUS,
  130. channel,
  131. pwm_setpoint[channel]);
  132. }
  133. }
  134. else if ((pwm_setpoint[channel] < pwm_index[channel]) &&
  135. (pwm_index[channel] > 0)
  136. )
  137. {
  138. pwm_index[channel]--;
  139. /* setpoint reached, notify others */
  140. if (pwm_index[channel] == pwm_setpoint[channel])
  141. {
  142. event_queue(EVENT_TYPE_PWM_STATUS,
  143. channel,
  144. pwm_setpoint[channel]);
  145. }
  146. }
  147. /* if PWM is zero, disable output */
  148. if (pwm_index[channel] == 0)
  149. {
  150. if (channel == 0)
  151. {
  152. PWM_CH0_OFF();
  153. }
  154. else
  155. {
  156. PWM_CH1_OFF();
  157. }
  158. }
  159. /* if PWM is max, enable output */
  160. else if (pwm_index[channel] == (PWM_TABLE_SIZE -1))
  161. {
  162. if (channel == 0)
  163. {
  164. PWM_CH0_ON();
  165. }
  166. else
  167. {
  168. PWM_CH1_ON();
  169. }
  170. }
  171. /* else load new PWM into timer */
  172. else
  173. {
  174. if (channel == 0)
  175. {
  176. PWM_CH0_PWM(PWM_TABLE_GET(pwm_index[0]));
  177. }
  178. else
  179. {
  180. PWM_CH1_PWM(PWM_TABLE_GET(pwm_index[1]));
  181. }
  182. }
  183. } /* pwm_set */
  184. ISR(PWM_TIM_VECT)
  185. {
  186. static uint8_t delay;
  187. delay++;
  188. if (delay == PWM_DELAY_COUNT)
  189. {
  190. delay = 0;
  191. /* update PWM values */
  192. pwm_update(0);
  193. pwm_update(1);
  194. /* disable timer if both channels are ON or OFF */
  195. if (PWM_TIM_CHECK())
  196. {
  197. PWM_TIM_ENABLE();
  198. }
  199. else
  200. {
  201. PWM_TIM_DISABLE();
  202. }
  203. }
  204. } /* TIM1_OVF_vect */
  205. uint8_t pwm_get_sleep_mode(void)
  206. {
  207. if (PWM_TIM_RUNNING())
  208. {
  209. return SLEEP_MODE_IDLE;
  210. }
  211. else
  212. {
  213. return SLEEP_MODE_PWR_DOWN;
  214. }
  215. } /* pwm_get_sleep_mode */
  216. void pwm_init(void)
  217. {
  218. PWM_TIM_INIT();
  219. } /* pwm_init */