mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-19 22:35:23 +03:00
Merge pull request #4845 from azolyoung/add_old_splitfirmware_support
add old split firmware support
This commit is contained in:
commit
aec732e9f0
3 changed files with 102 additions and 4 deletions
|
@ -187,11 +187,11 @@ static bool runcamDeviceSendRequestAndWaitingResp(runcamDevice_t *device, uint8_
|
|||
// only the command sending on initializing step need retry logic,
|
||||
// otherwise, the timeout of 1000 ms is enough for the response from device
|
||||
if (commandID == RCDEVICE_PROTOCOL_COMMAND_GET_DEVICE_INFO) {
|
||||
max_retries = 3;
|
||||
timeoutMs = 100; // we have test some device, 100ms as timeout, and retry times be 3, it's stable for most case
|
||||
max_retries = 5;
|
||||
timeoutMs = 60; // we have test some device, 60ms as timeout, and retry times be 5, it's stable for most case
|
||||
}
|
||||
|
||||
while (max_retries--) {
|
||||
for (int i = 0; i < max_retries; i++) {
|
||||
// flush rx buffer
|
||||
runcamDeviceFlushRxBuffer(device);
|
||||
|
||||
|
@ -212,10 +212,95 @@ static bool runcamDeviceSendRequestAndWaitingResp(runcamDevice_t *device, uint8_
|
|||
return false;
|
||||
}
|
||||
|
||||
static uint8_t calcCRCFromData(uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t crc = 0x00;
|
||||
while (len--) {
|
||||
crc ^= *ptr++;
|
||||
for (i = 8; i > 0; --i) {
|
||||
if (crc & 0x80) {
|
||||
crc = (crc << 1) ^ 0x31;
|
||||
} else {
|
||||
crc = (crc << 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
static void sendCtrlCommand(runcamDevice_t *device, rcsplit_ctrl_argument_e argument)
|
||||
{
|
||||
if (!device->serialPort) {
|
||||
return ;
|
||||
}
|
||||
|
||||
uint8_t uart_buffer[5] = {0};
|
||||
uint8_t crc = 0;
|
||||
|
||||
uart_buffer[0] = RCSPLIT_PACKET_HEADER;
|
||||
uart_buffer[1] = RCSPLIT_PACKET_CMD_CTRL;
|
||||
uart_buffer[2] = argument;
|
||||
uart_buffer[3] = RCSPLIT_PACKET_TAIL;
|
||||
crc = calcCRCFromData(uart_buffer, 4);
|
||||
|
||||
// build up a full request [header]+[command]+[argument]+[crc]+[tail]
|
||||
uart_buffer[3] = crc;
|
||||
uart_buffer[4] = RCSPLIT_PACKET_TAIL;
|
||||
|
||||
// write to device
|
||||
serialWriteBuf(device->serialPort, uart_buffer, 5);
|
||||
}
|
||||
|
||||
// get the device info(firmware version, protocol version and features, see the
|
||||
// definition of runcamDeviceInfo_t to know more)
|
||||
static bool runcamDeviceGetDeviceInfo(runcamDevice_t *device, uint8_t *outputBuffer)
|
||||
{
|
||||
// Send "who are you" command to device to detect the device whether is running RCSplit FW1.0 or RCSplit FW1.1
|
||||
int max_retries = 2;
|
||||
for (int i = 0; i < max_retries; i++) {
|
||||
runcamDeviceFlushRxBuffer(device);
|
||||
sendCtrlCommand(device, RCSPLIT_CTRL_ARGU_WHO_ARE_YOU);
|
||||
|
||||
timeMs_t timeout = millis() + 500;
|
||||
uint8_t response[5] = { 0 };
|
||||
while (millis() < timeout) {
|
||||
if (serialRxBytesWaiting(device->serialPort) >= 5) {
|
||||
response[0] = serialRead(device->serialPort);
|
||||
response[1] = serialRead(device->serialPort);
|
||||
response[2] = serialRead(device->serialPort);
|
||||
response[3] = serialRead(device->serialPort);
|
||||
response[4] = serialRead(device->serialPort);
|
||||
if (response[0] != RCSPLIT_PACKET_HEADER || response[1] != RCSPLIT_PACKET_CMD_CTRL || response[2] != RCSPLIT_CTRL_ARGU_WHO_ARE_YOU || response[4] != RCSPLIT_PACKET_TAIL) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t crcFromPacket = response[3];
|
||||
response[3] = response[4]; // move packet tail field to crc field, and calc crc with first 4 bytes
|
||||
uint8_t crc = calcCRCFromData(response, 4);
|
||||
if (crc != crcFromPacket) {
|
||||
break;
|
||||
}
|
||||
|
||||
// generate response for RCSplit FW 1.0 and FW 1.1
|
||||
outputBuffer[0] = RCDEVICE_PROTOCOL_HEADER;
|
||||
// protocol version
|
||||
outputBuffer[1] = RCDEVICE_PROTOCOL_RCSPLIT_VERSION;
|
||||
// features
|
||||
outputBuffer[2] = RCDEVICE_PROTOCOL_FEATURE_SIMULATE_POWER_BUTTON | RCDEVICE_PROTOCOL_FEATURE_SIMULATE_WIFI_BUTTON | RCDEVICE_PROTOCOL_FEATURE_CHANGE_MODE;
|
||||
outputBuffer[3] = 0;
|
||||
|
||||
crc = 0;
|
||||
const uint8_t * const end = outputBuffer + 4;
|
||||
for (const uint8_t *ptr = outputBuffer; ptr < end; ++ptr) {
|
||||
crc = crc8_dvb_s2(crc, *ptr);
|
||||
}
|
||||
outputBuffer[4] = crc;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return runcamDeviceSendRequestAndWaitingResp(device, RCDEVICE_PROTOCOL_COMMAND_GET_DEVICE_INFO, NULL, 0, outputBuffer, NULL);
|
||||
}
|
||||
|
||||
|
@ -277,7 +362,14 @@ bool runcamDeviceInit(runcamDevice_t *device)
|
|||
|
||||
bool runcamDeviceSimulateCameraButton(runcamDevice_t *device, uint8_t operation)
|
||||
{
|
||||
if (device->info.protocolVersion == RCDEVICE_PROTOCOL_RCSPLIT_VERSION) {
|
||||
sendCtrlCommand(device, operation + 1);
|
||||
} else if (device->info.protocolVersion == RCDEVICE_PROTOCOL_VERSION_1_0) {
|
||||
runcamDeviceSendPacket(device, RCDEVICE_PROTOCOL_COMMAND_CAMERA_CONTROL, &operation, sizeof(operation));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
#define SPRACINGF3MINI_REV 2
|
||||
#endif
|
||||
|
||||
// Space reduction measures to make the firmware fit into flash:
|
||||
#undef USE_RCDEVICE
|
||||
|
||||
#define CONFIG_FASTLOOP_PREFERRED_ACC ACC_NONE
|
||||
|
||||
#define LED0_PIN PB3
|
||||
|
|
|
@ -1575,6 +1575,9 @@ extern "C" {
|
|||
// // reset the input buffer
|
||||
testData.responseDataReadPos = 0;
|
||||
testData.indexOfCurrentRespBuf++;
|
||||
if (testData.indexOfCurrentRespBuf >= testData.responseBufCount) {
|
||||
testData.indexOfCurrentRespBuf = 0;
|
||||
}
|
||||
// testData.maxTimesOfRespDataAvailable = testData.responseDataLen + 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue