Mercurial > controller
annotate pwm.cpp @ 1:7b2d0a758e63
Add pcb and finish i2c slave
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Tue, 12 Jan 2016 22:28:22 +0100 |
| parents | 2b5078b37907 |
| children |
| rev | line source |
|---|---|
|
0
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
1 #include "pwm.h" |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
2 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
3 typedef struct pwm_pin_t { |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
4 volatile uint8_t *port; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
5 uint8_t pin; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
6 uint16_t compare_value; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
7 } pwm_pin_t; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
8 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
9 typedef struct pwm_event_t { |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
10 //Only used in OCR1B; ignored for high event in OCR1A. This is the value which TCNT1 is firing |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
11 // on *now*; you need to reference the next element in the array to get the value which is |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
12 // to be reset for next time. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
13 uint16_t compare_value; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
14 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
15 //Port masks |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
16 #ifndef PWM_PORTA_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
17 uint8_t porta_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
18 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
19 #ifndef PWM_PORTB_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
20 uint8_t portb_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
21 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
22 #ifndef PWM_PORTC_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
23 uint8_t portc_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
24 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
25 #ifndef PWM_PORTD_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
26 uint8_t portd_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
27 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
28 } pwm_event_t; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
29 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
30 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
31 volatile void* _pwm_events_low_ptr; //Pointer to current value in _pwm_events_low. Reset in OCR1A, incremented in OCR1B. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
32 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
33 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
34 static uint8_t _set_phase_batch = 0; //Set to 1 when set_phase_batch is called with a changed value. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
35 static volatile uint8_t _set_phase = 0; //Set to 1 when phase is re-calculated; signals that the ISR COMPA needs to re-load phase values. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
36 static volatile uint8_t _set_phase_lock = 0; //Set to 1 when we are in set_phase function. Prevents OCR1A from copying the double buffered pwm_events when this is 0. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
37 static volatile uint8_t _set_stop = 0; //Set to 1 when stop is requested. ISR COMPA will turn off timer. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
38 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
39 static uint16_t _set_period = 0; //New period defined; set in set_period, and updated to OCR1A in changed in COMPA interrupt |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
40 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
41 //Variables used to store config data |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
42 static pwm_pin_t _pwm_pins[PWM_MAX_PINS]; //Array of pins. Index is important here, as that is how we refer to the pins from the outside world. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
43 static uint8_t _count; //How many pins should be used |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
44 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
45 static pwm_event_t _pwm_event_high; //PWM event to set all pins high at start of period. Calculated on a non-zero set_phase. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
46 static pwm_event_t _pwm_event_high_new; //Double buffer of pwm high event; copied to pwm_events in OCR1A when _set_phase is non-zero. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
47 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
48 static pwm_event_t _pwm_events_low[PWM_MAX_PINS + 1]; //Array of pwm events. Each event will set one or more pins low. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
49 static pwm_event_t _pwm_events_low_new[PWM_MAX_PINS + 1]; //Double buffer of pwm events. Calculated in each set_phase call; copied to pwm_events in OCR1A when _set_phase is non-zero. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
50 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
51 static uint16_t _prescaler = 0x0; //Numeric prescaler (1, 8, etc). Required for _pwm_micros_to_clicks calls. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
52 static uint8_t _prescaler_mask = 0x0; //Prescaler mask corresponding to _prescaler |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
53 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
54 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
55 static uint16_t _pwm_micros_to_clicks(uint32_t micros){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
56 //There is a potential for an overflow here if micros * (F_CPU in MHz) does not fit into |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
57 // a 32 bit variable. If this happens, we can divide micros by prescaler before multiplying |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
58 // with F_CPU, although this will give a loss of precision. Leave as-is for now. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
59 return (((F_CPU / 1000000L) * micros) / _prescaler) & 0xFFF0; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
60 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
61 //TODO Rounding, based on 10MHz clock and various prescalers: |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
62 //Prescaler: 1, AND with 0xFF80 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
63 //Prescaler: 8, AND with 0xFFF0 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
64 //Prescaler: 64, AND with 0xFFFE |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
65 //Other prescalers should be fine as-is... |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
66 //More testing at different F_CPU values and prescalers are still required. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
67 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
68 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
69 /* |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
70 * Note: We extrapolate the DDR registers based off of the associated PORT |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
71 * register. This assumes that the DDR registers come directly after the PORT |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
72 * equivalents, with DDRX at the next address after PORTX. This is valid for |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
73 * all the chips I have looked at; however, it is highly recommended that you |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
74 * check any new chips which you want to use this library with. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
75 */ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
76 void pwm_init(volatile uint8_t *ports[], |
|
1
7b2d0a758e63
Add pcb and finish i2c slave
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
0
diff
changeset
|
77 uint8_t pins[], |
|
7b2d0a758e63
Add pcb and finish i2c slave
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
0
diff
changeset
|
78 uint8_t count, |
|
7b2d0a758e63
Add pcb and finish i2c slave
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
0
diff
changeset
|
79 uint32_t period) { |
|
0
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
80 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
81 _count = (count <= PWM_MAX_PINS ? count : PWM_MAX_PINS); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
82 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
83 //Store values |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
84 for (uint8_t i = 0; i < _count; i++){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
85 _pwm_pins[i].port = ports[i]; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
86 _pwm_pins[i].pin = pins[i]; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
87 *(_pwm_pins[i].port - 0x1) |= _BV(_pwm_pins[i].pin); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
88 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
89 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
90 //This is calculated by the focumula: |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
91 // CUTOFF_VALUE = PRESCALER * MAX_VALUE / (F_CPU / 1000000) |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
92 // where CUTOFF_VALUE is the period comparison for each if block, |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
93 // PRESCALER is the prescaler in the datasheet for a given CSx selection, |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
94 // and MAX_VALUE is the largest integer of the selected bit depth (256 / 65536). |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
95 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
96 #ifdef PWM_8_BIT |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
97 uint32_t max_value = 255; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
98 #else |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
99 uint32_t max_value = 65535L; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
100 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
101 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
102 if (period < (1 * max_value / (F_CPU / 1000000L))){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
103 _prescaler = 1; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
104 _prescaler_mask = _BV(CS10); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
105 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
106 else if (period < (8 * max_value / (F_CPU / 1000000L))){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
107 _prescaler = 8; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
108 _prescaler_mask = _BV(CS11); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
109 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
110 else if (period < (64 * max_value / (F_CPU / 1000000L))){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
111 _prescaler = 64; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
112 _prescaler_mask = _BV(CS11) | _BV(CS10); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
113 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
114 else if (period < (256 * max_value / (F_CPU / 1000000L))){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
115 _prescaler = 256; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
116 _prescaler_mask = _BV(CS12); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
117 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
118 else if (period < (1024 * max_value / (F_CPU / 1000000L))){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
119 _prescaler = 1024; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
120 _prescaler_mask = _BV(CS12) | _BV(CS10); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
121 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
122 else { |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
123 period = (1024 * max_value / (F_CPU / 1000000L)); //The largest possible period |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
124 _prescaler = 1024; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
125 _prescaler_mask = _BV(CS12) | _BV(CS10); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
126 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
127 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
128 TCCR1A = 0x00; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
129 TCCR1B &= ~(_BV(CS12) | _BV(CS11) | _BV(CS10)); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
130 TCCR1B |= _prescaler_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
131 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
132 uint16_t clicks = _pwm_micros_to_clicks(period); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
133 //OCR1A controls the PWM period |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
134 OCR1A = clicks; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
135 //OCR1B controls the PWM phase. It is initialized later. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
136 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
137 //Enable compare interrupt on both channels |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
138 TIMSK1 = _BV(OCIE1A) | _BV(OCIE1B); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
139 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
140 //Enable interrupts if the NO_INTERRUPT_ENABLE define is not set. If it is, you need to call sei() elsewhere. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
141 #ifndef NO_INTERRUPT_ENABLE |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
142 sei(); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
143 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
144 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
145 //Force interrupt on compare A initially |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
146 TCCR1C |= _BV(FOC1A); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
147 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
148 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
149 void pwm_start(){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
150 TCNT1 = 0x00; //Restart timer counter |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
151 TIMSK1 = _BV(OCIE1A) | _BV(OCIE1B); //Enable output compare match interrupt enable |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
152 TCCR1B |= _prescaler_mask; //Enable |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
153 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
154 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
155 void pwm_stop(){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
156 _set_stop = 1; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
157 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
158 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
159 //The comparison method used to sort pwm_pin variables |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
160 static int16_t _compare_values(const void *pin1, const void *pin2){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
161 const pwm_pin_t *pwm1 = (const pwm_pin_t*) pin1; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
162 const pwm_pin_t *pwm2 = (const pwm_pin_t*) pin2; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
163 if (pwm1->compare_value < pwm2->compare_value) return -1; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
164 else if (pwm1->compare_value > pwm2->compare_value) return 1; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
165 else return 0; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
166 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
167 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
168 void pwm_set_phase(uint8_t index, uint32_t phase){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
169 pwm_set_phase_batch(index, phase); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
170 pwm_apply_batch(); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
171 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
172 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
173 void pwm_set_phase_batch(uint8_t index, uint32_t phase){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
174 //Bounds checking |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
175 if (index >= _count) { |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
176 return; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
177 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
178 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
179 //The new compare value, in clock ticks |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
180 uint16_t new_clicks = _pwm_micros_to_clicks(phase); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
181 pwm_pin_t *p = &(_pwm_pins[index]); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
182 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
183 if (p->compare_value != new_clicks){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
184 _set_phase_batch = 1; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
185 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
186 //Set the new compare value |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
187 p->compare_value = new_clicks; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
188 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
189 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
190 void pwm_apply_batch(){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
191 if (_set_phase_batch == 0){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
192 return; //No need to re-calculate if there was no changed phases. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
193 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
194 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
195 _set_phase_lock = 1; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
196 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
197 //Copy _pwm_pins to _pwm_pins_sorted, and then sort it by value |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
198 pwm_pin_t _pwm_pins_sorted[PWM_MAX_PINS]; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
199 for (uint8_t i = 0; i < _count; i++){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
200 _pwm_pins_sorted[i] = _pwm_pins[i]; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
201 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
202 qsort(_pwm_pins_sorted, _count, sizeof _pwm_pins_sorted[0], _compare_values); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
203 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
204 //Populate the _pwm_events_high variable and _pwm_events_low_new array, used in |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
205 // OCR1A and OCR1B respectively to turn pins on / off. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
206 //First we reset everything in this array... |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
207 #ifndef PWM_PORTA_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
208 _pwm_event_high_new.porta_mask = 0x00; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
209 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
210 #ifndef PWM_PORTB_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
211 _pwm_event_high_new.portb_mask = 0x00; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
212 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
213 #ifndef PWM_PORTC_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
214 _pwm_event_high_new.portc_mask = 0x00; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
215 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
216 #ifndef PWM_PORTD_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
217 _pwm_event_high_new.portd_mask = 0x00; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
218 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
219 for (uint8_t i = 0; i < _count + 1; i++){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
220 _pwm_events_low_new[i].compare_value = 0xFFFF; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
221 #ifndef PWM_PORTA_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
222 _pwm_events_low_new[i].porta_mask = 0xFF; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
223 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
224 #ifndef PWM_PORTB_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
225 _pwm_events_low_new[i].portb_mask = 0xFF; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
226 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
227 #ifndef PWM_PORTC_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
228 _pwm_events_low_new[i].portc_mask = 0xFF; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
229 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
230 #ifndef PWM_PORTD_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
231 _pwm_events_low_new[i].portd_mask = 0xFF; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
232 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
233 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
234 //... then we look through the sorted _pwm_pins list, and collect all of the ports / pins which are |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
235 // set at the same compare values into a single event. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
236 uint16_t last_compare_value = _pwm_pins_sorted[0].compare_value; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
237 uint8_t last_index = 0; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
238 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
239 for (uint8_t i = 0; i < _count; i++){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
240 pwm_pin_t *p = &(_pwm_pins_sorted[i]); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
241 if (p->compare_value > last_compare_value){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
242 //We don't want an empty pwm_event at the beginning of the array, so verify whether last_compare_value was zero before incrementing |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
243 if (last_compare_value > 0) { |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
244 last_index++; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
245 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
246 last_compare_value = p->compare_value; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
247 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
248 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
249 if (p->compare_value > 0){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
250 //Set pins to high |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
251 #ifndef PWM_PORTA_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
252 if (p->port == &PORTA) _pwm_event_high_new.porta_mask |= _BV(p->pin); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
253 else |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
254 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
255 #ifndef PWM_PORTB_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
256 if (p->port == &PORTB) _pwm_event_high_new.portb_mask |= _BV(p->pin); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
257 else |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
258 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
259 #ifndef PWM_PORTC_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
260 if (p->port == &PORTC) _pwm_event_high_new.portc_mask |= _BV(p->pin); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
261 else |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
262 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
263 #ifndef PWM_PORTD_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
264 if (p->port == &PORTD) _pwm_event_high_new.portd_mask |= _BV(p->pin); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
265 else |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
266 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
267 if (0); //Nop so that ignored ports dont break things |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
268 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
269 //Set pins to low |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
270 pwm_event_t *e = &(_pwm_events_low_new[last_index]); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
271 e->compare_value = last_compare_value; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
272 #ifndef PWM_PORTA_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
273 if (p->port == &PORTA) e->porta_mask &= ~_BV(p->pin); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
274 else |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
275 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
276 #ifndef PWM_PORTB_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
277 if (p->port == &PORTB) e->portb_mask &= ~_BV(p->pin); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
278 else |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
279 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
280 #ifndef PWM_PORTC_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
281 if (p->port == &PORTC) e->portc_mask &= ~_BV(p->pin); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
282 else |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
283 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
284 #ifndef PWM_PORTD_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
285 if (p->port == &PORTD) e->portd_mask &= ~_BV(p->pin); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
286 else |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
287 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
288 if (0); //Nop so that ignored ports dont break things |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
289 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
290 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
291 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
292 _set_phase_batch = 0; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
293 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
294 //Signal OCR1A that we are ready to load new values |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
295 _set_phase = 1; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
296 _set_phase_lock = 0; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
297 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
298 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
299 void pwm_set_period(uint32_t period){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
300 _set_period = _pwm_micros_to_clicks(period); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
301 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
302 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
303 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
304 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
305 /* |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
306 * The frequency comparison. When it overflows, we reset the timer to 0. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
307 */ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
308 #ifdef PWM_8_BIT |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
309 EMPTY_INTERRUPT(TIM0_OVF_vect) |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
310 ISR(TIM0_COMPA_vect){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
311 #else |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
312 EMPTY_INTERRUPT(TIMER1_OVF_vect) |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
313 ISR(TIMER1_COMPA_vect){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
314 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
315 //Update values if needed |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
316 if (_set_phase && !_set_phase_lock){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
317 for (uint8_t i = 0; i < _count; i++){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
318 _pwm_events_low[i] = _pwm_events_low_new[i]; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
319 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
320 _pwm_event_high = _pwm_event_high_new; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
321 _set_phase = 0; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
322 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
323 if (_set_period){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
324 OCR1A = _set_period; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
325 _set_period = 0; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
326 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
327 if (_set_stop){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
328 TCCR1B = 0x00; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
329 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
330 #ifndef PWM_PORTA_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
331 PORTA &= ~_pwm_event_high.porta_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
332 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
333 #ifndef PWM_PORTB_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
334 PORTB &= ~_pwm_event_high.portb_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
335 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
336 #ifndef PWM_PORTC_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
337 PORTC &= ~_pwm_event_high.portc_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
338 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
339 #ifndef PWM_PORTD_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
340 PORTD &= ~_pwm_event_high.portd_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
341 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
342 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
343 _set_stop = 0; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
344 return; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
345 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
346 //Reset counter after the new compare values are updated (otherwise it affects the phase |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
347 // of the next execution, causing jitter). |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
348 TCNT1 = 0; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
349 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
350 //Set to the first (sorted) compare value in the pwm_events_low array. This is calculated |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
351 // in pwm_apply_batch(), and updated above in this ISR. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
352 _pwm_events_low_ptr = (void*) _pwm_events_low; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
353 OCR1B = _pwm_events_low[0].compare_value; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
354 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
355 //Set pins high. We do this after re-enabling the clock so that we do not artificially increase |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
356 // the phase. We turn off the ports (in COMPB) in the same order that we turn them on here, |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
357 // so that the delta of any delay between PORTA and PORTD should be reduced or eliminated. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
358 #ifndef PWM_PORTA_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
359 PORTA |= _pwm_event_high.porta_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
360 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
361 #ifndef PWM_PORTB_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
362 PORTB |= _pwm_event_high.portb_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
363 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
364 #ifndef PWM_PORTC_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
365 PORTC |= _pwm_event_high.portc_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
366 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
367 #ifndef PWM_PORTD_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
368 PORTD |= _pwm_event_high.portd_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
369 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
370 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
371 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
372 /* |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
373 * The phase comparison, implemented in C. When it overflows, we find the next highest value. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
374 * For a faster alternative, comment this out and use the ASM version in pwm.S |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
375 * |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
376 ISR(TIMER1_COMPB_vect){ |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
377 pwm_event_t* e = (pwm_event_t*) _pwm_events_low_ptr; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
378 _pwm_events_low_ptr = (uint8_t*) _pwm_events_low_ptr + sizeof(pwm_event_t); |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
379 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
380 #ifndef PWM_PORTA_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
381 PORTA &= e->porta_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
382 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
383 #ifndef PWM_PORTB_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
384 PORTB &= e->portb_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
385 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
386 #ifndef PWM_PORTC_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
387 PORTC &= e->portc_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
388 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
389 #ifndef PWM_PORTD_UNUSED |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
390 PORTD &= e->portd_mask; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
391 #endif |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
392 |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
393 //Set the timer for the next lowest value. |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
394 OCR1B = ((pwm_event_t*) _pwm_events_low_ptr)->compare_value; |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
395 } |
|
2b5078b37907
Working servo PWM
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
396 */ |
