1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-01 09:24:10 +01:00

OP-924: Completely turn off PPM output when it's not being refreshed. Also fixed testing of PPM input on the OPlink that was broken when the return values were changed to negative values. The PPM values were being stored in an unsigned datatype, which made detecting negative error returns impossible.

This commit is contained in:
Brian Webb 2013-04-27 04:26:21 +01:00
parent ab926da507
commit 56a524ab9e
3 changed files with 42 additions and 35 deletions

View File

@ -76,7 +76,7 @@ typedef struct {
#define PH_PPM_DATA_SIZE(p) ((uint8_t*)((p)->ecc) - (uint8_t*)(((PHPacketHandle)(p))->data))
typedef struct {
PHPacketHeader header;
uint16_t channels[PIOS_RFM22B_RCVR_MAX_CHANNELS];
int16_t channels[PIOS_RFM22B_RCVR_MAX_CHANNELS];
uint8_t ecc[RS_ECC_NPARITY];
} PHPpmPacket, *PHPpmPacketHandle;

View File

@ -2074,7 +2074,7 @@ static void rfm22_sendPPM(struct pios_rfm22b_dev *rfm22b_dev)
bool valid_input_detected = false;
for (uint8_t i = 1; i <= PIOS_PPM_NUM_INPUTS; ++i) {
rfm22b_dev->ppm_packet.channels[i - 1] = PIOS_RCVR_Read(PIOS_PPM_RECEIVER, i);
if(rfm22b_dev->ppm_packet.channels[i - 1] != PIOS_RCVR_TIMEOUT)
if((rfm22b_dev->ppm_packet.channels[i - 1] != PIOS_RCVR_INVALID) && (rfm22b_dev->ppm_packet.channels[i - 1] != PIOS_RCVR_TIMEOUT))
valid_input_detected = true;
}

View File

@ -60,6 +60,7 @@ struct pios_ppm_out_dev {
};
static void PIOS_PPM_Out_Supervisor(uint32_t ppm_id);
static void PIOS_PPM_Out_Enable_Disable(struct pios_ppm_out_dev *ppm_dev, bool enable);
static bool PIOS_PPM_Out_validate(struct pios_ppm_out_dev *ppm_dev)
{
@ -151,20 +152,6 @@ int32_t PIOS_PPM_Out_Init(uint32_t *ppm_out_id, const struct pios_ppm_out_cfg *
TIM_OC4PreloadConfig(chan->timer, TIM_OCPreload_Enable);
break;
}
switch (chan->timer_chan) {
case TIM_Channel_1:
TIM_ITConfig(chan->timer, TIM_IT_CC1 | TIM_IT_Update, ENABLE);
break;
case TIM_Channel_2:
TIM_ITConfig(chan->timer, TIM_IT_CC2 | TIM_IT_Update, ENABLE);
break;
case TIM_Channel_3:
TIM_ITConfig(chan->timer, TIM_IT_CC3 | TIM_IT_Update, ENABLE);
break;
case TIM_Channel_4:
TIM_ITConfig(chan->timer, TIM_IT_CC4 | TIM_IT_Update, ENABLE);
break;
}
TIM_ARRPreloadConfig(chan->timer, ENABLE);
TIM_CtrlPWMOutputs(chan->timer, ENABLE);
@ -176,20 +163,7 @@ int32_t PIOS_PPM_Out_Init(uint32_t *ppm_out_id, const struct pios_ppm_out_cfg *
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1;
TIM_TimeBaseStructure.TIM_Period = ((1000000 / 100) - 1);
TIM_TimeBaseInit(chan->timer, &TIM_TimeBaseStructure);
switch(chan->timer_chan) {
case TIM_Channel_1:
TIM_SetCompare1(chan->timer, ppm_dev->triggering_period);
break;
case TIM_Channel_2:
TIM_SetCompare2(chan->timer, ppm_dev->triggering_period);
break;
case TIM_Channel_3:
TIM_SetCompare3(chan->timer, ppm_dev->triggering_period);
break;
case TIM_Channel_4:
TIM_SetCompare4(chan->timer, ppm_dev->triggering_period);
break;
}
PIOS_PPM_Out_Enable_Disable(ppm_dev, false);
// Configure the supervisor
ppm_dev->supv_timer = 0;
@ -216,7 +190,11 @@ void PIOS_PPM_OUT_Set(uint32_t ppm_out_id, uint8_t servo, uint16_t position)
// Update the supervisor tracking variables.
ppm_dev->Fresh = TRUE;
ppm_dev->Tracking = TRUE;
// Reenable the TIM if it's been turned off.
if (!ppm_dev->Tracking) {
PIOS_PPM_Out_Enable_Disable(ppm_dev, true);
}
// Update the position
ppm_dev->ChannelValue[servo] = position;
@ -234,6 +212,14 @@ static void PIOS_PPM_OUT_tim_edge_cb (uint32_t tim_id, uint32_t context, uint8_t
pulse_width = PIOS_PPM_OUT_FRAME_PERIOD_US - ppm_dev->ChannelSum;
ppm_dev->NumChannelCounter = 0;
ppm_dev->ChannelSum = 0;
// Have we not received a sample for the supervisor timeout.
if (!ppm_dev->Tracking) {
// Flush counter variables
for (uint8_t i = 0; i < PIOS_PPM_OUT_MAX_CHANNELS; i++)
ppm_dev->ChannelValue[i] = 1000;
PIOS_PPM_Out_Enable_Disable(ppm_dev, false);
}
} else
ppm_dev->ChannelSum += (pulse_width = ppm_dev->ChannelValue[ppm_dev->NumChannelCounter++]);
@ -243,6 +229,31 @@ static void PIOS_PPM_OUT_tim_edge_cb (uint32_t tim_id, uint32_t context, uint8_t
return;
}
static void PIOS_PPM_Out_Enable_Disable(struct pios_ppm_out_dev *ppm_dev, bool enable)
{
const struct pios_tim_channel *chan = ppm_dev->cfg->channel;
uint32_t trig = enable ? ppm_dev->triggering_period : 0;
FunctionalState state = enable ? ENABLE : DISABLE;
switch (chan->timer_chan) {
case TIM_Channel_1:
TIM_ITConfig(chan->timer, TIM_IT_CC1 | TIM_IT_Update, state);
TIM_SetCompare1(chan->timer, trig);
break;
case TIM_Channel_2:
TIM_ITConfig(chan->timer, TIM_IT_CC2 | TIM_IT_Update, state);
TIM_SetCompare2(chan->timer, trig);
break;
case TIM_Channel_3:
TIM_ITConfig(chan->timer, TIM_IT_CC3 | TIM_IT_Update, state);
TIM_SetCompare3(chan->timer, trig);
break;
case TIM_Channel_4:
TIM_ITConfig(chan->timer, TIM_IT_CC4 | TIM_IT_Update, state);
TIM_SetCompare4(chan->timer, trig);
break;
}
}
static void PIOS_PPM_Out_Supervisor(uint32_t ppm_out_id) {
struct pios_ppm_out_dev *ppm_dev = (struct pios_ppm_out_dev *)ppm_out_id;
if (!PIOS_PPM_Out_validate(ppm_dev))
@ -258,10 +269,6 @@ static void PIOS_PPM_Out_Supervisor(uint32_t ppm_out_id) {
if (!ppm_dev->Fresh) {
ppm_dev->Tracking = FALSE;
// Flush counter variables
for (uint8_t i = 0; i < PIOS_PPM_OUT_MAX_CHANNELS; i++)
ppm_dev->ChannelValue[i] = 1000;
}
ppm_dev->Fresh = FALSE;