35 #if defined(PIOS_INCLUDE_DSM)
37 #if !defined(PIOS_INCLUDE_RTC)
38 #error PIOS_INCLUDE_RTC must be used to use DSM
41 static uint16_t PIOS_DSM_RxInCallback(uintptr_t context,
46 static void PIOS_DSM_Supervisor(uintptr_t dsm_id);
48 #if defined(PIOS_INCLUDE_RCVR)
49 static int32_t PIOS_DSM_Get(uintptr_t rcvr_id, uint8_t channel);
57 DSM_UNKNOWN, DSM_10BIT, DSM_11BIT
60 enum pios_dsm_dev_magic {
61 PIOS_DSM_DEV_MAGIC = 0x44534d78,
64 struct pios_dsm_state {
67 uint8_t receive_timer;
68 uint8_t failsafe_timer;
71 #ifdef DSM_LOST_FRAME_COUNTER
72 uint8_t frames_lost_last;
78 enum pios_dsm_dev_magic
magic;
80 struct pios_dsm_state
state;
81 enum dsm_resolution resolution;
85 static struct pios_dsm_dev *PIOS_DSM_Alloc(
void)
87 struct pios_dsm_dev *dsm_dev;
89 dsm_dev = (
struct pios_dsm_dev *)
PIOS_malloc(
sizeof(*dsm_dev));
93 dsm_dev->resolution = DSM_UNKNOWN;
94 dsm_dev->magic = PIOS_DSM_DEV_MAGIC;
99 static bool PIOS_DSM_Validate(
struct pios_dsm_dev *dsm_dev)
101 return (dsm_dev->magic == PIOS_DSM_DEV_MAGIC);
105 static void PIOS_DSM_Bind(
struct pios_dsm_dev *dsm_dev, uint8_t num_pulses)
110 GPIO_InitTypeDef GPIO_InitStructure = cfg->
bind.
init;
111 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
125 for (
int i = 0;
i < num_pulses ;
i++) {
134 GPIO_Init(cfg->
bind.
gpio, &GPIO_InitStructure);
136 (void) dsm_dev; (void) num_pulses;
141 static void PIOS_DSM_ResetChannels(
struct pios_dsm_dev *dsm_dev)
143 struct pios_dsm_state *
state = &(dsm_dev->state);
150 static void PIOS_DSM_ResetState(
struct pios_dsm_dev *dsm_dev)
152 struct pios_dsm_state *state = &(dsm_dev->state);
153 state->receive_timer = 0;
154 state->failsafe_timer = 0;
155 state->frame_found = 0;
156 #ifdef DSM_LOST_FRAME_COUNTER
157 state->frames_lost_last = 0;
158 state->frames_lost = 0;
160 PIOS_DSM_ResetChannels(dsm_dev);
171 enum dsm_resolution PIOS_DSM_DetectResolution(uint8_t *packet)
173 uint8_t channel0, channel1;
174 uint16_t word0, word1;
178 word0 = ((uint16_t)packet[2] << 8) | packet[3];
179 word1 = ((uint16_t)packet[4] << 8) | packet[5];
199 channel0 = (word0 >> 10) & 0x0f;
200 channel1 = (word1 >> 10) & 0x0f;
201 bit_10 = (channel0 == 1) && (channel1 == 5);
204 channel0 = (word0 >> 11) & 0x0f;
205 channel1 = (word1 >> 11) & 0x0f;
206 bit_11 = (channel0 == 1) && (channel1 == 5);
208 if (bit_10 && !bit_11)
211 if (bit_11 && !bit_10)
220 int PIOS_DSM_UnrollChannels(
struct pios_dsm_dev *dsm_dev)
222 struct pios_dsm_state *state = &(dsm_dev->state);
225 #ifdef DSM_LOST_FRAME_COUNTER
227 uint8_t frames_lost = state->received_data[0];
228 state->frames_lost += (frames_lost - state->frames_lost_last);
229 state->frames_lost_last = frames_lost;
234 if (dsm_dev->resolution == DSM_UNKNOWN) {
235 dsm_dev->resolution = PIOS_DSM_DetectResolution(state->received_data);
239 if (dsm_dev->resolution == DSM_UNKNOWN) {
242 uint8_t resolution = (dsm_dev->resolution == DSM_10BIT) ? 10 : 11;
243 uint16_t mask = (dsm_dev->resolution == DSM_10BIT) ? 0x03ff : 0x07ff;
246 uint8_t *s = &(state->received_data[2]);
249 uint16_t word = ((uint16_t)s[0] << 8) | s[1];
263 uint8_t channel_num = (word >> resolution) & 0x0f;
264 state->channel_data[channel_num] = (word & mask);
267 #ifdef DSM_LOST_FRAME_COUNTER
281 static void PIOS_DSM_UpdateState(
struct pios_dsm_dev *dsm_dev, uint8_t byte)
283 struct pios_dsm_state *state = &(dsm_dev->state);
284 if (state->frame_found) {
288 state->received_data[state->byte_count++] = byte;
291 if (!PIOS_DSM_UnrollChannels(dsm_dev)) {
293 state->failsafe_timer = 0;
294 #ifdef PIOS_INCLUDE_RCVR
300 state->frame_found = 0;
311 HwSharedDSMxModeOptions
mode)
317 struct pios_dsm_dev *dsm_dev;
319 dsm_dev = (
struct pios_dsm_dev *)PIOS_DSM_Alloc();
326 uint8_t num_pulses = 0;
330 if (mode > HWSHARED_DSMXMODE_BIND10PULSES)
336 case HWSHARED_DSMXMODE_AUTODETECT:
337 dsm_dev->resolution = DSM_UNKNOWN;
339 case HWSHARED_DSMXMODE_FORCE10BIT:
340 dsm_dev->resolution = DSM_10BIT;
342 case HWSHARED_DSMXMODE_FORCE11BIT:
343 dsm_dev->resolution = DSM_11BIT;
345 case HWSHARED_DSMXMODE_BIND3PULSES:
346 case HWSHARED_DSMXMODE_BIND4PULSES:
347 case HWSHARED_DSMXMODE_BIND5PULSES:
348 case HWSHARED_DSMXMODE_BIND6PULSES:
349 case HWSHARED_DSMXMODE_BIND7PULSES:
350 case HWSHARED_DSMXMODE_BIND8PULSES:
351 case HWSHARED_DSMXMODE_BIND9PULSES:
352 case HWSHARED_DSMXMODE_BIND10PULSES:
353 num_pulses = 3 + mode - HWSHARED_DSMXMODE_BIND3PULSES;
359 PIOS_DSM_Bind(dsm_dev, num_pulses);
361 PIOS_DSM_ResetState(dsm_dev);
363 *dsm_id = (uintptr_t)dsm_dev;
366 (driver->
bind_rx_cb)(lower_id, PIOS_DSM_RxInCallback, *dsm_id);
376 static uint16_t PIOS_DSM_RxInCallback(uintptr_t context,
382 struct pios_dsm_dev *dsm_dev = (
struct pios_dsm_dev *)context;
384 bool valid = PIOS_DSM_Validate(dsm_dev);
388 for (uint8_t
i = 0;
i < buf_len;
i++) {
389 PIOS_DSM_UpdateState(dsm_dev, buf[
i]);
390 dsm_dev->state.receive_timer = 0;
411 #if defined(PIOS_INCLUDE_RCVR)
412 static int32_t PIOS_DSM_Get(uintptr_t rcvr_id, uint8_t channel)
414 struct pios_dsm_dev *dsm_dev = (
struct pios_dsm_dev *)rcvr_id;
416 if (!PIOS_DSM_Validate(dsm_dev))
424 return dsm_dev->state.channel_data[channel];
440 static void PIOS_DSM_Supervisor(uintptr_t dsm_id)
442 struct pios_dsm_dev *dsm_dev = (
struct pios_dsm_dev *)dsm_id;
444 bool valid = PIOS_DSM_Validate(dsm_dev);
447 struct pios_dsm_state *state = &(dsm_dev->state);
450 if (++state->receive_timer > 4) {
451 state->frame_found = 1;
452 state->byte_count = 0;
453 state->receive_timer = 0;
457 if (++state->failsafe_timer > 156) {
458 PIOS_DSM_ResetChannels(dsm_dev);
459 state->failsafe_timer = 0;
#define DSM_CHANNELS_PER_FRAME
int32_t(* read)(uintptr_t id, uint8_t channel)
int32_t PIOS_DSM_Init(uintptr_t *dsm_id, const struct pios_dsm_cfg *cfg, const struct pios_com_driver *driver, uintptr_t lower_id, HwSharedDSMxModeOptions mode)
Main PiOS header to include all the compiled in PiOS options.
#define PIOS_DEBUG_Assert(test)
#define DSM_2ND_FRAME_MASK
void * PIOS_malloc(size_t size)
bool PIOS_RTC_RegisterTickCallback(void(*fn)(uintptr_t id), uintptr_t data)
void PIOS_RCVR_ActiveFromISR()
static struct flyingpicmd_cfg_fa cfg
Spektrum/JR DSMx satellite receiver private structures.
#define PIOS_DSM_NUM_INPUTS
const struct pios_rcvr_driver pios_dsm_rcvr_driver
void(* bind_rx_cb)(uintptr_t id, pios_com_callback rx_in_cb, uintptr_t context)
#define PIOS_Assert(test)
int32_t PIOS_DELAY_WaituS(uint32_t uS)
uint32_t PIOS_DELAY_GetRaw()
Get the raw delay timer, useful for timing.