1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-19 22:35:23 +03:00

escprog inverted output support

multiport test, usage "escprog ki 255"
This commit is contained in:
Sami Korhonen 2016-11-05 11:21:36 +02:00
parent 9124c496b6
commit d2981cd704
2 changed files with 140 additions and 57 deletions

View file

@ -17,6 +17,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include "platform.h" #include "platform.h"
@ -25,6 +26,13 @@ typedef enum {
BAUDRATE_KISS = 38400 BAUDRATE_KISS = 38400
} escBaudRate_e; } escBaudRate_e;
typedef enum {
PROTOCOL_SIMONK = 0,
PROTOCOL_BLHELI = 1,
PROTOCOL_KISS = 2,
PROTOCOL_KISSALL = 3
} escProtocol_e;
#if defined(USE_ESCSERIAL) #if defined(USE_ESCSERIAL)
#include "build/build_config.h" #include "build/build_config.h"
@ -80,11 +88,19 @@ typedef struct escSerial_s {
uint8_t escSerialPortIndex; uint8_t escSerialPortIndex;
uint8_t mode; uint8_t mode;
uint8_t outputCount;
timerCCHandlerRec_t timerCb; timerCCHandlerRec_t timerCb;
timerCCHandlerRec_t edgeCb; timerCCHandlerRec_t edgeCb;
} escSerial_t; } escSerial_t;
typedef struct {
IO_t io;
uint8_t inverted;
} escOutputs_t;
escOutputs_t escOutputs[MAX_SUPPORTED_MOTORS];
extern timerHardware_t* serialTimerHardware; extern timerHardware_t* serialTimerHardware;
extern escSerial_t escSerialPorts[]; extern escSerial_t escSerialPorts[];
@ -97,15 +113,37 @@ void onSerialTimerEsc(timerCCHandlerRec_t *cbRec, captureCompare_t capture);
void onSerialRxPinChangeEsc(timerCCHandlerRec_t *cbRec, captureCompare_t capture); void onSerialRxPinChangeEsc(timerCCHandlerRec_t *cbRec, captureCompare_t capture);
void onSerialTimerBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture); void onSerialTimerBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture);
void onSerialRxPinChangeBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture); void onSerialRxPinChangeBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture);
static void serialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity); static void escSerialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity);
void setTxSignalEsc(escSerial_t *escSerial, uint8_t state) void setTxSignalEsc(escSerial_t *escSerial, uint8_t state)
{ {
if((escSerial->mode = PROTOCOL_KISSALL))
{
for (volatile uint8_t i = 0; i < escSerial->outputCount; i++) {
uint8_t state_temp = state;
if(escOutputs[i].inverted) {
state_temp ^= ENABLE;
}
if (state_temp) {
IOHi(escOutputs[i].io);
} else {
IOLo(escOutputs[i].io);
}
}
}
else
{
if(escSerial->rxTimerHardware->output & TIMER_OUTPUT_INVERTED) {
state ^= ENABLE;
}
if (state) { if (state) {
IOHi(escSerial->txIO); IOHi(escSerial->txIO);
} else { } else {
IOLo(escSerial->txIO); IOLo(escSerial->txIO);
} }
}
} }
static void escSerialGPIOConfig(ioTag_t tag, ioConfig_t cfg) static void escSerialGPIOConfig(ioTag_t tag, ioConfig_t cfg)
@ -118,7 +156,7 @@ static void escSerialGPIOConfig(ioTag_t tag, ioConfig_t cfg)
IOConfigGPIO(IOGetByTag(tag), cfg); IOConfigGPIO(IOGetByTag(tag), cfg);
} }
void serialInputPortConfigEsc(const timerHardware_t *timerHardwarePtr) void escSerialInputPortConfig(const timerHardware_t *timerHardwarePtr)
{ {
#ifdef STM32F10X #ifdef STM32F10X
escSerialGPIOConfig(timerHardwarePtr->tag, IOCFG_IPU); escSerialGPIOConfig(timerHardwarePtr->tag, IOCFG_IPU);
@ -164,12 +202,12 @@ static void serialTimerRxConfigBL(const timerHardware_t *timerHardwarePtr, uint8
uint8_t mhz = SystemCoreClock / 2000000; uint8_t mhz = SystemCoreClock / 2000000;
TIM_DeInit(timerHardwarePtr->tim); TIM_DeInit(timerHardwarePtr->tim);
timerConfigure(timerHardwarePtr, 0xFFFF, mhz); timerConfigure(timerHardwarePtr, 0xFFFF, mhz);
serialICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, (options & SERIAL_INVERTED) ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling); escSerialICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, (options & SERIAL_INVERTED) ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling);
timerChCCHandlerInit(&escSerialPorts[reference].edgeCb, onSerialRxPinChangeBL); timerChCCHandlerInit(&escSerialPorts[reference].edgeCb, onSerialRxPinChangeBL);
timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].edgeCb, NULL); timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].edgeCb, NULL);
} }
static void serialTimerTxConfig(const timerHardware_t *timerHardwarePtr, uint8_t reference) static void escSerialTimerTxConfig(const timerHardware_t *timerHardwarePtr, uint8_t reference)
{ {
uint32_t timerPeriod=34; uint32_t timerPeriod=34;
TIM_DeInit(timerHardwarePtr->tim); TIM_DeInit(timerHardwarePtr->tim);
@ -178,7 +216,7 @@ static void serialTimerTxConfig(const timerHardware_t *timerHardwarePtr, uint8_t
timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].timerCb, NULL); timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].timerCb, NULL);
} }
static void serialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity) static void escSerialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity)
{ {
TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitTypeDef TIM_ICInitStructure;
@ -192,17 +230,17 @@ static void serialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity)
TIM_ICInit(tim, &TIM_ICInitStructure); TIM_ICInit(tim, &TIM_ICInitStructure);
} }
static void serialTimerRxConfig(const timerHardware_t *timerHardwarePtr, uint8_t reference) static void escSerialTimerRxConfig(const timerHardware_t *timerHardwarePtr, uint8_t reference)
{ {
// start bit is usually a FALLING signal // start bit is usually a FALLING signal
TIM_DeInit(timerHardwarePtr->tim); TIM_DeInit(timerHardwarePtr->tim);
timerConfigure(timerHardwarePtr, 0xFFFF, 1); timerConfigure(timerHardwarePtr, 0xFFFF, 1);
serialICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Falling); escSerialICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Falling);
timerChCCHandlerInit(&escSerialPorts[reference].edgeCb, onSerialRxPinChangeEsc); timerChCCHandlerInit(&escSerialPorts[reference].edgeCb, onSerialRxPinChangeEsc);
timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].edgeCb, NULL); timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].edgeCb, NULL);
} }
static void serialOutputPortConfig(const timerHardware_t *timerHardwarePtr) static void escSerialOutputPortConfig(const timerHardware_t *timerHardwarePtr)
{ {
escSerialGPIOConfig(timerHardwarePtr->tag, IOCFG_OUT_PP); escSerialGPIOConfig(timerHardwarePtr->tag, IOCFG_OUT_PP);
timerChITConfig(timerHardwarePtr,DISABLE); timerChITConfig(timerHardwarePtr,DISABLE);
@ -225,7 +263,11 @@ serialPort_t *openEscSerial(escSerialPortIndex_e portIndex, serialReceiveCallbac
{ {
escSerial_t *escSerial = &(escSerialPorts[portIndex]); escSerial_t *escSerial = &(escSerialPorts[portIndex]);
if(mode != PROTOCOL_KISSALL){
escSerial->rxTimerHardware = &(timerHardware[output]); escSerial->rxTimerHardware = &(timerHardware[output]);
}
escSerial->mode = mode;
escSerial->txTimerHardware = &(timerHardware[ESCSERIAL_TIMER_TX_HARDWARE]); escSerial->txTimerHardware = &(timerHardware[ESCSERIAL_TIMER_TX_HARDWARE]);
escSerial->port.vTable = escSerialVTable; escSerial->port.vTable = escSerialVTable;
@ -247,30 +289,56 @@ serialPort_t *openEscSerial(escSerialPortIndex_e portIndex, serialReceiveCallbac
escSerial->escSerialPortIndex = portIndex; escSerial->escSerialPortIndex = portIndex;
if(mode != PROTOCOL_KISSALL)
{
escSerial->txIO = IOGetByTag(escSerial->rxTimerHardware->tag); escSerial->txIO = IOGetByTag(escSerial->rxTimerHardware->tag);
serialInputPortConfigEsc(escSerial->rxTimerHardware); escSerialInputPortConfig(escSerial->rxTimerHardware);
setTxSignalEsc(escSerial, ENABLE); setTxSignalEsc(escSerial, ENABLE);
}
delay(50); delay(50);
if(mode==0){ if(mode==PROTOCOL_SIMONK){
serialTimerTxConfig(escSerial->txTimerHardware, portIndex); escSerialTimerTxConfig(escSerial->txTimerHardware, portIndex);
serialTimerRxConfig(escSerial->rxTimerHardware, portIndex); escSerialTimerRxConfig(escSerial->rxTimerHardware, portIndex);
} }
else if(mode==1){ else if(mode==PROTOCOL_BLHELI){
serialTimerTxConfigBL(escSerial->txTimerHardware, portIndex, baud); serialTimerTxConfigBL(escSerial->txTimerHardware, portIndex, baud);
serialTimerRxConfigBL(escSerial->rxTimerHardware, portIndex, options); serialTimerRxConfigBL(escSerial->rxTimerHardware, portIndex, options);
} }
else if(mode==2) { else if(mode==PROTOCOL_KISS) {
serialOutputPortConfig(escSerial->rxTimerHardware); // rx is the pin used escSerialOutputPortConfig(escSerial->rxTimerHardware); // rx is the pin used
serialTimerTxConfigBL(escSerial->txTimerHardware, portIndex, baud);
}
else if(mode==PROTOCOL_KISSALL) {
escSerial->outputCount = 0;
memset(&escOutputs, 0, sizeof(escOutputs));
pwmOutputPort_t *pwmMotors = pwmGetMotors();
for (volatile uint8_t i = 0; i < MAX_SUPPORTED_MOTORS; i++) {
if (pwmMotors[i].enabled) {
if (pwmMotors[i].io != IO_NONE) {
for (volatile uint8_t j = 0; j < USABLE_TIMER_CHANNEL_COUNT; j++) {
if(pwmMotors[i].io == IOGetByTag(timerHardware[j].tag))
{
escSerialOutputPortConfig(&timerHardware[j]);
if(timerHardware[j].output & TIMER_OUTPUT_INVERTED) {
escOutputs[escSerial->outputCount].inverted = 1;
}
break;
}
}
escOutputs[escSerial->outputCount].io = pwmMotors[i].io;
escSerial->outputCount++;
}
}
}
setTxSignalEsc(escSerial, ENABLE);
serialTimerTxConfigBL(escSerial->txTimerHardware, portIndex, baud); serialTimerTxConfigBL(escSerial->txTimerHardware, portIndex, baud);
} }
escSerial->mode = mode;
return &escSerial->port; return &escSerial->port;
} }
void serialInputPortDeConfig(const timerHardware_t *timerHardwarePtr) void escSerialInputPortDeConfig(const timerHardware_t *timerHardwarePtr)
{ {
timerChClearCCFlag(timerHardwarePtr); timerChClearCCFlag(timerHardwarePtr);
timerChITConfig(timerHardwarePtr,DISABLE); timerChITConfig(timerHardwarePtr,DISABLE);
@ -284,7 +352,7 @@ void closeEscSerial(escSerialPortIndex_e portIndex, uint16_t output)
escSerial->rxTimerHardware = &(timerHardware[output]); escSerial->rxTimerHardware = &(timerHardware[output]);
escSerial->txTimerHardware = &(timerHardware[ESCSERIAL_TIMER_TX_HARDWARE]); escSerial->txTimerHardware = &(timerHardware[ESCSERIAL_TIMER_TX_HARDWARE]);
serialInputPortDeConfig(escSerial->rxTimerHardware); escSerialInputPortDeConfig(escSerial->rxTimerHardware);
timerChConfigCallbacks(escSerial->txTimerHardware,NULL,NULL); timerChConfigCallbacks(escSerial->txTimerHardware,NULL,NULL);
timerChConfigCallbacks(escSerial->rxTimerHardware,NULL,NULL); timerChConfigCallbacks(escSerial->rxTimerHardware,NULL,NULL);
TIM_DeInit(escSerial->txTimerHardware->tim); TIM_DeInit(escSerial->txTimerHardware->tim);
@ -339,7 +407,7 @@ reload:
escSerial->isTransmittingData = true; escSerial->isTransmittingData = true;
//set output //set output
serialOutputPortConfig(escSerial->rxTimerHardware); escSerialOutputPortConfig(escSerial->rxTimerHardware);
return; return;
} }
@ -383,7 +451,7 @@ reload:
if (isEscSerialTransmitBufferEmpty((serialPort_t *)escSerial)) { if (isEscSerialTransmitBufferEmpty((serialPort_t *)escSerial)) {
escSerial->isTransmittingData = false; escSerial->isTransmittingData = false;
serialInputPortConfigEsc(escSerial->rxTimerHardware); escSerialInputPortConfig(escSerial->rxTimerHardware);
} }
} }
@ -417,7 +485,9 @@ void processTxStateBL(escSerial_t *escSerial)
//set output //set output
serialOutputPortConfig(escSerial->rxTimerHardware); if(escSerial->mode==PROTOCOL_BLHELI) {
escSerialOutputPortConfig(escSerial->rxTimerHardware);
}
return; return;
} }
@ -432,9 +502,9 @@ void processTxStateBL(escSerial_t *escSerial)
escSerial->isTransmittingData = false; escSerial->isTransmittingData = false;
if (isEscSerialTransmitBufferEmpty((serialPort_t *)escSerial)) { if (isEscSerialTransmitBufferEmpty((serialPort_t *)escSerial)) {
if(escSerial->mode==1) if(escSerial->mode==PROTOCOL_BLHELI)
{ {
serialInputPortConfigEsc(escSerial->rxTimerHardware); escSerialInputPortConfig(escSerial->rxTimerHardware);
} }
} }
} }
@ -463,7 +533,7 @@ void prepareForNextRxByteBL(escSerial_t *escSerial)
escSerial->isSearchingForStartBit = true; escSerial->isSearchingForStartBit = true;
if (escSerial->rxEdge == LEADING) { if (escSerial->rxEdge == LEADING) {
escSerial->rxEdge = TRAILING; escSerial->rxEdge = TRAILING;
serialICConfig( escSerialICConfig(
escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->tim,
escSerial->rxTimerHardware->channel, escSerial->rxTimerHardware->channel,
(escSerial->port.options & SERIAL_INVERTED) ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling (escSerial->port.options & SERIAL_INVERTED) ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling
@ -551,7 +621,7 @@ void onSerialRxPinChangeBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture)
escSerial->transmissionErrors++; escSerial->transmissionErrors++;
} }
serialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising); escSerialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising);
escSerial->rxEdge = LEADING; escSerial->rxEdge = LEADING;
escSerial->rxBitIndex = 0; escSerial->rxBitIndex = 0;
@ -569,10 +639,10 @@ void onSerialRxPinChangeBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture)
if (escSerial->rxEdge == TRAILING) { if (escSerial->rxEdge == TRAILING) {
escSerial->rxEdge = LEADING; escSerial->rxEdge = LEADING;
serialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising); escSerialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising);
} else { } else {
escSerial->rxEdge = TRAILING; escSerial->rxEdge = TRAILING;
serialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling); escSerialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling);
} }
} }
/*-------------------------BL*/ /*-------------------------BL*/
@ -605,7 +675,7 @@ void onSerialTimerEsc(timerCCHandlerRec_t *cbRec, captureCompare_t capture)
{ {
escSerial->isReceivingData=0; escSerial->isReceivingData=0;
escSerial->receiveTimeout=0; escSerial->receiveTimeout=0;
serialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, TIM_ICPolarity_Falling); escSerialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, TIM_ICPolarity_Falling);
} }
} }
@ -655,7 +725,7 @@ void onSerialRxPinChangeEsc(timerCCHandlerRec_t *cbRec, captureCompare_t capture
bits=1; bits=1;
escSerial->internalRxBuffer = 0x80; escSerial->internalRxBuffer = 0x80;
serialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, TIM_ICPolarity_Rising); escSerialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, TIM_ICPolarity_Rising);
} }
} }
escSerial->receiveTimeout = 0; escSerial->receiveTimeout = 0;
@ -763,7 +833,7 @@ void escSerialInitialize()
for (volatile uint8_t i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) { for (volatile uint8_t i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
// set outputs to pullup // set outputs to pullup
if(timerHardware[i].output==1) if(timerHardware[i].output & TIMER_OUTPUT_ENABLED)
{ {
escSerialGPIOConfig(timerHardware[i].tag, IOCFG_IPU); //GPIO_Mode_IPU escSerialGPIOConfig(timerHardware[i].tag, IOCFG_IPU); //GPIO_Mode_IPU
} }
@ -844,15 +914,23 @@ static bool ProcessExitCommand(uint8_t c)
void escEnablePassthrough(serialPort_t *escPassthroughPort, uint16_t output, uint8_t mode) void escEnablePassthrough(serialPort_t *escPassthroughPort, uint16_t output, uint8_t mode)
{ {
bool exitEsc = false; bool exitEsc = false;
uint8_t motor_output = 0;
LED0_OFF; LED0_OFF;
LED1_OFF; LED1_OFF;
//StopPwmAllMotors(); //StopPwmAllMotors();
pwmDisableMotors(); pwmDisableMotors();
passPort = escPassthroughPort; passPort = escPassthroughPort;
uint32_t escBaudrate = (mode == PROTOCOL_KISS) ? BAUDRATE_KISS : BAUDRATE_NORMAL;
if((mode == PROTOCOL_KISS) && (output == 255)){
motor_output = 255;
mode = PROTOCOL_KISSALL;
}
else {
uint8_t first_output = 0; uint8_t first_output = 0;
for (volatile uint8_t i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) { for (volatile uint8_t i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
if(timerHardware[i].output==1) if(timerHardware[i].output & TIMER_OUTPUT_ENABLED)
{ {
first_output=i; first_output=i;
break; break;
@ -860,11 +938,10 @@ void escEnablePassthrough(serialPort_t *escPassthroughPort, uint16_t output, uin
} }
//doesn't work with messy timertable //doesn't work with messy timertable
uint8_t motor_output=first_output+output-1; motor_output=first_output+output-1;
if(motor_output >=USABLE_TIMER_CHANNEL_COUNT) if(motor_output >=USABLE_TIMER_CHANNEL_COUNT)
return; return;
}
uint32_t escBaudrate = (mode == 2) ? BAUDRATE_KISS : BAUDRATE_NORMAL;
escPort = openEscSerial(ESCSERIAL1, NULL, motor_output, escBaudrate, 0, mode); escPort = openEscSerial(ESCSERIAL1, NULL, motor_output, escBaudrate, 0, mode);
uint8_t ch; uint8_t ch;
@ -898,7 +975,7 @@ void escEnablePassthrough(serialPort_t *escPassthroughPort, uint16_t output, uin
closeEscSerial(ESCSERIAL1, output); closeEscSerial(ESCSERIAL1, output);
return; return;
} }
if(mode==1){ if(mode==PROTOCOL_BLHELI){
serialWrite(escPassthroughPort, ch); // blheli loopback serialWrite(escPassthroughPort, ch); // blheli loopback
} }
serialWrite(escPort, ch); serialWrite(escPort, ch);

View file

@ -3000,6 +3000,11 @@ static void cliEscPassthrough(char *cmdline)
break; break;
case 1: case 1:
index = atoi(pch); index = atoi(pch);
if(mode == 2 && index == 255)
{
printf("passthru on all pwm outputs enabled\r\n");
}
else{
if ((index >= 0) && (index < USABLE_TIMER_CHANNEL_COUNT)) { if ((index >= 0) && (index < USABLE_TIMER_CHANNEL_COUNT)) {
printf("passthru at pwm output %d enabled\r\n", index); printf("passthru at pwm output %d enabled\r\n", index);
} }
@ -3007,6 +3012,7 @@ static void cliEscPassthrough(char *cmdline)
printf("invalid pwm output, valid range: 1 to %d\r\n", USABLE_TIMER_CHANNEL_COUNT); printf("invalid pwm output, valid range: 1 to %d\r\n", USABLE_TIMER_CHANNEL_COUNT);
return; return;
} }
}
break; break;
} }
i++; i++;