Force inactive output between pulse trains
This commit is contained in:
@@ -66,9 +66,9 @@ void sendByteDsm2(uint8_t b) // max 10 changes 0 10 10 10 10 1
|
||||
void putDsm2Flush()
|
||||
{
|
||||
if (extmodulePulsesData.dsm2.index & 1)
|
||||
*extmodulePulsesData.dsm2.ptr++ = 60000;
|
||||
*extmodulePulsesData.dsm2.ptr++ = 255;
|
||||
else
|
||||
*(extmodulePulsesData.dsm2.ptr - 1) = 60000;
|
||||
*(extmodulePulsesData.dsm2.ptr - 1) = 255;
|
||||
}
|
||||
|
||||
// This is the data stream to send, prepare after 19.5 mS
|
||||
|
||||
@@ -47,7 +47,9 @@ void setupPulsesPPM(PpmPulsesData<T> * ppmPulsesData, uint8_t channelsStart, int
|
||||
|
||||
// Set the final period to the max
|
||||
// (a new transfer is issued before it expires)
|
||||
*ppmPulsesData->ptr++ = 65535;
|
||||
// debug: set the last period to the ppm_delay
|
||||
*ppmPulsesData->ptr++ = 2000;
|
||||
//*ppmPulsesData->ptr++ = 65535;
|
||||
|
||||
// it's needed in case PPM is sent without DMA
|
||||
// (we stop when we reach this 0)
|
||||
|
||||
@@ -122,7 +122,7 @@ class PwmPxxBitTransport: public PulsesBuffer<pulse_duration_t, 200> {
|
||||
void addTail()
|
||||
{
|
||||
// rest min value is 18000 - 200 * 48 = 8400 (4.2ms)
|
||||
*(ptr - 1) = 60000;
|
||||
*(ptr - 1) = 255;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -92,9 +92,9 @@ inline int getChannelValue(uint8_t port, int channel)
|
||||
static void sbusFlush()
|
||||
{
|
||||
if (extmodulePulsesData.dsm2.index & 1)
|
||||
*extmodulePulsesData.dsm2.ptr++ = 60000;
|
||||
*extmodulePulsesData.dsm2.ptr++ = 255;
|
||||
else
|
||||
*(extmodulePulsesData.dsm2.ptr - 1) = 60000;
|
||||
*(extmodulePulsesData.dsm2.ptr - 1) = 255;
|
||||
}
|
||||
|
||||
void setupPulsesSbus()
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "pulses/crossfire.h"
|
||||
#endif
|
||||
|
||||
#define STOP_TIMER_ON_LAST_UPDATE
|
||||
|
||||
static const stm32_pulse_timer_t extmoduleTimer = {
|
||||
.GPIOx = EXTMODULE_TX_GPIO,
|
||||
.GPIO_Pin = EXTMODULE_TX_GPIO_PIN,
|
||||
@@ -36,22 +38,69 @@ static const stm32_pulse_timer_t extmoduleTimer = {
|
||||
.TIMx = EXTMODULE_TIMER,
|
||||
.TIM_Prescaler = __LL_TIM_CALC_PSC(EXTMODULE_TIMER_FREQ, 2000000),
|
||||
.TIM_Channel = EXTMODULE_TIMER_Channel,
|
||||
.TIM_IRQn = EXTMODULE_TIMER_IRQn,
|
||||
.DMAx = EXTMODULE_TIMER_DMA,
|
||||
.DMA_Stream = EXTMODULE_TIMER_DMA_STREAM_LL,
|
||||
.DMA_Channel = EXTMODULE_TIMER_DMA_CHANNEL,
|
||||
.DMA_IRQn = EXTMODULE_TIMER_DMA_STREAM_IRQn,
|
||||
};
|
||||
|
||||
#if defined(STOP_TIMER_ON_LAST_UPDATE)
|
||||
|
||||
static_assert(EXTMODULE_TIMER_Channel == LL_TIM_CHANNEL_CH1
|
||||
|| EXTMODULE_TIMER_Channel == LL_TIM_CHANNEL_CH1N
|
||||
|| EXTMODULE_TIMER_Channel == LL_TIM_CHANNEL_CH3,
|
||||
"Unsupported timer channel");
|
||||
|
||||
static void set_compare_reg(uint32_t val)
|
||||
{
|
||||
switch(EXTMODULE_TIMER_Channel){
|
||||
case LL_TIM_CHANNEL_CH1:
|
||||
case LL_TIM_CHANNEL_CH1N:
|
||||
LL_TIM_OC_SetCompareCH1(EXTMODULE_TIMER, val);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH3:
|
||||
LL_TIM_OC_SetCompareCH3(EXTMODULE_TIMER, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void EXTMODULE_TIMER_DMA_IRQHandler()
|
||||
{
|
||||
if (!LL_DMA_IsActiveFlag_TC5(EXTMODULE_TIMER_DMA))
|
||||
return;
|
||||
|
||||
LL_DMA_ClearFlag_TC5(EXTMODULE_TIMER_DMA);
|
||||
|
||||
LL_TIM_ClearFlag_UPDATE(EXTMODULE_TIMER);
|
||||
LL_TIM_EnableIT_UPDATE(EXTMODULE_TIMER);
|
||||
|
||||
set_compare_reg(0);
|
||||
LL_TIM_OC_SetMode(EXTMODULE_TIMER, EXTMODULE_TIMER_Channel, LL_TIM_OCMODE_PWM1);
|
||||
}
|
||||
|
||||
extern "C" void EXTMODULE_TIMER_IRQHandler()
|
||||
{
|
||||
if (!LL_TIM_IsActiveFlag_UPDATE(EXTMODULE_TIMER))
|
||||
return;
|
||||
|
||||
LL_TIM_ClearFlag_UPDATE(EXTMODULE_TIMER);
|
||||
LL_TIM_DisableIT_UPDATE(EXTMODULE_TIMER);
|
||||
|
||||
// Halt pulses and force to inactive level
|
||||
LL_TIM_OC_SetMode(EXTMODULE_TIMER, EXTMODULE_TIMER_Channel,
|
||||
LL_TIM_OCMODE_FORCED_INACTIVE);
|
||||
}
|
||||
#endif
|
||||
|
||||
void extmoduleStop()
|
||||
{
|
||||
EXTERNAL_MODULE_OFF();
|
||||
stm32_pulse_deinit(&extmoduleTimer);
|
||||
}
|
||||
|
||||
void extmodulePpmStart(uint16_t ppm_delay, bool polarity)
|
||||
static void config_ppm_output(uint16_t ppm_delay, bool polarity)
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
stm32_pulse_init(&extmoduleTimer);
|
||||
|
||||
// PPM generation principle:
|
||||
//
|
||||
// Hardware timer in PWM mode is used for PPM generation
|
||||
@@ -65,7 +114,6 @@ void extmodulePpmStart(uint16_t ppm_delay, bool polarity)
|
||||
|
||||
ocInit.OCMode = LL_TIM_OCMODE_PWM1;
|
||||
ocInit.OCState = LL_TIM_OCSTATE_ENABLE;
|
||||
ocInit.OCNState = LL_TIM_OCSTATE_ENABLE;
|
||||
|
||||
if (polarity) {
|
||||
ocInit.OCPolarity = LL_TIM_OCPOLARITY_LOW;
|
||||
@@ -74,28 +122,70 @@ void extmodulePpmStart(uint16_t ppm_delay, bool polarity)
|
||||
}
|
||||
|
||||
ocInit.CompareValue = ppm_delay * 2;
|
||||
stm32_pulse_config_output(&extmoduleTimer, &ocInit);
|
||||
stm32_pulse_config_output(&extmoduleTimer, &ocInit);
|
||||
}
|
||||
|
||||
void extmodulePpmStart(uint16_t ppm_delay, bool polarity)
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
stm32_pulse_init(&extmoduleTimer);
|
||||
config_ppm_output(ppm_delay, polarity);
|
||||
}
|
||||
|
||||
void extmoduleSendNextFramePpm(void* pulses, uint16_t length,
|
||||
uint16_t ppm_delay, bool polarity)
|
||||
{
|
||||
if (!stm32_pulse_stop_if_running(&extmoduleTimer))
|
||||
return;
|
||||
|
||||
// Config output
|
||||
set_compare_reg(ppm_delay * 2);
|
||||
|
||||
uint32_t ll_polarity;
|
||||
if (polarity) {
|
||||
ll_polarity = LL_TIM_OCPOLARITY_LOW;
|
||||
} else {
|
||||
ll_polarity = LL_TIM_OCPOLARITY_HIGH;
|
||||
}
|
||||
LL_TIM_OC_SetPolarity(EXTMODULE_TIMER, EXTMODULE_TIMER_Channel, ll_polarity);
|
||||
LL_TIM_OC_SetMode(EXTMODULE_TIMER, EXTMODULE_TIMER_Channel, LL_TIM_OCMODE_PWM1);
|
||||
|
||||
// Start DMA request and re-enable timer
|
||||
stm32_pulse_start_dma_req(&extmoduleTimer, pulses, length);
|
||||
}
|
||||
|
||||
#if defined(PXX1)
|
||||
void extmodulePxx1PulsesStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
stm32_pulse_init(&extmoduleTimer);
|
||||
|
||||
LL_TIM_OC_InitTypeDef ocInit;
|
||||
LL_TIM_OC_StructInit(&ocInit);
|
||||
|
||||
ocInit.OCMode = LL_TIM_OCMODE_PWM1;
|
||||
ocInit.OCState = LL_TIM_OCSTATE_ENABLE;
|
||||
ocInit.OCNState = LL_TIM_OCSTATE_ENABLE;
|
||||
ocInit.OCPolarity = LL_TIM_OCPOLARITY_LOW;
|
||||
ocInit.CompareValue = 9 * 2; // 9 uS
|
||||
|
||||
stm32_pulse_config_output(&extmoduleTimer, &ocInit);
|
||||
|
||||
stm32_pulse_init(&extmoduleTimer);
|
||||
}
|
||||
|
||||
void extmoduleSendNextFramePxx1(const void* pulses, uint16_t length)
|
||||
{
|
||||
if (!stm32_pulse_stop_if_running(&extmoduleTimer))
|
||||
return;
|
||||
|
||||
set_compare_reg(9 * 2);
|
||||
LL_TIM_OC_SetMode(EXTMODULE_TIMER, EXTMODULE_TIMER_Channel, LL_TIM_OCMODE_PWM1);
|
||||
|
||||
// Start DMA request and re-enable timer
|
||||
stm32_pulse_start_dma_req(&extmoduleTimer, pulses, length);
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: polarity?
|
||||
void extmoduleSerialStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
@@ -112,44 +202,6 @@ void extmoduleSerialStart()
|
||||
stm32_pulse_config_output(&extmoduleTimer, &ocInit);
|
||||
}
|
||||
|
||||
void extmoduleSendNextFramePpm(void* pulses, uint16_t length,
|
||||
uint16_t ppm_delay, bool polarity)
|
||||
{
|
||||
if (!stm32_pulse_stop_if_running(&extmoduleTimer))
|
||||
return;
|
||||
|
||||
switch(EXTMODULE_TIMER_Channel){
|
||||
case LL_TIM_CHANNEL_CH1:
|
||||
LL_TIM_OC_SetCompareCH1(EXTMODULE_TIMER, ppm_delay * 2);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH3:
|
||||
LL_TIM_OC_SetCompareCH3(EXTMODULE_TIMER, ppm_delay * 2);
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t ll_polarity;
|
||||
if (polarity) {
|
||||
ll_polarity = LL_TIM_OCPOLARITY_LOW;
|
||||
} else {
|
||||
ll_polarity = LL_TIM_OCPOLARITY_HIGH;
|
||||
}
|
||||
LL_TIM_OC_SetPolarity(EXTMODULE_TIMER, EXTMODULE_TIMER_Channel, ll_polarity);
|
||||
|
||||
// Start DMA request and re-enable timer
|
||||
stm32_pulse_start_dma_req(&extmoduleTimer, pulses, length);
|
||||
}
|
||||
|
||||
#if defined(PXX1)
|
||||
void extmoduleSendNextFramePxx1(const void* pulses, uint16_t length)
|
||||
{
|
||||
if (!stm32_pulse_stop_if_running(&extmoduleTimer))
|
||||
return;
|
||||
|
||||
// Start DMA request and re-enable timer
|
||||
stm32_pulse_start_dma_req(&extmoduleTimer, pulses, length);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AFHDS3) && !(defined(EXTMODULE_USART) && defined(EXTMODULE_TX_INVERT_GPIO))
|
||||
void extmoduleSendNextFrameAFHDS3(const void* pulses, uint16_t length)
|
||||
{
|
||||
@@ -174,11 +226,13 @@ void extmoduleSendNextFrameSoftSerial100kbit(const void* pulses, uint16_t length
|
||||
ll_polarity = LL_TIM_OCPOLARITY_LOW;
|
||||
}
|
||||
LL_TIM_OC_SetPolarity(EXTMODULE_TIMER, EXTMODULE_TIMER_Channel, ll_polarity);
|
||||
LL_TIM_OC_SetMode(EXTMODULE_TIMER, EXTMODULE_TIMER_Channel, LL_TIM_OCMODE_TOGGLE);
|
||||
|
||||
// Start DMA request and re-enable timer
|
||||
stm32_pulse_start_dma_req(&extmoduleTimer, pulses, length);
|
||||
}
|
||||
|
||||
// Delay based byte sending @ 57600 bps
|
||||
void extmoduleSendInvertedByte(uint8_t byte)
|
||||
{
|
||||
uint16_t time;
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "stm32_pulse_driver.h"
|
||||
#include "definitions.h"
|
||||
|
||||
#define STOP_TIMER_ON_LAST_UPDATE
|
||||
|
||||
void stm32_pulse_init(const stm32_pulse_timer_t* tim)
|
||||
{
|
||||
LL_GPIO_InitTypeDef pinInit;
|
||||
@@ -38,6 +40,16 @@ void stm32_pulse_init(const stm32_pulse_timer_t* tim)
|
||||
timInit.Prescaler = tim->TIM_Prescaler;
|
||||
timInit.Autoreload = 65535;
|
||||
LL_TIM_Init(tim->TIMx, &timInit);
|
||||
|
||||
#if defined(STOP_TIMER_ON_LAST_UPDATE)
|
||||
// Enable DMA IRQ
|
||||
NVIC_EnableIRQ(tim->DMA_IRQn);
|
||||
NVIC_SetPriority(tim->DMA_IRQn, 7);
|
||||
|
||||
// Enable timer IRQ
|
||||
NVIC_EnableIRQ(tim->TIM_IRQn);
|
||||
NVIC_SetPriority(tim->TIM_IRQn, 7);
|
||||
#endif
|
||||
}
|
||||
|
||||
void stm32_pulse_deinit(const stm32_pulse_timer_t* tim)
|
||||
@@ -57,7 +69,6 @@ void stm32_pulse_deinit(const stm32_pulse_timer_t* tim)
|
||||
|
||||
void stm32_pulse_config_output(const stm32_pulse_timer_t* tim, LL_TIM_OC_InitTypeDef* ocInit)
|
||||
{
|
||||
LL_TIM_DisableCounter(tim->TIMx);
|
||||
LL_TIM_OC_Init(tim->TIMx, tim->TIM_Channel, ocInit);
|
||||
LL_TIM_OC_EnablePreload(tim->TIMx, tim->TIM_Channel);
|
||||
|
||||
@@ -66,7 +77,6 @@ void stm32_pulse_config_output(const stm32_pulse_timer_t* tim, LL_TIM_OC_InitTyp
|
||||
}
|
||||
|
||||
LL_TIM_EnableDMAReq_UPDATE(tim->TIMx);
|
||||
LL_TIM_EnableCounter(tim->TIMx);
|
||||
}
|
||||
|
||||
// return true if stopped, false otherwise
|
||||
@@ -77,12 +87,15 @@ bool stm32_pulse_stop_if_running(const stm32_pulse_timer_t* tim)
|
||||
|
||||
// disable timer
|
||||
LL_TIM_DisableCounter(tim->TIMx);
|
||||
LL_TIM_DisableIT_UPDATE(tim->TIMx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void stm32_pulse_start_dma_req(const stm32_pulse_timer_t* tim,
|
||||
const void* pulses, uint16_t length)
|
||||
{
|
||||
// re-init DMA stream
|
||||
LL_DMA_DeInit(tim->DMAx, tim->DMA_Stream);
|
||||
|
||||
LL_DMA_InitTypeDef dmaInit;
|
||||
@@ -112,12 +125,25 @@ void stm32_pulse_start_dma_req(const stm32_pulse_timer_t* tim,
|
||||
dmaInit.NbData = length;
|
||||
dmaInit.Channel = tim->DMA_Channel;
|
||||
dmaInit.Priority = LL_DMA_PRIORITY_VERYHIGH;
|
||||
|
||||
LL_DMA_Init(tim->DMAx, tim->DMA_Stream, &dmaInit);
|
||||
|
||||
#if defined(STOP_TIMER_ON_LAST_UPDATE)
|
||||
// Enable TC IRQ
|
||||
LL_DMA_EnableIT_TC(tim->DMAx, tim->DMA_Stream);
|
||||
#endif
|
||||
|
||||
// Enable DMA
|
||||
LL_TIM_ClearFlag_UPDATE(tim->TIMx);
|
||||
LL_TIM_DisableDMAReq_UPDATE(tim->TIMx);
|
||||
LL_TIM_SetCounter(tim->TIMx, 0);
|
||||
LL_DMA_EnableStream(tim->DMAx, tim->DMA_Stream);
|
||||
|
||||
// re-init timer
|
||||
// Trigger update to effect the first DMA transation
|
||||
// and thus load ARR with the first duration
|
||||
LL_TIM_EnableDMAReq_UPDATE(tim->TIMx);
|
||||
LL_TIM_GenerateEvent_UPDATE(tim->TIMx);
|
||||
|
||||
// start timer
|
||||
LL_TIM_EnableCounter(tim->TIMx);
|
||||
}
|
||||
|
||||
@@ -33,10 +33,12 @@ struct stm32_pulse_timer_t {
|
||||
TIM_TypeDef* TIMx;
|
||||
uint16_t TIM_Prescaler;
|
||||
uint32_t TIM_Channel;
|
||||
IRQn_Type TIM_IRQn;
|
||||
|
||||
DMA_TypeDef* DMAx;
|
||||
uint32_t DMA_Stream;
|
||||
uint32_t DMA_Channel;
|
||||
IRQn_Type DMA_IRQn;
|
||||
};
|
||||
|
||||
void stm32_pulse_init(const stm32_pulse_timer_t* tim);
|
||||
|
||||
@@ -859,7 +859,7 @@
|
||||
#define EXTMODULE_TIMER_32BITS
|
||||
#define EXTMODULE_TIMER_DMA_SIZE (DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1)
|
||||
#define EXTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
#define EXTMODULE_TIMER_CC_IRQn TIM2_IRQn
|
||||
#define EXTMODULE_TIMER_IRQn TIM2_IRQn
|
||||
#define EXTMODULE_TIMER_IRQHandler TIM2_IRQHandler
|
||||
#define EXTMODULE_TIMER_DMA_CHANNEL DMA_Channel_3
|
||||
#define EXTMODULE_TIMER_DMA_STREAM DMA1_Stream1
|
||||
@@ -891,8 +891,8 @@
|
||||
#define EXTMODULE_TIMER TIM1
|
||||
#define EXTMODULE_TIMER_Channel LL_TIM_CHANNEL_CH3
|
||||
#define EXTMODULE_TIMER_DMA_SIZE (DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0)
|
||||
#define EXTMODULE_TIMER_CC_IRQn TIM1_CC_IRQn
|
||||
#define EXTMODULE_TIMER_IRQHandler TIM1_CC_IRQHandler
|
||||
#define EXTMODULE_TIMER_IRQn TIM1_UP_TIM10_IRQn
|
||||
#define EXTMODULE_TIMER_IRQHandler TIM1_UP_TIM10_IRQHandler
|
||||
#define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
|
||||
#define EXTMODULE_TIMER_DMA_CHANNEL DMA_Channel_6
|
||||
#define EXTMODULE_TIMER_DMA_STREAM DMA2_Stream5
|
||||
@@ -913,7 +913,7 @@
|
||||
#define EXTMODULE_TIMER_Channel LL_TIM_CHANNEL_CH1
|
||||
#define EXTMODULE_TIMER_32BITS
|
||||
#define EXTMODULE_TIMER_DMA_SIZE (DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1)
|
||||
#define EXTMODULE_TIMER_CC_IRQn TIM2_IRQn
|
||||
#define EXTMODULE_TIMER_IRQn TIM2_IRQn
|
||||
#define EXTMODULE_TIMER_IRQHandler TIM2_IRQHandler
|
||||
#define EXTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
#define EXTMODULE_TIMER_DMA_CHANNEL DMA_Channel_3
|
||||
|
||||
Reference in New Issue
Block a user