Commit 30ff2f97dc97fb5219e64f38c03b0ebfdb44fc1f

Authored by Antonio Carlos Domínguez Brito
1 parent 083e038f
Exists in master

added member function get_duty_period_and_pulses() to capture objects

Showing 3 changed files with 54 additions and 299 deletions   Show diff stats
README.md
... ... @@ -42,6 +42,8 @@ As soon as the object is configured the corresponding TC channel starts capturin
42 42  
43 43 Capture objects take advantage of TC module channels in *capture* mode to measure digital pulses. Concretely, using tc_lib capture objects we can obtain the last pulse duration (duty) and the last period of the measured signal. Example *capture_test.ino* use a PWM signal generated on analog pin 7 as the signal to measure. When nothing is measured the duty and the period measured by the capture object are zero. Take into account that the measured duty and period get stored inside the capture objects at the interrupt handlers associated with the TC channels involved.
44 44  
  45 +In addition, capture objects can tell you how many pulses they have captured so far using member function *get_duty_period_and_pulses()*.
  46 +
45 47 ### 2.1 Fast signals and capture objects
46 48  
47 49 When capturing signals capture objects do intensive use of interrupts associated to the TC channel associated with the specific object. If the signal to capture is very fast (pulse duration around 1 microsecond or less), some interrupts will be missed to track the signal. Internally the TC channel in capture mode registers those situations with the signaling of a "load overrun" of one of the capture registers RA or RB (more details in ATSAM3X8E data sheet). Evidently, this may also happen in an application where the use of interrupts is very high, even if the signal to capture is not so fast. In any case, specially with fast signals (frequencies of around 1 Mhz) this massive use of interrupts could provoke the freezing of the CPU, since all CPU time was invested on interrupts. To avoid that situation, the capture object stops capturing when it detects too much overrun events, keeping internally the duty and period of the last pulse captured. Function *get_duty_and_period()* returns a status value where we can check if the capture objects was overrun and/or stopped. Here a snippet of code from example *pwm_capture_test.ino* illustrating its use:
... ... @@ -67,7 +69,9 @@ Serial.println();
67 69 ```
68 70 Once a capture object is stopped due to the occurrence of too many load overrun situations, the object is restarted when calling member function *get_duty_and_period()* or member function *restart()*.
69 71  
70   -### 3. Action objects
  72 +Note that many load overruns implies that the capture object is losing pulses, accordingly member function *get_duty_period_and_pulses()* will provide only the number of pulses really captured.
  73 +
  74 +## 3. Action objects
71 75  
72 76 The action objects available in tc_lib allow us to have a callback called periodically in our program.
73 77  
... ...
tc_lib.h
... ... @@ -150,10 +150,30 @@ namespace arduino_due
150 150  
151 151 // NOTE: member function get_duty_and_period() returns
152 152 // the status of the capture object. Returns in arguments
153   - // the last valid measured duty and period.
154   - uint32_t get_duty_and_period(uint32_t& the_duty, uint32_t& the_period)
  153 + // the last valid measured and period.
  154 + uint32_t get_duty_and_period(
  155 + uint32_t& the_duty,
  156 + uint32_t& the_period
  157 + )
155 158 { return _ctx_.get_duty_and_period(the_duty,the_period); }
156 159  
  160 + // NOTE: member function get_duty_and_period() returns
  161 + // the status of the capture object. Returns in arguments
  162 + // the last valid measured and period, and the count of
  163 + // pulses accumulated since the last config.
  164 + uint32_t get_duty_period_and_pulses(
  165 + uint32_t& the_duty,
  166 + uint32_t& the_period,
  167 + uint32_t& the_pulses
  168 + )
  169 + {
  170 + return _ctx_.get_duty_period_and_pulses(
  171 + the_duty,
  172 + the_period,
  173 + the_pulses
  174 + );
  175 + }
  176 +
157 177 uint32_t get_capture_window() { return _ctx_.capture_window; }
158 178  
159 179 bool is_overrun(uint32_t the_status)
... ... @@ -223,7 +243,10 @@ namespace arduino_due
223 243 ticks_per_usec();
224 244 }
225 245  
226   - uint32_t get_duty_and_period(uint32_t& the_duty, uint32_t& the_period)
  246 + uint32_t get_duty_and_period(
  247 + uint32_t& the_duty,
  248 + uint32_t& the_period
  249 + )
227 250 {
228 251 uint32_t the_status=status;
229 252 if(is_unset(the_status)) return the_status;
... ... @@ -239,6 +262,26 @@ namespace arduino_due
239 262 return the_status;
240 263 }
241 264  
  265 + uint32_t get_duty_period_and_pulses(
  266 + uint32_t& the_duty,
  267 + uint32_t& the_period,
  268 + uint32_t& the_pulses
  269 + )
  270 + {
  271 + uint32_t the_status=status;
  272 + if(is_unset(the_status)) return the_status;
  273 +
  274 + timer::disable_interrupts();
  275 + the_duty=duty; the_period=period; the_pulses=pulses;
  276 + the_status=status;
  277 + status=status&(~status_codes::OVERRUN);
  278 + timer::enable_interrupts();
  279 +
  280 + if(is_stopped(the_status)) restart();
  281 +
  282 + return the_status;
  283 + }
  284 +
242 285 bool is_overrun(uint32_t the_status)
243 286 { return (the_status&status_codes::OVERRUN); }
244 287  
... ... @@ -313,7 +356,7 @@ namespace arduino_due
313 356 void rb_loaded()
314 357 {
315 358 period=timer::info::tc_p->TC_CHANNEL[timer::info::channel].TC_RB;
316   - duty=period-ra;
  359 + duty=period-ra; pulses++;
317 360 }
318 361  
319 362 void rc_matched() { ra=duty=period=0; }
... ... @@ -322,6 +365,7 @@ namespace arduino_due
322 365 volatile uint32_t ra;
323 366 volatile uint32_t duty;
324 367 volatile uint32_t period;
  368 + volatile uint32_t pulses;
325 369 volatile uint32_t overruns;
326 370 volatile uint32_t status;
327 371  
... ... @@ -346,7 +390,7 @@ namespace arduino_due
346 390 return false;
347 391  
348 392 capture_window=the_capture_window;
349   - ra=duty=period=overruns=0;
  393 + ra=duty=period=pulses=overruns=0;
350 394 max_overruns=the_overruns;
351 395 status=status_codes::SET;
352 396  
... ...
tc_lib.vim
No preview for this file type