1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-15 20:35:33 +03:00

Cleanup 4way-if from cleanflight

This commit is contained in:
4712 2016-06-13 00:41:45 +02:00
parent 7aa8b623bd
commit a40c0c0442
8 changed files with 938 additions and 1085 deletions

File diff suppressed because it is too large Load diff

View file

@ -16,61 +16,126 @@
* Author: 4712 * Author: 4712
*/ */
#pragma once
#ifdef USE_SERIAL_4WAY_BLHELI_INTERFACE
#define USE_SERIAL_4WAY_BLHELI_BOOTLOADER #define USE_SERIAL_4WAY_BLHELI_BOOTLOADER
#define USE_SERIAL_4WAY_SK_BOOTLOADER #define USE_SERIAL_4WAY_SK_BOOTLOADER
#define imC2 0 typedef enum {
#define imSIL_BLB 1 imC2 = 0,
#define imATM_BLB 2 imSIL_BLB = 1,
#define imSK 3 imATM_BLB = 2,
imSK = 3,
} esc4wayInterfaceMode_e;
typedef struct { typedef enum {
GPIO_TypeDef* gpio; // Test Interface still present
uint16_t pinpos; cmd_InterfaceTestAlive = 0x30, // '0' alive
uint16_t pin; // RETURN: ACK
gpio_config_t gpio_config_INPUT;
gpio_config_t gpio_config_OUTPUT;
} escHardware_t;
extern uint8_t selected_esc; // get Protocol Version Number 01..255
cmd_ProtocolGetVersion = 0x31, // '1' version
// RETURN: uint8_t VersionNumber + ACK
bool isEscHi(uint8_t selEsc); // get Version String
bool isEscLo(uint8_t selEsc); cmd_InterfaceGetName = 0x32, // '2' name
void setEscHi(uint8_t selEsc); // RETURN: String + ACK
void setEscLo(uint8_t selEsc);
void setEscInput(uint8_t selEsc);
void setEscOutput(uint8_t selEsc);
#define ESC_IS_HI isEscHi(selected_esc) //get Version Number 01..255
#define ESC_IS_LO isEscLo(selected_esc) cmd_InterfaceGetVersion = 0x33, // '3' version
#define ESC_SET_HI setEscHi(selected_esc) // RETURN: uint16_t VersionNumber + ACK
#define ESC_SET_LO setEscLo(selected_esc)
#define ESC_INPUT setEscInput(selected_esc)
#define ESC_OUTPUT setEscOutput(selected_esc)
typedef struct ioMem_s { // Exit / Restart Interface - can be used to switch to Box Mode
uint8_t D_NUM_BYTES; cmd_InterfaceExit = 0x34, // '4' exit
uint8_t D_FLASH_ADDR_H; // RETURN: ACK
uint8_t D_FLASH_ADDR_L;
uint8_t *D_PTR_I;
} ioMem_t;
extern ioMem_t ioMem; // Reset the Device connected to the Interface
cmd_DeviceReset = 0x35, // '5' reset
// PARAM: uint8_t escId
// RETURN: ACK
typedef union __attribute__ ((packed)) { // Get the Device ID connected
uint8_t bytes[2]; // cmd_DeviceGetID = 0x36, // '6' device id; removed since 06/106
uint16_t word; // RETURN: uint8_t DeviceID + ACK
} uint8_16_u;
typedef union __attribute__ ((packed)) { // Initialize Flash Access for Device connected
uint8_t bytes[4]; // Autodetects interface protocol; retruns device signature and protocol
uint16_t words[2]; cmd_DeviceInitFlash = 0x37, // '7' init flash access
uint32_t dword; // PARAM: uint8_t escId
} uint8_32_u; // RETURN: uint8_t deviceInfo[4] + ACK
//extern uint8_32_u DeviceInfo; // Erase the whole Device Memory of connected Device
cmd_DeviceEraseAll = 0x38, // '8' erase all
// RETURN: ACK
bool isMcuConnected(void); // Erase one Page of Device Memory of connected Device
uint8_t Initialize4WayInterface(void); cmd_DevicePageErase = 0x39, // '9' page erase
void Process4WayInterface(mspPort_t *mspPort, bufWriter_t *bufwriter); // PARAM: uint8_t PageNumber (512B pages)
void DeInitialize4WayInterface(void); // RETURN: APageNumber ACK
// Read to Buffer from FLASH Memory of connected Device
// Buffer Len is Max 256 Bytes, 0 means 256 Bytes
cmd_DeviceRead = 0x3A, // ':' read Device
// PARAM: [ADRESS] uint8_t BuffLen
// RETURN: [ADRESS, len] Buffer[0..256] ACK
// Write Buffer to FLASH Memory of connected Device
// Buffer Len is Max 256 Bytes, 0 means 256 Bytes
cmd_DeviceWrite = 0x3B, // ';' write
// PARAM: [ADRESS + BuffLen] Buffer[1..256]
// RETURN: ACK
// Set C2CK low infinite - permanent Reset state (unimplemented)
cmd_DeviceC2CK_LOW = 0x3C, // '<'
// RETURN: ACK
// Read to Buffer from EEPROM Memory of connected Device
// Buffer Len is Max 256 Bytes, 0 means 256 Bytes
cmd_DeviceReadEEprom = 0x3D, // '=' read Device
// PARAM: [ADRESS] uint8_t BuffLen
// RETURN: [ADRESS + BuffLen] + Buffer[1..256] ACK
// Write Buffer to EEPROM Memory of connected Device
// Buffer Len is Max 256 Bytes, 0 means 256 Bytes
cmd_DeviceWriteEEprom = 0x3E, // '>' write
// PARAM: [ADRESS + BuffLen] Buffer[1..256]
// RETURN: ACK
// Set Interface Mode
cmd_InterfaceSetMode = 0x3F, // '?'
// PARAM: uint8_t Mode (interfaceMode_e)
// RETURN: ACK
} esc4wayCmd_e;
// responses
typedef enum {
esc4wayAck_OK = 0x00,
// esc4wayAck_I_UNKNOWN_ERROR = 0x01,
esc4wayAck_I_INVALID_CMD = 0x02,
esc4wayAck_I_INVALID_CRC = 0x03,
esc4wayAck_I_VERIFY_ERROR = 0x04,
// esc4wayAck_D_INVALID_COMMAND = 0x05,
// esc4wayAck_D_COMMAND_FAILED = 0x06,
// esc4wayAck_D_UNKNOWN_ERROR = 0x07,
esc4wayAck_I_INVALID_CHANNEL = 0x08,
esc4wayAck_I_INVALID_PARAM = 0x09,
esc4wayAck_D_GENERAL_ERROR = 0x0f,
} esc4wayAck_e;
typedef struct escDeviceInfo_s {
uint16_t signature; // lower 16 bit of signature
uint8_t signature2; // top 8 bit of signature for SK / BootMsg last char from BL
uint8_t interfaceMode;
} escDeviceInfo_t;
extern bool esc4wayExitRequested; // flag that exit was requested. Set by esc4wayProcessCmd, used internally by esc4wayProcess
int esc4wayInit(void);
void esc4wayStart(void);
void esc4wayRelease(void);
void esc4wayProcess(serialPort_t *serial);
esc4wayAck_e esc4wayProcessCmd(esc4wayCmd_e command, uint16_t addr, uint8_t *data, int inLen, int *outLen);
#endif

View file

@ -24,7 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "platform.h" #include "platform.h"
#ifdef USE_SERIAL_4WAY_BLHELI_INTERFACE #include "common/utils.h"
#include "drivers/system.h" #include "drivers/system.h"
#include "drivers/serial.h" #include "drivers/serial.h"
#include "drivers/buf_writer.h" #include "drivers/buf_writer.h"
@ -33,9 +33,10 @@
#include "io/serial.h" #include "io/serial.h"
#include "io/serial_msp.h" #include "io/serial_msp.h"
#include "io/serial_4way.h" #include "io/serial_4way.h"
#include "io/serial_4way_impl.h"
#include "io/serial_4way_avrootloader.h" #include "io/serial_4way_avrootloader.h"
#ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
#if defined(USE_SERIAL_4WAY_BLHELI_INTERFACE) && defined(USE_SERIAL_4WAY_BLHELI_BOOTLOADER)
// Bootloader commands // Bootloader commands
// RunCmd // RunCmd
@ -60,251 +61,231 @@
// Bootloader result codes // Bootloader result codes
#define brSUCCESS 0x30 #define BR_SUCCESS 0x30
#define brERRORCOMMAND 0xC1 #define BR_ERRORCOMMAND 0xC1
#define brERRORCRC 0xC2 #define BR_ERRORCRC 0xC2
#define brNONE 0xFF #define BR_NONE 0xFF
#define START_BIT_TIMEOUT 2000 // 2ms
#define START_BIT_TIMEOUT_MS 2 #define BIT_TIME 52 // 52uS
#define BIT_TIME_HALVE (BIT_TIME >> 1) // 26uS
#define BIT_TIME_3_4 (BIT_TIME_HALVE + (BIT_TIME_HALVE >> 1)) // 39uS
#define START_BIT_TIME (BIT_TIME_3_4)
#define BIT_TIME (52) //52uS static int suart_getc(void)
#define BIT_TIME_HALVE (BIT_TIME >> 1) //26uS
#define START_BIT_TIME (BIT_TIME_HALVE + 1)
//#define STOP_BIT_TIME ((BIT_TIME * 9) + BIT_TIME_HALVE)
static uint8_t suart_getc_(uint8_t *bt)
{ {
uint32_t btime; uint32_t btime;
uint32_t start_time; uint32_t start_time;
uint32_t wait_time = millis() + START_BIT_TIMEOUT_MS; uint32_t wait_time = micros() + START_BIT_TIMEOUT;
while (ESC_IS_HI) { while (ESC_IS_HI) {
// check for startbit begin // check for startbit begin
if (millis() >= wait_time) { if (micros() >= wait_time) {
return 0; return -1;
} }
} }
// start bit // start bit
start_time = micros(); start_time = micros();
btime = start_time + START_BIT_TIME; btime = start_time + START_BIT_TIME;
uint16_t bitmask = 0; uint16_t bitmask = 0;
uint8_t bit = 0; for(int bit = 0; bit < 10; bit++) {
while (micros() < btime); while (cmp32(micros(), btime) < 0);
while(1) {
if (ESC_IS_HI) if (ESC_IS_HI)
{
bitmask |= (1 << bit); bitmask |= (1 << bit);
}
btime = btime + BIT_TIME; btime = btime + BIT_TIME;
bit++;
if (bit == 10) break;
while (micros() < btime);
} }
// check start bit and stop bit // check start bit and stop bit
if ((bitmask & 1) || (!(bitmask & (1 << 9)))) { if ((bitmask & (1 << 0)) || (!(bitmask & (1 << 9)))) {
return 0; return -1;
} }
*bt = bitmask >> 1; return bitmask >> 1;
return 1;
} }
static void suart_putc_(uint8_t *tx_b) static void suart_putc(uint8_t byte)
{ {
// shift out stopbit first // send one idle bit first (stopbit from previous byte)
uint16_t bitmask = (*tx_b << 2) | 1 | (1 << 10); uint16_t bitmask = (byte << 2) | (1 << 0) | (1 << 10);
uint32_t btime = micros(); uint32_t btime = micros();
while(1) { while(1) {
if(bitmask & 1) { if(bitmask & 1)
ESC_SET_HI; // 1 ESC_SET_HI; // 1
} else
else {
ESC_SET_LO; // 0 ESC_SET_LO; // 0
}
btime = btime + BIT_TIME; btime = btime + BIT_TIME;
bitmask = (bitmask >> 1); bitmask >>= 1;
if (bitmask == 0) break; // stopbit shifted out - but don't wait if (bitmask == 0)
while (micros() < btime); break; // stopbit shifted out - but don't wait
while (cmp32(micros(), btime) < 0);
} }
} }
static uint8_16_u CRC_16; static uint16_t crc16Byte(uint16_t from, uint8_t byte)
static uint8_16_u LastCRC_16;
static void ByteCrc(uint8_t *bt)
{ {
uint8_t xb = *bt; uint16_t crc16 = from;
for (uint8_t i = 0; i < 8; i++) for (int i = 0; i < 8; i++) {
{ if (((byte & 0x01) ^ (crc16 & 0x0001)) != 0) {
if (((xb & 0x01) ^ (CRC_16.word & 0x0001)) !=0 ) { crc16 >>= 1;
CRC_16.word = CRC_16.word >> 1; crc16 ^= 0xA001;
CRC_16.word = CRC_16.word ^ 0xA001;
} else { } else {
CRC_16.word = CRC_16.word >> 1; crc16 >>= 1;
} }
xb = xb >> 1; byte >>= 1;
} }
return crc16;
} }
static uint8_t BL_ReadBuf(uint8_t *pstring, uint8_t len) static uint8_t BL_ReadBuf(uint8_t *pstring, int len, bool checkCrc)
{ {
// len 0 means 256 int crc = 0;
CRC_16.word = 0; int c;
LastCRC_16.word = 0;
uint8_t LastACK = brNONE;
do {
if(!suart_getc_(pstring)) goto timeout;
ByteCrc(pstring);
pstring++;
len--;
} while(len > 0);
if(isMcuConnected()) { uint8_t lastACK = BR_NONE;
//With CRC read 3 more for(int i = 0; i < len; i++) {
if(!suart_getc_(&LastCRC_16.bytes[0])) goto timeout; int c;
if(!suart_getc_(&LastCRC_16.bytes[1])) goto timeout; if ((c = suart_getc()) < 0) goto timeout;
if(!suart_getc_(&LastACK)) goto timeout; crc = crc16Byte(crc, c);
if (CRC_16.word != LastCRC_16.word) { pstring[i] = c;
LastACK = brERRORCRC;
} }
if(checkCrc) {
// With CRC read 3 more
for(int i = 0; i < 2; i++) { // checksum 2 CRC bytes
if ((c = suart_getc()) < 0) goto timeout;
crc = crc16Byte(crc, c);
}
if((c = suart_getc()) < 0) goto timeout;
lastACK = c;
if (crc != 0) // CRC of correct message is 0
lastACK = BR_ERRORCRC;
} else { } else {
if(!suart_getc_(&LastACK)) goto timeout; if((c = suart_getc()) < 0) goto timeout;
lastACK = c;
} }
timeout: timeout:
return (LastACK == brSUCCESS); return (lastACK == BR_SUCCESS);
} }
static void BL_SendBuf(uint8_t *pstring, uint8_t len) static void BL_SendBuf(uint8_t *pstring, int len, bool appendCrc)
{ {
ESC_OUTPUT; ESC_OUTPUT;
CRC_16.word=0; uint16_t crc = 0;
do { for(int i = 0; i < len; i++) {
suart_putc_(pstring); suart_putc(pstring[i]);
ByteCrc(pstring); crc = crc16Byte(crc, pstring[i]);
pstring++; }
len--; if (appendCrc) {
} while (len > 0); suart_putc(crc & 0xff);
suart_putc(crc >> 8);
if (isMcuConnected()) {
suart_putc_(&CRC_16.bytes[0]);
suart_putc_(&CRC_16.bytes[1]);
} }
ESC_INPUT; ESC_INPUT;
} }
uint8_t BL_ConnectEx(uint8_32_u *pDeviceInfo) uint8_t BL_ConnectEx(escDeviceInfo_t *pDeviceInfo)
{ {
#define BootMsgLen 4 #define BOOT_MSG_LEN 4
#define DevSignHi (BootMsgLen) #define DevSignHi (BOOT_MSG_LEN)
#define DevSignLo (BootMsgLen+1) #define DevSignLo (BOOT_MSG_LEN + 1)
//DeviceInfo.dword=0; is set before memset(pDeviceInfo, 0, sizeof(*pDeviceInfo));
uint8_t BootInfo[9]; uint8_t bootInfo[BOOT_MSG_LEN + 4];
uint8_t BootMsg[BootMsgLen-1] = "471"; static const uint8_t bootMsgCheck[BOOT_MSG_LEN - 1] = "471";
// x * 0 + 9 // x * 0 + 9
#if defined(USE_SERIAL_4WAY_SK_BOOTLOADER) #if defined(USE_SERIAL_4WAY_SK_BOOTLOADER)
uint8_t BootInit[] = {0,0,0,0,0,0,0,0,0,0,0,0,0x0D,'B','L','H','e','l','i',0xF4,0x7D}; // SK message was sent during autodetection, use longer preamble
BL_SendBuf(BootInit, 21); uint8_t bootInit[] = {0,0,0,0,0,0,0,0,0,0,0,0,0x0D,'B','L','H','e','l','i',0xF4,0x7D};
#else #else
uint8_t BootInit[] = {0,0,0,0,0,0,0,0,0x0D,'B','L','H','e','l','i',0xF4,0x7D}; uint8_t bootInit[] = { 0,0,0,0,0,0,0,0,0x0D,'B','L','H','e','l','i',0xF4,0x7D};
BL_SendBuf(BootInit, 17);
#endif #endif
if (!BL_ReadBuf(BootInfo, BootMsgLen + 4)) { BL_SendBuf(bootInit, sizeof(bootInit), false);
if (!BL_ReadBuf(bootInfo, sizeof(bootInfo), false))
return 0; return 0;
}
// BootInfo has no CRC (ACK byte already analyzed... ) // BootInfo has no CRC (ACK byte already analyzed... )
// Format = BootMsg("471c") SIGNATURE_001, SIGNATURE_002, BootVersion (always 6), BootPages (,ACK) // Format = BootMsg("471c") SIGNATURE_001, SIGNATURE_002, BootVersion (always 6), BootPages (,ACK)
for (uint8_t i = 0; i < (BootMsgLen - 1); i++) { // Check only the first 3 letters -> 471x OK if(memcmp(bootInfo, bootMsgCheck, sizeof(bootMsgCheck)) != 0) // Check only the first 3 letters -> 471x OK
if (BootInfo[i] != BootMsg[i]) { return 0;
return (0);
}
}
//only 2 bytes used $1E9307 -> 0x9307 pDeviceInfo->signature2 = bootInfo[BOOT_MSG_LEN - 1]; // taken from bootloaderMsg part, ascii 'c' now
pDeviceInfo->bytes[2] = BootInfo[BootMsgLen - 1]; pDeviceInfo->signature = (bootInfo[DevSignHi] << 8) | bootInfo[DevSignLo]; // SIGNATURE_001, SIGNATURE_002
pDeviceInfo->bytes[1] = BootInfo[DevSignHi]; return 1;
pDeviceInfo->bytes[0] = BootInfo[DevSignLo];
return (1);
} }
static uint8_t BL_GetACK(uint32_t Timeout) static uint8_t BL_GetACK(int timeout)
{ {
uint8_t LastACK = brNONE; int c;
while (!(suart_getc_(&LastACK)) && (Timeout)) { while ((c = suart_getc()) < 0)
Timeout--; if(--timeout < 0) // timeout=1 -> 1 retry
} ; return BR_NONE;
return (LastACK); return c;
} }
uint8_t BL_SendCMDKeepAlive(void) uint8_t BL_SendCMDKeepAlive(void)
{ {
uint8_t sCMD[] = {CMD_KEEP_ALIVE, 0}; uint8_t sCMD[] = {CMD_KEEP_ALIVE, 0};
BL_SendBuf(sCMD, 2); BL_SendBuf(sCMD, sizeof(sCMD), true);
if (BL_GetACK(1) != brERRORCOMMAND) { if (BL_GetACK(1) != BR_ERRORCOMMAND)
return 0; return 0;
}
return 1; return 1;
} }
void BL_SendCMDRunRestartBootloader(uint8_32_u *pDeviceInfo) void BL_SendCMDRunRestartBootloader(void)
{ {
uint8_t sCMD[] = {RestartBootloader, 0}; uint8_t sCMD[] = {RestartBootloader, 0};
pDeviceInfo->bytes[0] = 1; BL_SendBuf(sCMD, sizeof(sCMD), true); // sends simply 4 x 0x00 (CRC = 00)
BL_SendBuf(sCMD, 2); //sends simply 4 x 0x00 (CRC =00)
return; return;
} }
static uint8_t BL_SendCMDSetAddress(ioMem_t *pMem) //supports only 16 bit Adr static uint8_t BL_SendCMDSetAddress(ioMem_t *pMem) //supports only 16 bit Adr
{ {
// skip if adr == 0xFFFF // skip if adr == 0xFFFF
if((pMem->D_FLASH_ADDR_H == 0xFF) && (pMem->D_FLASH_ADDR_L == 0xFF)) return 1; if((pMem->addr == 0xffff))
uint8_t sCMD[] = {CMD_SET_ADDRESS, 0, pMem->D_FLASH_ADDR_H, pMem->D_FLASH_ADDR_L }; return 1;
BL_SendBuf(sCMD, 4); uint8_t sCMD[] = {CMD_SET_ADDRESS, 0, pMem->addr >> 8, pMem->addr & 0xff };
return (BL_GetACK(2) == brSUCCESS); BL_SendBuf(sCMD, sizeof(sCMD), true);
return BL_GetACK(2) == BR_SUCCESS;
} }
static uint8_t BL_SendCMDSetBuffer(ioMem_t *pMem) static uint8_t BL_SendCMDSetBuffer(ioMem_t *pMem)
{ {
uint8_t sCMD[] = {CMD_SET_BUFFER, 0, 0, pMem->D_NUM_BYTES}; uint16_t len = pMem->len;
if (pMem->D_NUM_BYTES == 0) { uint8_t sCMD[] = {CMD_SET_BUFFER, 0, len >> 8, len & 0xff};
// set high byte BL_SendBuf(sCMD, sizeof(sCMD), true);
sCMD[2] = 1; if (BL_GetACK(2) != BR_NONE)
} return 0;
BL_SendBuf(sCMD, 4); BL_SendBuf(pMem->data, len, true);
if (BL_GetACK(2) != brNONE) return 0; return BL_GetACK(40) == BR_SUCCESS;
BL_SendBuf(pMem->D_PTR_I, pMem->D_NUM_BYTES);
return (BL_GetACK(40) == brSUCCESS);
} }
static uint8_t BL_ReadA(uint8_t cmd, ioMem_t *pMem) static uint8_t BL_ReadA(uint8_t cmd, ioMem_t *pMem)
{ {
if (BL_SendCMDSetAddress(pMem)) { if(!BL_SendCMDSetAddress(pMem))
uint8_t sCMD[] = {cmd, pMem->D_NUM_BYTES};
BL_SendBuf(sCMD, 2);
return (BL_ReadBuf(pMem->D_PTR_I, pMem->D_NUM_BYTES ));
}
return 0; return 0;
unsigned len = pMem->len;
uint8_t sCMD[] = {cmd, len & 0xff}; // 0x100 is sent a 0x00 here
BL_SendBuf(sCMD, sizeof(sCMD), true);
return BL_ReadBuf(pMem->data, len, true);
} }
static uint8_t BL_WriteA(uint8_t cmd, ioMem_t *pMem, uint32_t timeout) static uint8_t BL_WriteA(uint8_t cmd, ioMem_t *pMem, uint32_t timeout)
{ {
if (BL_SendCMDSetAddress(pMem)) { if(!BL_SendCMDSetAddress(pMem))
if (!BL_SendCMDSetBuffer(pMem)) return 0;
uint8_t sCMD[] = {cmd, 0x01};
BL_SendBuf(sCMD, 2);
return (BL_GetACK(timeout) == brSUCCESS);
}
return 0; return 0;
if (!BL_SendCMDSetBuffer(pMem))
return 0;
uint8_t sCMD[] = {cmd, 0x01};
BL_SendBuf(sCMD, sizeof(sCMD), true);
return BL_GetACK(timeout) == BR_SUCCESS;
} }
uint8_t BL_ReadFlash(uint8_t interface_mode, ioMem_t *pMem) uint8_t BL_ReadFlashATM(ioMem_t *pMem)
{ {
if(interface_mode == imATM_BLB) {
return BL_ReadA(CMD_READ_FLASH_ATM, pMem); return BL_ReadA(CMD_READ_FLASH_ATM, pMem);
} else { }
uint8_t BL_ReadFlashSIL(ioMem_t *pMem)
{
return BL_ReadA(CMD_READ_FLASH_SIL, pMem); return BL_ReadA(CMD_READ_FLASH_SIL, pMem);
}
} }
@ -315,23 +296,22 @@ uint8_t BL_ReadEEprom(ioMem_t *pMem)
uint8_t BL_PageErase(ioMem_t *pMem) uint8_t BL_PageErase(ioMem_t *pMem)
{ {
if (BL_SendCMDSetAddress(pMem)) { if(!BL_SendCMDSetAddress(pMem))
uint8_t sCMD[] = {CMD_ERASE_FLASH, 0x01};
BL_SendBuf(sCMD, 2);
return (BL_GetACK((40 / START_BIT_TIMEOUT_MS)) == brSUCCESS);
}
return 0; return 0;
uint8_t sCMD[] = {CMD_ERASE_FLASH, 0x01};
BL_SendBuf(sCMD, sizeof(sCMD), true);
return BL_GetACK(40 * 1000 / START_BIT_TIMEOUT) == BR_SUCCESS;
} }
uint8_t BL_WriteEEprom(ioMem_t *pMem) uint8_t BL_WriteEEprom(ioMem_t *pMem)
{ {
return BL_WriteA(CMD_PROG_EEPROM, pMem, (3000 / START_BIT_TIMEOUT_MS)); return BL_WriteA(CMD_PROG_EEPROM, pMem, 3000 * 1000 / START_BIT_TIMEOUT);
} }
uint8_t BL_WriteFlash(ioMem_t *pMem) uint8_t BL_WriteFlash(ioMem_t *pMem)
{ {
return BL_WriteA(CMD_PROG_FLASH, pMem, (40 / START_BIT_TIMEOUT_MS)); return BL_WriteA(CMD_PROG_FLASH, pMem, 40 * 1000 / START_BIT_TIMEOUT);
} }
#endif #endif
#endif

View file

@ -20,12 +20,17 @@
#pragma once #pragma once
#ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
void BL_SendBootInit(void); void BL_SendBootInit(void);
uint8_t BL_ConnectEx(uint8_32_u *pDeviceInfo); uint8_t BL_ConnectEx(escDeviceInfo_t *pDeviceInfo);
uint8_t BL_SendCMDKeepAlive(void); uint8_t BL_SendCMDKeepAlive(void);
uint8_t BL_PageErase(ioMem_t *pMem);
uint8_t BL_ReadEEprom(ioMem_t *pMem);
uint8_t BL_WriteEEprom(ioMem_t *pMem); uint8_t BL_WriteEEprom(ioMem_t *pMem);
uint8_t BL_ReadEEprom(ioMem_t *pMem);
uint8_t BL_PageErase(ioMem_t *pMem);
uint8_t BL_WriteFlash(ioMem_t *pMem); uint8_t BL_WriteFlash(ioMem_t *pMem);
uint8_t BL_ReadFlash(uint8_t interface_mode, ioMem_t *pMem); uint8_t BL_ReadFlashATM(ioMem_t *pMem);
void BL_SendCMDRunRestartBootloader(uint8_32_u *pDeviceInfo); uint8_t BL_ReadFlashSIL(ioMem_t *pMem);
void BL_SendCMDRunRestartBootloader(void);
#endif

View file

@ -0,0 +1,47 @@
/*
* This file is part of Cleanflight.
*
* Cleanflight is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Cleanflight is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
* Author: 4712
*/
typedef struct {
GPIO_TypeDef* gpio;
uint16_t pinpos;
uint16_t pin;
gpio_config_t gpio_config_INPUT;
gpio_config_t gpio_config_OUTPUT;
} escHardware_t;
extern uint8_t escSelected;
bool isEscHi(uint8_t selEsc);
bool isEscLo(uint8_t selEsc);
void setEscHi(uint8_t selEsc);
void setEscLo(uint8_t selEsc);
void setEscInput(uint8_t selEsc);
void setEscOutput(uint8_t selEsc);
#define ESC_IS_HI isEscHi(escSelected)
#define ESC_IS_LO isEscLo(escSelected)
#define ESC_SET_HI setEscHi(escSelected)
#define ESC_SET_LO setEscLo(escSelected)
#define ESC_INPUT setEscInput(escSelected)
#define ESC_OUTPUT setEscOutput(escSelected)
typedef struct ioMem_s {
uint16_t len;
uint16_t addr;
uint8_t *data;
} ioMem_t;

View file

@ -23,35 +23,38 @@
#include <stdlib.h> #include <stdlib.h>
#include "platform.h" #include "platform.h"
#ifdef USE_SERIAL_4WAY_BLHELI_INTERFACE #include "common/utils.h"
#include "drivers/gpio.h" #include "drivers/gpio.h"
#include "drivers/buf_writer.h" #include "drivers/buf_writer.h"
#include "drivers/pwm_mapping.h" #include "drivers/pwm_mapping.h"
#include "drivers/serial.h" #include "drivers/serial.h"
#include "drivers/system.h"
#include "config/config.h" #include "config/config.h"
#include "io/serial.h" #include "io/serial.h"
#include "io/serial_msp.h" #include "io/serial_msp.h"
#include "io/serial_4way.h" #include "io/serial_4way.h"
#include "io/serial_4way_impl.h"
#include "io/serial_4way_stk500v2.h" #include "io/serial_4way_stk500v2.h"
#include "drivers/system.h"
#ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
#define BIT_LO_US (32) //32uS #if defined(USE_SERIAL_4WAY_BLHELI_INTERFACE) && defined(USE_SERIAL_4WAY_SK_BOOTLOADER)
#define BIT_HI_US (2*BIT_LO_US)
static uint8_t StkInBuf[16];
#define BIT_LO_US 32 //32uS
#define BIT_HI_US (2 * BIT_LO_US)
static uint8_t stkInBuf[16];
#define STK_BIT_TIMEOUT 250 // micro seconds #define STK_BIT_TIMEOUT 250 // micro seconds
#define STK_WAIT_TICKS (1000 / STK_BIT_TIMEOUT) // per ms #define STK_WAIT_TICKS (1000 / STK_BIT_TIMEOUT) // per ms
#define STK_WAITCYLCES (STK_WAIT_TICKS * 35) // 35ms #define STK_WAITCYLCES (STK_WAIT_TICKS * 35) // 35ms
#define STK_WAITCYLCES_START (STK_WAIT_TICKS / 2) // 0.5 ms #define STK_WAITCYLCES_START (STK_WAIT_TICKS / 2) // 0.5ms
#define STK_WAITCYLCES_EXT (STK_WAIT_TICKS * 5000) //5 s #define STK_WAITCYLCES_EXT (STK_WAIT_TICKS * 5000) // 5s
#define WaitPinLo while (ESC_IS_HI) {if (micros() > timeout_timer) goto timeout;} #define WaitPinLo while (ESC_IS_HI) { if (cmp32(micros(), timeout_timer) > 0) goto timeout; }
#define WaitPinHi while (ESC_IS_LO) {if (micros() > timeout_timer) goto timeout;} #define WaitPinHi while (ESC_IS_LO) { if (cmp32(micros(), timeout_timer) > 0) goto timeout; }
static uint32_t LastBitTime; static uint32_t lastBitTime;
static uint32_t HiLoTsh; static uint32_t hiLoTsh;
static uint8_t SeqNumber; static uint8_t SeqNumber;
static uint8_t StkCmd; static uint8_t StkCmd;
@ -77,7 +80,7 @@ static uint8_t ckSumOut;
#define CmdFlashEepromRead 0xA0 #define CmdFlashEepromRead 0xA0
#define EnterIspCmd1 0xAC #define EnterIspCmd1 0xAC
#define EnterIspCmd2 0x53 #define EnterIspCmd2 0x53
#define signature_r 0x30 #define SPI_SIGNATURE_READ 0x30
#define delay_us(x) delayMicroseconds(x) #define delay_us(x) delayMicroseconds(x)
#define IRQ_OFF // dummy #define IRQ_OFF // dummy
@ -108,7 +111,7 @@ static void StkSendByte(uint8_t dat)
} }
} }
static void StkSendPacketHeader(void) static void StkSendPacketHeader(uint16_t len)
{ {
IRQ_OFF; IRQ_OFF;
ESC_OUTPUT; ESC_OUTPUT;
@ -118,6 +121,9 @@ static void StkSendPacketHeader(void)
ckSumOut = 0; ckSumOut = 0;
StkSendByte(MESSAGE_START); StkSendByte(MESSAGE_START);
StkSendByte(++SeqNumber); StkSendByte(++SeqNumber);
StkSendByte(len >> 8);
StkSendByte(len & 0xff);
StkSendByte(TOKEN);
} }
static void StkSendPacketFooter(void) static void StkSendPacketFooter(void)
@ -129,16 +135,14 @@ static void StkSendPacketFooter(void)
IRQ_ON; IRQ_ON;
} }
static int8_t ReadBit(void) static int8_t ReadBit(void)
{ {
uint32_t btimer = micros(); uint32_t btimer = micros();
uint32_t timeout_timer = btimer + STK_BIT_TIMEOUT; uint32_t timeout_timer = btimer + STK_BIT_TIMEOUT;
WaitPinLo; WaitPinLo;
WaitPinHi; WaitPinHi;
LastBitTime = micros() - btimer; lastBitTime = micros() - btimer;
if (LastBitTime <= HiLoTsh) { if (lastBitTime <= hiLoTsh) {
timeout_timer = timeout_timer + STK_BIT_TIMEOUT; timeout_timer = timeout_timer + STK_BIT_TIMEOUT;
WaitPinLo; WaitPinLo;
WaitPinHi; WaitPinHi;
@ -151,30 +155,27 @@ timeout:
return -1; return -1;
} }
static uint8_t ReadByte(uint8_t *bt) static int ReadByte(void)
{ {
*bt = 0; uint8_t byte = 0;
for (uint8_t i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
int8_t bit = ReadBit(); int8_t bit = ReadBit();
if (bit == -1) goto timeout; if (bit < 0)
if (bit == 1) { return -1; // timeout
*bt |= (1 << i); byte |= bit << i;
} }
} ckSumIn ^= byte;
ckSumIn ^=*bt; return byte;
return 1;
timeout:
return 0;
} }
static uint8_t StkReadLeader(void) static uint8_t StkReadLeader(void)
{ {
// Reset learned timing // Reset learned timing
HiLoTsh = BIT_HI_US + BIT_LO_US; hiLoTsh = BIT_HI_US + BIT_LO_US;
// Wait for the first bit // Wait for the first bit
uint32_t waitcycl; //250uS each int waitcycl; //250uS each
if((StkCmd == CMD_PROGRAM_EEPROM_ISP) || (StkCmd == CMD_CHIP_ERASE_ISP)) { if((StkCmd == CMD_PROGRAM_EEPROM_ISP) || (StkCmd == CMD_CHIP_ERASE_ISP)) {
waitcycl = STK_WAITCYLCES_EXT; waitcycl = STK_WAITCYLCES_EXT;
@ -183,57 +184,54 @@ static uint8_t StkReadLeader(void)
} else { } else {
waitcycl= STK_WAITCYLCES; waitcycl= STK_WAITCYLCES;
} }
for ( ; waitcycl >0 ; waitcycl--) { while(ReadBit() < 0 && --waitcycl > 0);
//check is not timeout if (waitcycl <= 0)
if (ReadBit() >- 1) break; goto timeout;
}
//Skip the first bits // Skip the first bits
if (waitcycl == 0){ for (int i = 0; i < 10; i++) {
if (ReadBit() < 0)
goto timeout; goto timeout;
} }
for (uint8_t i = 0; i < 10; i++) { // learn timing (0.75 * lastBitTime)
if (ReadBit() == -1) goto timeout; hiLoTsh = (lastBitTime >> 1) + (lastBitTime >> 2);
}
// learn timing
HiLoTsh = (LastBitTime >> 1) + (LastBitTime >> 2);
// Read until we get a 0 bit // Read until we get a 0 bit
int8_t bit; int bit;
do { do {
bit = ReadBit(); bit = ReadBit();
if (bit == -1) goto timeout; if (bit < 0)
goto timeout;
} while (bit > 0); } while (bit > 0);
return 1; return 1;
timeout: timeout:
return 0; return 0;
} }
static uint8_t StkRcvPacket(uint8_t *pstring) static uint8_t StkRcvPacket(uint8_t *pstring, int maxLen)
{ {
uint8_t bt = 0; int byte;
uint8_16_u Len; int len;
IRQ_OFF; IRQ_OFF;
if (!StkReadLeader()) goto Err; if (!StkReadLeader()) goto Err;
ckSumIn=0; ckSumIn=0;
if (!ReadByte(&bt) || (bt != MESSAGE_START)) goto Err; if ((byte = ReadByte()) < 0 || (byte != MESSAGE_START)) goto Err;
if (!ReadByte(&bt) || (bt != SeqNumber)) goto Err; if ((byte = ReadByte()) < 0 || (byte != SeqNumber)) goto Err;
ReadByte(&Len.bytes[1]); len = ReadByte() << 8;
if (Len.bytes[1] > 1) goto Err; len |= ReadByte();
ReadByte(&Len.bytes[0]); if(len < 1 || len >= 256 + 4) // will catch timeout too; limit length to max expected size
if (Len.bytes[0] < 1) goto Err; goto Err;
if (!ReadByte(&bt) || (bt != TOKEN)) goto Err; if ((byte = ReadByte()) < 0 || (byte != TOKEN)) goto Err;
if (!ReadByte(&bt) || (bt != StkCmd)) goto Err; if ((byte = ReadByte()) < 0 || (byte != StkCmd)) goto Err;
if (!ReadByte(&bt) || (bt != STATUS_CMD_OK)) goto Err; if ((byte = ReadByte()) < 0 || (byte != STATUS_CMD_OK)) goto Err;
for (uint16_t i = 0; i < (Len.word - 2); i++) for (int i = 0; i < len - 2; i++) {
{ if ((byte = ReadByte()) < 0) goto Err;
if (!ReadByte(pstring)) goto Err; if(i < maxLen) // limit saved length (buffer is only 256B, but memory read reply contains additional status + 1 unknown byte)
pstring++; pstring[i] = byte;
} }
ReadByte(&bt); ReadByte(); // read checksum
if (ckSumIn != 0) goto Err; if (ckSumIn != 0) goto Err;
IRQ_ON; IRQ_ON;
return 1; return 1;
@ -242,25 +240,24 @@ Err:
return 0; return 0;
} }
static uint8_t _CMD_SPI_MULTI_EX(volatile uint8_t * ResByte,uint8_t Cmd,uint8_t AdrHi,uint8_t AdrLo) static uint8_t _CMD_SPI_MULTI_EX(uint8_t * resByte, uint8_t subcmd, uint16_t addr)
{ {
StkCmd= CMD_SPI_MULTI; StkCmd = CMD_SPI_MULTI;
StkSendPacketHeader(); StkSendPacketHeader(8);
StkSendByte(0); // hi byte Msg len
StkSendByte(8); // lo byte Msg len
StkSendByte(TOKEN);
StkSendByte(CMD_SPI_MULTI); StkSendByte(CMD_SPI_MULTI);
StkSendByte(4); // NumTX StkSendByte(4); // NumTX
StkSendByte(4); // NumRX StkSendByte(4); // NumRX
StkSendByte(0); // RxStartAdr StkSendByte(0); // RxStartAdr
StkSendByte(Cmd); // {TxData} Cmd StkSendByte(subcmd); // {TxData} Cmd
StkSendByte(AdrHi); // {TxData} AdrHi StkSendByte(addr >> 8); // {TxData} AdrHi
StkSendByte(AdrLo); // {TxData} AdrLoch StkSendByte(addr & 0xff); // {TxData} AdrLow
StkSendByte(0); // {TxData} 0 StkSendByte(0); // {TxData} 0
StkSendPacketFooter(); StkSendPacketFooter();
if (StkRcvPacket((void *)StkInBuf)) { // NumRX + 3 if (StkRcvPacket(stkInBuf, sizeof(stkInBuf))) { // NumRX + 3
if ((StkInBuf[0] == 0x00) && ((StkInBuf[1] == Cmd)||(StkInBuf[1] == 0x00)/* ignore zero returns */) &&(StkInBuf[2] == 0x00)) { if ((stkInBuf[0] == 0x00)
*ResByte = StkInBuf[3]; && ((stkInBuf[1] == subcmd) || (stkInBuf[1] == 0x00 /* ignore zero returns */))
&& (stkInBuf[2] == 0x00)) {
*resByte = stkInBuf[3];
} }
return 1; return 1;
} }
@ -270,61 +267,37 @@ static uint8_t _CMD_SPI_MULTI_EX(volatile uint8_t * ResByte,uint8_t Cmd,uint8_t
static uint8_t _CMD_LOAD_ADDRESS(ioMem_t *pMem) static uint8_t _CMD_LOAD_ADDRESS(ioMem_t *pMem)
{ {
// ignore 0xFFFF // ignore 0xFFFF
// assume address is set before and we read or write the immediately following package // assume address is set before and we read or write the immediately following memory
if((pMem->D_FLASH_ADDR_H == 0xFF) && (pMem->D_FLASH_ADDR_L == 0xFF)) return 1; if((pMem->addr == 0xffff))
return 1;
StkCmd = CMD_LOAD_ADDRESS; StkCmd = CMD_LOAD_ADDRESS;
StkSendPacketHeader(); StkSendPacketHeader(5);
StkSendByte(0); // hi byte Msg len
StkSendByte(5); // lo byte Msg len
StkSendByte(TOKEN);
StkSendByte(CMD_LOAD_ADDRESS); StkSendByte(CMD_LOAD_ADDRESS);
StkSendByte(0); StkSendByte(0);
StkSendByte(0); StkSendByte(0);
StkSendByte(pMem->D_FLASH_ADDR_H); StkSendByte(pMem->addr >> 8);
StkSendByte(pMem->D_FLASH_ADDR_L); StkSendByte(pMem->addr & 0xff);
StkSendPacketFooter(); StkSendPacketFooter();
return (StkRcvPacket((void *)StkInBuf)); return StkRcvPacket(stkInBuf, sizeof(stkInBuf));
} }
static uint8_t _CMD_READ_MEM_ISP(ioMem_t *pMem) static uint8_t _CMD_READ_MEM_ISP(ioMem_t *pMem)
{ {
uint8_t LenHi; StkSendPacketHeader(4);
if (pMem->D_NUM_BYTES>0) {
LenHi=0;
} else {
LenHi=1;
}
StkSendPacketHeader();
StkSendByte(0); // hi byte Msg len
StkSendByte(4); // lo byte Msg len
StkSendByte(TOKEN);
StkSendByte(StkCmd); StkSendByte(StkCmd);
StkSendByte(LenHi); StkSendByte(pMem->len >> 8);
StkSendByte(pMem->D_NUM_BYTES); StkSendByte(pMem->len & 0xff);
StkSendByte(CmdFlashEepromRead); StkSendByte(CmdFlashEepromRead);
StkSendPacketFooter(); StkSendPacketFooter();
return (StkRcvPacket(pMem->D_PTR_I)); return StkRcvPacket(pMem->data, pMem->len);
} }
static uint8_t _CMD_PROGRAM_MEM_ISP(ioMem_t *pMem) static uint8_t _CMD_PROGRAM_MEM_ISP(ioMem_t *pMem)
{ {
uint8_16_u Len; StkSendPacketHeader(pMem->len + 10);
uint8_t LenLo = pMem->D_NUM_BYTES;
uint8_t LenHi;
if (LenLo) {
LenHi = 0;
Len.word = LenLo + 10;
} else {
LenHi = 1;
Len.word = 256 + 10;
}
StkSendPacketHeader();
StkSendByte(Len.bytes[1]); // high byte Msg len
StkSendByte(Len.bytes[0]); // low byte Msg len
StkSendByte(TOKEN);
StkSendByte(StkCmd); StkSendByte(StkCmd);
StkSendByte(LenHi); StkSendByte(pMem->len >> 8);
StkSendByte(LenLo); StkSendByte(pMem->len & 0xff);
StkSendByte(0); // mode StkSendByte(0); // mode
StkSendByte(0); // delay StkSendByte(0); // delay
StkSendByte(0); // cmd1 StkSendByte(0); // cmd1
@ -332,47 +305,41 @@ static uint8_t _CMD_PROGRAM_MEM_ISP(ioMem_t *pMem)
StkSendByte(0); // cmd3 StkSendByte(0); // cmd3
StkSendByte(0); // poll1 StkSendByte(0); // poll1
StkSendByte(0); // poll2 StkSendByte(0); // poll2
do { for(int i = 0; i < pMem->len; i++)
StkSendByte(*pMem->D_PTR_I); StkSendByte(pMem->data[i]);
pMem->D_PTR_I++;
LenLo--;
} while (LenLo);
StkSendPacketFooter(); StkSendPacketFooter();
return StkRcvPacket((void *)StkInBuf); return StkRcvPacket(stkInBuf, sizeof(stkInBuf));
} }
uint8_t Stk_SignOn(void) uint8_t Stk_SignOn(void)
{ {
StkCmd=CMD_SIGN_ON; StkCmd = CMD_SIGN_ON;
StkSendPacketHeader(); StkSendPacketHeader(1);
StkSendByte(0); // hi byte Msg len
StkSendByte(1); // lo byte Msg len
StkSendByte(TOKEN);
StkSendByte(CMD_SIGN_ON); StkSendByte(CMD_SIGN_ON);
StkSendPacketFooter(); StkSendPacketFooter();
return (StkRcvPacket((void *) StkInBuf)); return StkRcvPacket(stkInBuf, sizeof(stkInBuf));
} }
uint8_t Stk_ConnectEx(uint8_32_u *pDeviceInfo) uint8_t Stk_ConnectEx(escDeviceInfo_t *pDeviceInfo)
{ {
if (Stk_SignOn()) { if (!Stk_SignOn())
if (_CMD_SPI_MULTI_EX(&pDeviceInfo->bytes[1], signature_r,0,1)) {
if (_CMD_SPI_MULTI_EX(&pDeviceInfo->bytes[0], signature_r,0,2)) {
return 1;
}
}
}
return 0; return 0;
uint8_t signature[3]; // device signature, MSB first
for(unsigned i = 0; i < sizeof(signature); i++) {
if (!_CMD_SPI_MULTI_EX(&signature[i], SPI_SIGNATURE_READ, i))
return 0;
}
// convert signature to little endian
pDeviceInfo->signature = (signature[1] << 8) | signature[2];
pDeviceInfo->signature2 = signature[0];
return 1;
} }
uint8_t Stk_Chip_Erase(void) uint8_t Stk_Chip_Erase(void)
{ {
StkCmd = CMD_CHIP_ERASE_ISP; StkCmd = CMD_CHIP_ERASE_ISP;
StkSendPacketHeader(); StkSendPacketHeader(7);
StkSendByte(0); // high byte Msg len StkSendByte(StkCmd);
StkSendByte(7); // low byte Msg len
StkSendByte(TOKEN);
StkSendByte(CMD_CHIP_ERASE_ISP);
StkSendByte(20); // ChipErase_eraseDelay atmega8 StkSendByte(20); // ChipErase_eraseDelay atmega8
StkSendByte(0); // ChipErase_pollMethod atmega8 StkSendByte(0); // ChipErase_pollMethod atmega8
StkSendByte(0xAC); StkSendByte(0xAC);
@ -380,44 +347,40 @@ uint8_t Stk_Chip_Erase(void)
StkSendByte(0x13); StkSendByte(0x13);
StkSendByte(0x76); StkSendByte(0x76);
StkSendPacketFooter(); StkSendPacketFooter();
return (StkRcvPacket(StkInBuf)); return StkRcvPacket(stkInBuf, sizeof(stkInBuf));
} }
uint8_t Stk_ReadFlash(ioMem_t *pMem) uint8_t Stk_ReadFlash(ioMem_t *pMem)
{ {
if (_CMD_LOAD_ADDRESS(pMem)) { if (!_CMD_LOAD_ADDRESS(pMem))
StkCmd = CMD_READ_FLASH_ISP;
return (_CMD_READ_MEM_ISP(pMem));
}
return 0; return 0;
StkCmd = CMD_READ_FLASH_ISP;
return _CMD_READ_MEM_ISP(pMem);
} }
uint8_t Stk_ReadEEprom(ioMem_t *pMem) uint8_t Stk_ReadEEprom(ioMem_t *pMem)
{ {
if (_CMD_LOAD_ADDRESS(pMem)) { if (!_CMD_LOAD_ADDRESS(pMem))
StkCmd = CMD_READ_EEPROM_ISP;
return (_CMD_READ_MEM_ISP(pMem));
}
return 0; return 0;
StkCmd = CMD_READ_EEPROM_ISP;
return _CMD_READ_MEM_ISP(pMem);
} }
uint8_t Stk_WriteFlash(ioMem_t *pMem) uint8_t Stk_WriteFlash(ioMem_t *pMem)
{ {
if (_CMD_LOAD_ADDRESS(pMem)) { if (!_CMD_LOAD_ADDRESS(pMem))
StkCmd = CMD_PROGRAM_FLASH_ISP;
return (_CMD_PROGRAM_MEM_ISP(pMem));
}
return 0; return 0;
StkCmd = CMD_PROGRAM_FLASH_ISP;
return _CMD_PROGRAM_MEM_ISP(pMem);
} }
uint8_t Stk_WriteEEprom(ioMem_t *pMem) uint8_t Stk_WriteEEprom(ioMem_t *pMem)
{ {
if (_CMD_LOAD_ADDRESS(pMem)) { if (!_CMD_LOAD_ADDRESS(pMem))
StkCmd = CMD_PROGRAM_EEPROM_ISP;
return (_CMD_PROGRAM_MEM_ISP(pMem));
}
return 0; return 0;
StkCmd = CMD_PROGRAM_EEPROM_ISP;
return _CMD_PROGRAM_MEM_ISP(pMem);
} }
#endif
#endif #endif

View file

@ -17,11 +17,14 @@
*/ */
#pragma once #pragma once
#ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
uint8_t Stk_SignOn(void); uint8_t Stk_SignOn(void);
uint8_t Stk_ConnectEx(uint8_32_u *pDeviceInfo); uint8_t Stk_ConnectEx(escDeviceInfo_t *pDeviceInfo);
uint8_t Stk_ReadEEprom(ioMem_t *pMem); uint8_t Stk_ReadEEprom(ioMem_t *pMem);
uint8_t Stk_WriteEEprom(ioMem_t *pMem); uint8_t Stk_WriteEEprom(ioMem_t *pMem);
uint8_t Stk_ReadFlash(ioMem_t *pMem); uint8_t Stk_ReadFlash(ioMem_t *pMem);
uint8_t Stk_WriteFlash(ioMem_t *pMem); uint8_t Stk_WriteFlash(ioMem_t *pMem);
uint8_t Stk_Chip_Erase(void); uint8_t Stk_Chip_Erase(void);
#endif

View file

@ -93,9 +93,7 @@
#include "serial_msp.h" #include "serial_msp.h"
#ifdef USE_SERIAL_4WAY_BLHELI_INTERFACE
#include "io/serial_4way.h" #include "io/serial_4way.h"
#endif
static serialPort_t *mspSerialPort; static serialPort_t *mspSerialPort;
@ -1736,7 +1734,7 @@ static bool processInCommand(void)
// switch all motor lines HI // switch all motor lines HI
// reply the count of ESC found // reply the count of ESC found
headSerialReply(1); headSerialReply(1);
serialize8(Initialize4WayInterface()); serialize8(esc4wayInit());
// because we do not come back after calling Process4WayInterface // because we do not come back after calling Process4WayInterface
// proceed with a success reply first // proceed with a success reply first
tailSerialReply(); tailSerialReply();
@ -1747,7 +1745,7 @@ static bool processInCommand(void)
// rem: App: Wait at least appx. 500 ms for BLHeli to jump into // rem: App: Wait at least appx. 500 ms for BLHeli to jump into
// bootloader mode before try to connect any ESC // bootloader mode before try to connect any ESC
// Start to activate here // Start to activate here
Process4WayInterface(currentPort, writer); esc4wayProcess(currentPort->port);
// former used MSP uart is still active // former used MSP uart is still active
// proceed as usual with MSP commands // proceed as usual with MSP commands
break; break;