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:
timecop@gmail.com 2013-10-12 07:46:55 +00:00
parent 9ebd82c5ef
commit c682f1f21e
9 changed files with 39 additions and 19 deletions

View File

@ -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 {

View File

@ -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 },

View File

@ -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;

View File

@ -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))

View File

@ -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

View File

@ -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]);

View File

@ -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);

View File

@ -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
if (loopbackPort) {
while (serialTotalBytesWaiting(loopbackPort)) { while (serialTotalBytesWaiting(loopbackPort)) {
uint8_t b = serialRead(loopbackPort); uint8_t b = serialRead(loopbackPort);
serialWrite(loopbackPort, b); serialWrite(loopbackPort, b);
//serialWrite(core.mainport, b); //serialWrite(core.mainport, b);
}; };
}
#endif #endif
} }
} }

View File

@ -267,6 +267,9 @@ typedef struct master_t {
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