Softserial can now be enabled/disabled via the SOFTSERIAL feature switch in the command line. Softserial baud rate can be set via softserial_baudrate setting. Added input & output inversion support, use softserial_inverted setting by Dominic Clifton
git-svn-id: https://afrodevices.googlecode.com/svn/trunk/baseflight@435 7c89a4a9-59b9-e629-4cfe-3a2d53b20e61
This commit is contained in:
parent
9ebd82c5ef
commit
c682f1f21e
|
@ -74,6 +74,7 @@ typedef enum {
|
||||||
FEATURE_POWERMETER = 1 << 12,
|
FEATURE_POWERMETER = 1 << 12,
|
||||||
FEATURE_VARIO = 1 << 13,
|
FEATURE_VARIO = 1 << 13,
|
||||||
FEATURE_3D = 1 << 14,
|
FEATURE_3D = 1 << 14,
|
||||||
|
FEATURE_SOFTSERIAL = 1 << 15,
|
||||||
} AvailableFeatures;
|
} AvailableFeatures;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -44,7 +44,7 @@ static const char * const mixerNames[] = {
|
||||||
static const char * const featureNames[] = {
|
static const char * const featureNames[] = {
|
||||||
"PPM", "VBAT", "INFLIGHT_ACC_CAL", "SERIALRX", "MOTOR_STOP",
|
"PPM", "VBAT", "INFLIGHT_ACC_CAL", "SERIALRX", "MOTOR_STOP",
|
||||||
"SERVO_TILT", "GYRO_SMOOTHING", "LED_RING", "GPS",
|
"SERVO_TILT", "GYRO_SMOOTHING", "LED_RING", "GPS",
|
||||||
"FAILSAFE", "SONAR", "TELEMETRY", "POWERMETER", "VARIO", "3D",
|
"FAILSAFE", "SONAR", "TELEMETRY", "POWERMETER", "VARIO", "3D", "SOFTSERIAL",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,6 +115,8 @@ const clivalue_t valueTable[] = {
|
||||||
{ "servo_pwm_rate", VAR_UINT16, &mcfg.servo_pwm_rate, 50, 498 },
|
{ "servo_pwm_rate", VAR_UINT16, &mcfg.servo_pwm_rate, 50, 498 },
|
||||||
{ "retarded_arm", VAR_UINT8, &mcfg.retarded_arm, 0, 1 },
|
{ "retarded_arm", VAR_UINT8, &mcfg.retarded_arm, 0, 1 },
|
||||||
{ "serial_baudrate", VAR_UINT32, &mcfg.serial_baudrate, 1200, 115200 },
|
{ "serial_baudrate", VAR_UINT32, &mcfg.serial_baudrate, 1200, 115200 },
|
||||||
|
{ "softserial_baudrate", VAR_UINT32, &mcfg.softserial_baudrate, 9600, 19200 },
|
||||||
|
{ "softserial_inverted", VAR_UINT8, &mcfg.softserial_inverted, 0, 1 },
|
||||||
{ "gps_baudrate", VAR_UINT32, &mcfg.gps_baudrate, 1200, 115200 },
|
{ "gps_baudrate", VAR_UINT32, &mcfg.gps_baudrate, 1200, 115200 },
|
||||||
{ "serialrx_type", VAR_UINT8, &mcfg.serialrx_type, 0, 2 },
|
{ "serialrx_type", VAR_UINT8, &mcfg.serialrx_type, 0, 2 },
|
||||||
{ "vbatscale", VAR_UINT8, &mcfg.vbatscale, 10, 200 },
|
{ "vbatscale", VAR_UINT8, &mcfg.vbatscale, 10, 200 },
|
||||||
|
|
|
@ -208,6 +208,8 @@ static void resetConf(void)
|
||||||
mcfg.gps_baudrate = 115200;
|
mcfg.gps_baudrate = 115200;
|
||||||
// serial (USART1) baudrate
|
// serial (USART1) baudrate
|
||||||
mcfg.serial_baudrate = 115200;
|
mcfg.serial_baudrate = 115200;
|
||||||
|
mcfg.softserial_baudrate = 19200;
|
||||||
|
mcfg.softserial_inverted = 0;
|
||||||
mcfg.looptime = 3500;
|
mcfg.looptime = 3500;
|
||||||
mcfg.rssi_aux_channel = 0;
|
mcfg.rssi_aux_channel = 0;
|
||||||
|
|
||||||
|
|
|
@ -323,11 +323,9 @@ bool pwmInit(drv_pwm_config_t *init)
|
||||||
if (init->useUART && (port == PWM3 || port == PWM4))
|
if (init->useUART && (port == PWM3 || port == PWM4))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#ifdef SOFTSERIAL_19200_LOOPBACK
|
|
||||||
// skip softSerial ports
|
// skip softSerial ports
|
||||||
if ((port == PWM5 || port == PWM6 || port == PWM7 || port == PWM8))
|
if (init->useSoftSerial && (port == PWM5 || port == PWM6 || port == PWM7 || port == PWM8))
|
||||||
continue;
|
continue;
|
||||||
#endif
|
|
||||||
|
|
||||||
// skip ADC for powerMeter if configured
|
// skip ADC for powerMeter if configured
|
||||||
if (init->adcChannel && (init->adcChannel == port))
|
if (init->adcChannel && (init->adcChannel == port))
|
||||||
|
|
|
@ -8,6 +8,7 @@ typedef struct drv_pwm_config_t {
|
||||||
bool enableInput;
|
bool enableInput;
|
||||||
bool usePPM;
|
bool usePPM;
|
||||||
bool useUART;
|
bool useUART;
|
||||||
|
bool useSoftSerial;
|
||||||
bool useServos;
|
bool useServos;
|
||||||
bool extraServos; // configure additional 4 channels in PPM mode as servos, not motors
|
bool extraServos; // configure additional 4 channels in PPM mode as servos, not motors
|
||||||
bool airplane; // fixed wing hardware config, lots of servos etc
|
bool airplane; // fixed wing hardware config, lots of servos etc
|
||||||
|
|
|
@ -17,12 +17,16 @@ void onSerialTimer(uint8_t portIndex, uint16_t capture);
|
||||||
|
|
||||||
uint8_t readRxSignal(softSerial_t *softSerial)
|
uint8_t readRxSignal(softSerial_t *softSerial)
|
||||||
{
|
{
|
||||||
return !(digitalIn(softSerial->rxTimerHardware->gpio, softSerial->rxTimerHardware->pin) == 0);
|
uint8_t invertedSignal = (digitalIn(softSerial->rxTimerHardware->gpio, softSerial->rxTimerHardware->pin) == 0);
|
||||||
|
if (softSerial->isInverted) {
|
||||||
|
return invertedSignal;
|
||||||
|
}
|
||||||
|
return !invertedSignal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTxSignal(softSerial_t *softSerial, uint8_t state)
|
void setTxSignal(softSerial_t *softSerial, uint8_t state)
|
||||||
{
|
{
|
||||||
if (state) {
|
if ((state == 1 && softSerial->isInverted == false) || (state == 0 && softSerial->isInverted == true)) {
|
||||||
digitalHi(softSerial->txTimerHardware->gpio, softSerial->txTimerHardware->pin);
|
digitalHi(softSerial->txTimerHardware->gpio, softSerial->txTimerHardware->pin);
|
||||||
} else {
|
} else {
|
||||||
digitalLo(softSerial->txTimerHardware->gpio, softSerial->txTimerHardware->pin);
|
digitalLo(softSerial->txTimerHardware->gpio, softSerial->txTimerHardware->pin);
|
||||||
|
@ -82,7 +86,7 @@ void serialOutputPortConfig(const timerHardware_t *timerHardwarePtr)
|
||||||
softSerialGPIOConfig(timerHardwarePtr->gpio, timerHardwarePtr->pin, Mode_Out_PP);
|
softSerialGPIOConfig(timerHardwarePtr->gpio, timerHardwarePtr->pin, Mode_Out_PP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSoftSerial1(uint32_t baud)
|
void setupSoftSerial1(uint32_t baud, uint8_t inverted)
|
||||||
{
|
{
|
||||||
int portIndex = 0;
|
int portIndex = 0;
|
||||||
softSerial_t *softSerial = &(softSerialPorts[portIndex]);
|
softSerial_t *softSerial = &(softSerialPorts[portIndex]);
|
||||||
|
@ -90,6 +94,7 @@ void setupSoftSerial1(uint32_t baud)
|
||||||
softSerial->port.vTable = softSerialVTable;
|
softSerial->port.vTable = softSerialVTable;
|
||||||
softSerial->port.mode = MODE_RXTX;
|
softSerial->port.mode = MODE_RXTX;
|
||||||
softSerial->port.baudRate = baud;
|
softSerial->port.baudRate = baud;
|
||||||
|
softSerial->isInverted = inverted;
|
||||||
|
|
||||||
softSerial->rxTimerHardware = &(timerHardware[SOFT_SERIAL_1_TIMER_RX_HARDWARE]);
|
softSerial->rxTimerHardware = &(timerHardware[SOFT_SERIAL_1_TIMER_RX_HARDWARE]);
|
||||||
softSerial->txTimerHardware = &(timerHardware[SOFT_SERIAL_1_TIMER_TX_HARDWARE]);
|
softSerial->txTimerHardware = &(timerHardware[SOFT_SERIAL_1_TIMER_TX_HARDWARE]);
|
||||||
|
|
|
@ -29,6 +29,7 @@ typedef struct softSerial_s {
|
||||||
uint16_t internalRxBuffer; // excluding start/stop bits
|
uint16_t internalRxBuffer; // excluding start/stop bits
|
||||||
uint16_t internalTxBuffer; // includes start and stop bits
|
uint16_t internalTxBuffer; // includes start and stop bits
|
||||||
|
|
||||||
|
uint8_t isInverted;
|
||||||
} softSerial_t;
|
} softSerial_t;
|
||||||
|
|
||||||
extern timerHardware_t* serialTimerHardware;
|
extern timerHardware_t* serialTimerHardware;
|
||||||
|
@ -36,7 +37,7 @@ extern softSerial_t softSerialPorts[];
|
||||||
|
|
||||||
extern const struct serialPortVTable softSerialVTable[];
|
extern const struct serialPortVTable softSerialVTable[];
|
||||||
|
|
||||||
void setupSoftSerial1(uint32_t baud);
|
void setupSoftSerial1(uint32_t baud, uint8_t inverted);
|
||||||
|
|
||||||
// serialPort API
|
// serialPort API
|
||||||
void softSerialWriteByte(serialPort_t *instance, uint8_t ch);
|
void softSerialWriteByte(serialPort_t *instance, uint8_t ch);
|
||||||
|
|
29
src/main.c
29
src/main.c
|
@ -30,6 +30,7 @@ int main(void)
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
drv_pwm_config_t pwm_params;
|
drv_pwm_config_t pwm_params;
|
||||||
drv_adc_config_t adc_params;
|
drv_adc_config_t adc_params;
|
||||||
|
serialPort_t* loopbackPort = NULL;
|
||||||
|
|
||||||
systemInit();
|
systemInit();
|
||||||
#ifdef USE_LAME_PRINTF
|
#ifdef USE_LAME_PRINTF
|
||||||
|
@ -59,6 +60,7 @@ int main(void)
|
||||||
else
|
else
|
||||||
pwm_params.airplane = false;
|
pwm_params.airplane = false;
|
||||||
pwm_params.useUART = feature(FEATURE_GPS) || feature(FEATURE_SERIALRX); // spektrum/sbus support uses UART too
|
pwm_params.useUART = feature(FEATURE_GPS) || feature(FEATURE_SERIALRX); // spektrum/sbus support uses UART too
|
||||||
|
pwm_params.useSoftSerial = feature(FEATURE_SOFTSERIAL);
|
||||||
pwm_params.usePPM = feature(FEATURE_PPM);
|
pwm_params.usePPM = feature(FEATURE_PPM);
|
||||||
pwm_params.enableInput = !feature(FEATURE_SERIALRX); // disable inputs if using spektrum
|
pwm_params.enableInput = !feature(FEATURE_SERIALRX); // disable inputs if using spektrum
|
||||||
pwm_params.useServos = core.useServo;
|
pwm_params.useServos = core.useServo;
|
||||||
|
@ -133,11 +135,14 @@ int main(void)
|
||||||
batteryInit();
|
batteryInit();
|
||||||
|
|
||||||
serialInit(mcfg.serial_baudrate);
|
serialInit(mcfg.serial_baudrate);
|
||||||
#ifdef SOFTSERIAL_19200_LOOPBACK
|
|
||||||
setupSoftSerial1(19200);
|
if (feature(FEATURE_SOFTSERIAL)) {
|
||||||
serialPort_t* loopbackPort = (serialPort_t*)&(softSerialPorts[0]);
|
setupSoftSerial1(mcfg.softserial_baudrate, mcfg.softserial_inverted);
|
||||||
serialPrint(loopbackPort, "LOOPBACK 19200 ENABLED\r\n");
|
#ifdef SOFTSERIAL_LOOPBACK
|
||||||
|
loopbackPort = (serialPort_t*)&(softSerialPorts[0]);
|
||||||
|
serialPrint(loopbackPort, "LOOPBACK ENABLED\r\n");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
previousTime = micros();
|
previousTime = micros();
|
||||||
if (mcfg.mixerConfiguration == MULTITYPE_GIMBAL)
|
if (mcfg.mixerConfiguration == MULTITYPE_GIMBAL)
|
||||||
|
@ -149,13 +154,15 @@ int main(void)
|
||||||
// loopy
|
// loopy
|
||||||
while (1) {
|
while (1) {
|
||||||
loop();
|
loop();
|
||||||
#ifdef SOFTSERIAL_19200_LOOPBACK
|
#ifdef SOFTSERIAL_LOOPBACK
|
||||||
while (serialTotalBytesWaiting(loopbackPort)) {
|
if (loopbackPort) {
|
||||||
|
while (serialTotalBytesWaiting(loopbackPort)) {
|
||||||
uint8_t b = serialRead(loopbackPort);
|
|
||||||
serialWrite(loopbackPort, b);
|
uint8_t b = serialRead(loopbackPort);
|
||||||
//serialWrite(core.mainport, b);
|
serialWrite(loopbackPort, b);
|
||||||
};
|
//serialWrite(core.mainport, b);
|
||||||
|
};
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
src/mw.h
3
src/mw.h
|
@ -266,6 +266,9 @@ typedef struct master_t {
|
||||||
uint32_t gps_baudrate; // GPS baudrate
|
uint32_t gps_baudrate; // GPS baudrate
|
||||||
|
|
||||||
uint32_t serial_baudrate;
|
uint32_t serial_baudrate;
|
||||||
|
|
||||||
|
uint32_t softserial_baudrate;
|
||||||
|
uint8_t softserial_inverted; // use inverted softserial input and output signals
|
||||||
|
|
||||||
config_t profile[3]; // 3 separate profiles
|
config_t profile[3]; // 3 separate profiles
|
||||||
uint8_t current_profile; // currently loaded profile
|
uint8_t current_profile; // currently loaded profile
|
||||||
|
|
Loading…
Reference in New Issue