MCPcopy Create free account
hub / github.com/ArduPilot/ardupilot / push

Method push

libraries/AP_HAL_Linux/RCOutput_PCA9685.cpp:230–287  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

228}
229
230void RCOutput_PCA9685::push()
231{
232 if (!_corking) {
233 return;
234 }
235 _corking = false;
236
237 if (_pending_write_mask == 0)
238 return;
239
240 // Calculate the number of channels for this transfer.
241 uint8_t max_ch = (sizeof(unsigned) * 8) - __builtin_clz(_pending_write_mask);
242 uint8_t min_ch = __builtin_ctz(_pending_write_mask);
243
244 /*
245 * scratch buffer size is always for all the channels, but we write only
246 * from min_ch to max_ch
247 */
248 struct PACKED pwm_values {
249 uint8_t reg;
250 uint8_t data[PWM_CHAN_COUNT * 4];
251 } pwm_values;
252
253 for (unsigned ch = min_ch; ch < max_ch; ch++) {
254 uint16_t period_us = _pulses_buffer[ch];
255 uint16_t length = 0;
256
257 if (period_us) {
258 length = round((period_us * 4096) / (1000000.f / _frequency)) - 1;
259 }
260
261 uint8_t *d = &pwm_values.data[(ch - min_ch) * 4];
262
263 if (_is_gpio_mask & (1 << ch)) {
264 *d++ = 0; // LEDn_ON_L
265 *d++ = period_us ? PCA9685_LED_ON_H_ALWAYS_ON_BIT : 0; // LEDn_ON_H
266 *d++ = 0; // LEDn_OFF_L
267 *d++ = period_us ? 0 : PCA9685_LED_OFF_H_ALWAYS_OFF_BIT; // LEDn_OFF_H
268 } else {
269 *d++ = 0; // LEDn_ON_L
270 *d++ = 0; // LEDn_ON_H
271 *d++ = length & 0xFF; // LEDn_OFF_L
272 *d++ = length >> 8; // LEDn_OFF_H
273 }
274 }
275
276 if (!_dev || !_dev->get_semaphore()->take_nonblocking()) {
277 return;
278 }
279
280 pwm_values.reg = PCA9685_RA_LED0_ON_L + 4 * (_channel_offset + min_ch);
281 /* reg + all the channels we are going to write */
282 size_t payload_size = 1 + (max_ch - min_ch) * 4;
283
284 _dev->transfer((uint8_t *)&pwm_values, payload_size, nullptr, 0);
285 _dev->get_semaphore()->give();
286 _pending_write_mask = 0;
287}

Callers

nothing calls this directly

Calls 4

take_nonblockingMethod · 0.45
get_semaphoreMethod · 0.45
transferMethod · 0.45
giveMethod · 0.45

Tested by

no test coverage detected