2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
31 #ifdef USE_SERIAL_4WAY_BLHELI_INTERFACE
33 #include "drivers/buf_writer.h"
34 #include "drivers/io.h"
35 #include "drivers/serial.h"
36 #include "drivers/time.h"
37 #include "drivers/timer.h"
38 #include "drivers/light_led.h"
40 #include "flight/mixer.h"
42 #include "io/beeper.h"
43 #include "io/serial_4way.h"
45 #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
46 #include "io/serial_4way_avrootloader.h"
48 #if defined(USE_SERIAL_4WAY_SK_BOOTLOADER)
49 #include "io/serial_4way_stk500v2.h"
52 #if defined(USE_HAL_DRIVER)
53 #define Bit_RESET GPIO_PIN_RESET
54 #elif defined(AT32F435)
61 #define RX_LED_OFF LED0_OFF
62 #define RX_LED_ON LED0_ON
64 #define TX_LED_OFF LED1_OFF
65 #define TX_LED_ON LED1_ON
67 #define TX_LED_OFF LED0_OFF
68 #define TX_LED_ON LED0_ON
77 #define SERIAL_4WAY_INTERFACE_NAME_STR "m4wFCIntf"
78 // *** change to adapt Revision
79 #define SERIAL_4WAY_VER_MAIN 20
80 #define SERIAL_4WAY_VER_SUB_1 (uint8_t) 0
81 #define SERIAL_4WAY_VER_SUB_2 (uint8_t) 06
83 #define SERIAL_4WAY_PROTOCOL_VER 108
86 #if (SERIAL_4WAY_VER_MAIN > 24)
87 #error "beware of SERIAL_4WAY_VER_SUB_1 is uint8_t"
90 #define SERIAL_4WAY_VERSION (uint16_t) ((SERIAL_4WAY_VER_MAIN * 1000) + (SERIAL_4WAY_VER_SUB_1 * 100) + SERIAL_4WAY_VER_SUB_2)
92 #define SERIAL_4WAY_VERSION_HI (uint8_t) (SERIAL_4WAY_VERSION / 100)
93 #define SERIAL_4WAY_VERSION_LO (uint8_t) (SERIAL_4WAY_VERSION % 100)
95 #define CMD_TIMEOUT_US 50000
96 #define ARG_TIMEOUT_US 25000
97 #define DAT_TIMEOUT_US 10000
98 #define CRC_TIMEOUT_US 10000
100 static uint8_t escCount
;
102 escHardware_t escHardware
[MAX_SUPPORTED_MOTORS
];
104 uint8_t selected_esc
;
106 uint8_32_u DeviceInfo
;
108 #define DeviceInfoSize 4
110 inline bool isMcuConnected(void)
112 return (DeviceInfo
.bytes
[0] > 0);
115 inline bool isEscHi(uint8_t selEsc
)
117 return (IORead(escHardware
[selEsc
].io
) != Bit_RESET
);
119 inline bool isEscLo(uint8_t selEsc
)
121 return (IORead(escHardware
[selEsc
].io
) == Bit_RESET
);
124 inline void setEscHi(uint8_t selEsc
)
126 IOHi(escHardware
[selEsc
].io
);
129 inline void setEscLo(uint8_t selEsc
)
131 IOLo(escHardware
[selEsc
].io
);
134 inline void setEscInput(uint8_t selEsc
)
136 IOConfigGPIO(escHardware
[selEsc
].io
, IOCFG_IPU
);
139 inline void setEscOutput(uint8_t selEsc
)
141 IOConfigGPIO(escHardware
[selEsc
].io
, IOCFG_OUT_PP
);
144 uint8_t esc4wayInit(void)
146 // StopPwmAllMotors();
147 // XXX Review effect of motor refactor
148 //pwmDisableMotors();
150 memset(&escHardware
, 0, sizeof(escHardware
));
151 pwmOutputPort_t
*pwmMotors
= pwmGetMotors();
152 for (volatile uint8_t i
= 0; i
< MAX_SUPPORTED_MOTORS
; i
++) {
153 if (pwmMotors
[i
].enabled
) {
154 if (pwmMotors
[i
].io
!= IO_NONE
) {
155 escHardware
[escCount
].io
= pwmMotors
[i
].io
;
156 setEscInput(escCount
);
166 void esc4wayRelease(void)
168 while (escCount
> 0) {
170 IOConfigGPIO(escHardware
[escCount
].io
, IOCFG_AF_PP
);
177 #define SET_DISCONNECTED DeviceInfo.words[0] = 0
179 #define INTF_MODE_IDX 3 // index for DeviceInfostate
181 // Interface related only
182 // establish and test connection to the Interface
185 // ESC + CMD PARAM_LEN [PARAM (if len > 0)] CRC16_Hi CRC16_Lo
187 // ESC CMD PARAM_LEN [PARAM (if len > 0)] + ACK (uint8_t OK or ERR) + CRC16_Hi CRC16_Lo
189 #define cmd_Remote_Escape 0x2E // '.'
190 #define cmd_Local_Escape 0x2F // '/'
192 // Test Interface still present
193 #define cmd_InterfaceTestAlive 0x30 // '0' alive
196 // get Protocol Version Number 01..255
197 #define cmd_ProtocolGetVersion 0x31 // '1' version
198 // RETURN: uint8_t VersionNumber + ACK
200 // get Version String
201 #define cmd_InterfaceGetName 0x32 // '2' name
202 // RETURN: String + ACK
204 //get Version Number 01..255
205 #define cmd_InterfaceGetVersion 0x33 // '3' version
206 // RETURN: uint8_t AVersionNumber + ACK
209 // Exit / Restart Interface - can be used to switch to Box Mode
210 #define cmd_InterfaceExit 0x34 // '4' exit
213 // Reset the Device connected to the Interface
214 #define cmd_DeviceReset 0x35 // '5' reset
217 // Get the Device ID connected
218 // #define cmd_DeviceGetID 0x36 //'6' device id removed since 06/106
219 // RETURN: uint8_t DeviceID + ACK
221 // Initialize Flash Access for Device connected
222 #define cmd_DeviceInitFlash 0x37 // '7' init flash access
225 // Erase the whole Device Memory of connected Device
226 #define cmd_DeviceEraseAll 0x38 // '8' erase all
229 // Erase one Page of Device Memory of connected Device
230 #define cmd_DevicePageErase 0x39 // '9' page erase
231 // PARAM: uint8_t APageNumber
234 // Read to Buffer from Device Memory of connected Device // Buffer Len is Max 256 Bytes
235 // BuffLen = 0 means 256 Bytes
236 #define cmd_DeviceRead 0x3A // ':' read Device
237 // PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BuffLen[0..255]
238 // RETURN: PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BUffLen + Buffer[0..255] ACK
240 // Write to Buffer for Device Memory of connected Device // Buffer Len is Max 256 Bytes
241 // BuffLen = 0 means 256 Bytes
242 #define cmd_DeviceWrite 0x3B // ';' write
243 // PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BUffLen + Buffer[0..255]
246 // Set C2CK low infinite ) permanent Reset state
247 #define cmd_DeviceC2CK_LOW 0x3C // '<'
250 // Read to Buffer from Device Memory of connected Device //Buffer Len is Max 256 Bytes
251 // BuffLen = 0 means 256 Bytes
252 #define cmd_DeviceReadEEprom 0x3D // '=' read Device
253 // PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BuffLen[0..255]
254 // RETURN: PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BUffLen + Buffer[0..255] ACK
256 // Write to Buffer for Device Memory of connected Device // Buffer Len is Max 256 Bytes
257 // BuffLen = 0 means 256 Bytes
258 #define cmd_DeviceWriteEEprom 0x3E // '>' write
259 // PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BUffLen + Buffer[0..255]
262 // Set Interface Mode
263 #define cmd_InterfaceSetMode 0x3F // '?'
265 // #define imSIL_BLB 1
266 // #define imATM_BLB 2
268 // PARAM: uint8_t Mode
269 // RETURN: ACK or ACK_I_INVALID_CHANNEL
271 //Write to Buffer for Verify Device Memory of connected Device //Buffer Len is Max 256 Bytes
272 //BuffLen = 0 means 256 Bytes
273 #define cmd_DeviceVerify 0x40 //'@' write
274 //PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BUffLen + Buffer[0..255]
280 // #define ACK_I_UNKNOWN_ERROR 0x01
281 #define ACK_I_INVALID_CMD 0x02
282 #define ACK_I_INVALID_CRC 0x03
283 #define ACK_I_VERIFY_ERROR 0x04
284 // #define ACK_D_INVALID_COMMAND 0x05
285 // #define ACK_D_COMMAND_FAILED 0x06
286 // #define ACK_D_UNKNOWN_ERROR 0x07
288 #define ACK_I_INVALID_CHANNEL 0x08
289 #define ACK_I_INVALID_PARAM 0x09
290 #define ACK_D_GENERAL_ERROR 0x0F
292 /* Copyright (c) 2002, 2003, 2004 Marek Michalkiewicz
293 Copyright (c) 2005, 2007 Joerg Wunsch
294 Copyright (c) 2013 Dave Hylands
295 Copyright (c) 2013 Frederic Nadeau
298 Redistribution and use in source and binary forms, with or without
299 modification, are permitted provided that the following conditions are met:
301 * Redistributions of source code must retain the above copyright
302 notice, this list of conditions and the following disclaimer.
304 * Redistributions in binary form must reproduce the above copyright
305 notice, this list of conditions and the following disclaimer in
306 the documentation and/or other materials provided with the
309 * Neither the name of the copyright holders nor the names of
310 contributors may be used to endorse or promote products derived
311 from this software without specific prior written permission.
313 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
314 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
315 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
316 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
317 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
318 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
319 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
320 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
321 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
322 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
323 POSSIBILITY OF SUCH DAMAGE. */
324 uint16_t _crc_xmodem_update (uint16_t crc
, uint8_t data
)
328 crc
= crc
^ ((uint16_t)data
<< 8);
329 for (i
=0; i
< 8; i
++) {
331 crc
= (crc
<< 1) ^ 0x1021;
340 #define ATMEL_DEVICE_MATCH ((pDeviceInfo->words[0] == 0x9307) || (pDeviceInfo->words[0] == 0x930A) || \
341 (pDeviceInfo->words[0] == 0x930F) || (pDeviceInfo->words[0] == 0x940B))
343 #define SILABS_DEVICE_MATCH ((pDeviceInfo->words[0] > 0xE800) && (pDeviceInfo->words[0] < 0xF900))
346 // BLHeli_32 MCU ID hi > 0x00 and < 0x90 / lo always = 0x06
347 #define ARM_DEVICE_MATCH ((pDeviceInfo->bytes[1] > 0x00) && (pDeviceInfo->bytes[1] < 0x90) && (pDeviceInfo->bytes[0] == 0x06))
349 static uint8_t CurrentInterfaceMode
;
351 static uint8_t Connect(uint8_32_u
*pDeviceInfo
)
353 for (uint8_t I
= 0; I
< 3; ++I
) {
354 #if (defined(USE_SERIAL_4WAY_BLHELI_BOOTLOADER) && defined(USE_SERIAL_4WAY_SK_BOOTLOADER))
355 if ((CurrentInterfaceMode
!= imARM_BLB
) && Stk_ConnectEx(pDeviceInfo
) && ATMEL_DEVICE_MATCH
) {
356 CurrentInterfaceMode
= imSK
;
359 if (BL_ConnectEx(pDeviceInfo
)) {
360 if SILABS_DEVICE_MATCH
{
361 CurrentInterfaceMode
= imSIL_BLB
;
363 } else if ATMEL_DEVICE_MATCH
{
364 CurrentInterfaceMode
= imATM_BLB
;
366 } else if ARM_DEVICE_MATCH
{
367 CurrentInterfaceMode
= imARM_BLB
;
372 #elif defined(USE_SERIAL_4WAY_BLHELI_BOOTLOADER)
373 if (BL_ConnectEx(pDeviceInfo
)) {
374 if SILABS_DEVICE_MATCH
{
375 CurrentInterfaceMode
= imSIL_BLB
;
377 } else if ATMEL_DEVICE_MATCH
{
378 CurrentInterfaceMode
= imATM_BLB
;
380 } else if ARM_DEVICE_MATCH
{
381 CurrentInterfaceMode
= imARM_BLB
;
385 #elif defined(USE_SERIAL_4WAY_SK_BOOTLOADER)
386 if (Stk_ConnectEx(pDeviceInfo
)) {
387 CurrentInterfaceMode
= imSK
;
388 if ATMEL_DEVICE_MATCH
return 1;
395 static serialPort_t
*port
;
397 static bool ReadByte(uint8_t *data
, timeDelta_t timeoutUs
)
399 #ifdef USE_TIMEOUT_4WAYIF
400 timeUs_t startTime
= micros();
401 while (!serialRxBytesWaiting(port
)) {
402 if (timeoutUs
&& (cmpTimeUs(micros(), startTime
) > timeoutUs
)) {
410 while (!serialRxBytesWaiting(port
));
413 *data
= serialRead(port
);
418 static uint8_16_u CRC_in
;
419 static bool ReadByteCrc(uint8_t *data
, timeDelta_t timeoutUs
)
421 bool timedOut
= ReadByte(data
, timeoutUs
);
424 CRC_in
.word
= _crc_xmodem_update(CRC_in
.word
, *data
);
430 static void WriteByte(uint8_t b
)
432 serialWrite(port
, b
);
435 static uint8_16_u CRCout
;
436 static void WriteByteCrc(uint8_t b
)
439 CRCout
.word
= _crc_xmodem_update(CRCout
.word
, b
);
442 void esc4wayProcess(serialPort_t
*mspPort
)
444 uint8_t ParamBuf
[256];
449 uint8_16_u CRC_check
;
458 // Start here with UART Main loop
460 // fix for buzzer often starts beeping continuously when the ESCs are read
461 // switch beeper silent here
464 bool isExitScheduled
= false;
467 bool timedOut
= false;
469 // restart looking for new sequence from host
472 // No timeout as BLHeliSuite32 has this loops sitting indefinitely waiting for input
473 ReadByteCrc(&ESC
, 0);
474 } while (ESC
!= cmd_Local_Escape
);
479 O_PARAM
= &Dummy
.bytes
[0];
482 timedOut
= ReadByteCrc(&CMD
, CMD_TIMEOUT_US
) ||
483 ReadByteCrc(&ioMem
.D_FLASH_ADDR_H
, ARG_TIMEOUT_US
) ||
484 ReadByteCrc(&ioMem
.D_FLASH_ADDR_L
, ARG_TIMEOUT_US
) ||
485 ReadByteCrc(&I_PARAM_LEN
, ARG_TIMEOUT_US
);
488 uint8_t i
= I_PARAM_LEN
;
492 timedOut
= ReadByteCrc(InBuff
++, DAT_TIMEOUT_US
);
493 } while ((--i
> 0) && !timedOut
);
495 for (int8_t i
= 1; (i
>= 0) && !timedOut
; i
--) {
496 timedOut
= ReadByte(&CRC_check
.bytes
[i
], CRC_TIMEOUT_US
);
500 if ((CRC_check
.word
== CRC_in
.word
) && !timedOut
) {
503 ACK_OUT
= ACK_I_INVALID_CRC
;
508 if (ACK_OUT
== ACK_OK
)
510 // wtf.D_FLASH_ADDR_H=Adress_H;
511 // wtf.D_FLASH_ADDR_L=Adress_L;
512 ioMem
.D_PTR_I
= ParamBuf
;
516 // ******* Interface related stuff *******
517 case cmd_InterfaceTestAlive
:
519 if (isMcuConnected()) {
520 switch (CurrentInterfaceMode
)
522 #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
527 if (!BL_SendCMDKeepAlive()) { // SetStateDisconnected() included
528 ACK_OUT
= ACK_D_GENERAL_ERROR
;
533 #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
536 if (!Stk_SignOn()) { // SetStateDisconnected();
537 ACK_OUT
= ACK_D_GENERAL_ERROR
;
543 ACK_OUT
= ACK_D_GENERAL_ERROR
;
545 if ( ACK_OUT
!= ACK_OK
) SET_DISCONNECTED
;
549 case cmd_ProtocolGetVersion
:
551 // Only interface itself, no matter what Device
552 Dummy
.bytes
[0] = SERIAL_4WAY_PROTOCOL_VER
;
556 case cmd_InterfaceGetName
:
558 // Only interface itself, no matter what Device
560 O_PARAM_LEN
= strlen(SERIAL_4WAY_INTERFACE_NAME_STR
);
561 O_PARAM
= (uint8_t *)SERIAL_4WAY_INTERFACE_NAME_STR
;
565 case cmd_InterfaceGetVersion
:
567 // Only interface itself, no matter what Device
568 // Dummy = iUart_res_InterfVersion;
570 Dummy
.bytes
[0] = SERIAL_4WAY_VERSION_HI
;
571 Dummy
.bytes
[1] = SERIAL_4WAY_VERSION_LO
;
574 case cmd_InterfaceExit
:
576 isExitScheduled
= true;
579 case cmd_InterfaceSetMode
:
581 #if defined(USE_SERIAL_4WAY_BLHELI_BOOTLOADER) && defined(USE_SERIAL_4WAY_SK_BOOTLOADER)
582 if ((ParamBuf
[0] <= imARM_BLB
) && (ParamBuf
[0] >= imSIL_BLB
)) {
583 #elif defined(USE_SERIAL_4WAY_BLHELI_BOOTLOADER)
584 if (((ParamBuf
[0] <= imATM_BLB
)||(ParamBuf
[0] == imARM_BLB
)) && (ParamBuf
[0] >= imSIL_BLB
)) {
585 #elif defined(USE_SERIAL_4WAY_SK_BOOTLOADER)
586 if (ParamBuf
[0] == imSK
) {
588 CurrentInterfaceMode
= ParamBuf
[0];
590 ACK_OUT
= ACK_I_INVALID_PARAM
;
595 case cmd_DeviceReset
:
597 bool rebootEsc
= false;
598 if (ParamBuf
[0] < escCount
) {
599 // Channel may change here
600 selected_esc
= ParamBuf
[0];
601 if (ioMem
.D_FLASH_ADDR_L
== 1) {
606 ACK_OUT
= ACK_I_INVALID_CHANNEL
;
609 switch (CurrentInterfaceMode
)
612 #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
616 BL_SendCMDRunRestartBootloader(&DeviceInfo
);
619 setEscLo(selected_esc
);
620 timeMs_t m
= millis();
621 while (millis() - m
< 300);
622 setEscHi(selected_esc
);
628 #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
638 case cmd_DeviceInitFlash
:
641 if (ParamBuf
[0] < escCount
) {
642 //Channel may change here
643 //ESC_LO or ESC_HI; Halt state for prev channel
644 selected_esc
= ParamBuf
[0];
646 ACK_OUT
= ACK_I_INVALID_CHANNEL
;
649 O_PARAM_LEN
= DeviceInfoSize
; //4
650 O_PARAM
= (uint8_t *)&DeviceInfo
;
651 if (Connect(&DeviceInfo
)) {
652 DeviceInfo
.bytes
[INTF_MODE_IDX
] = CurrentInterfaceMode
;
655 ACK_OUT
= ACK_D_GENERAL_ERROR
;
660 #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
661 case cmd_DeviceEraseAll
:
663 switch (CurrentInterfaceMode
)
667 if (!Stk_Chip_Erase()) ACK_OUT
=ACK_D_GENERAL_ERROR
;
671 ACK_OUT
= ACK_I_INVALID_CMD
;
677 #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
678 case cmd_DevicePageErase
:
680 switch (CurrentInterfaceMode
)
685 Dummy
.bytes
[0] = ParamBuf
[0];
686 if (CurrentInterfaceMode
== imARM_BLB
) {
687 // Address =Page * 1024
688 ioMem
.D_FLASH_ADDR_H
= (Dummy
.bytes
[0] << 2);
690 // Address =Page * 512
691 ioMem
.D_FLASH_ADDR_H
= (Dummy
.bytes
[0] << 1);
693 ioMem
.D_FLASH_ADDR_L
= 0;
694 if (!BL_PageErase(&ioMem
)) ACK_OUT
= ACK_D_GENERAL_ERROR
;
698 ACK_OUT
= ACK_I_INVALID_CMD
;
704 //*** Device Memory Read Ops ***
707 ioMem
.D_NUM_BYTES
= ParamBuf
[0];
709 wtf.D_FLASH_ADDR_H=Adress_H;
710 wtf.D_FLASH_ADDR_L=Adress_L;
713 switch (CurrentInterfaceMode
)
715 #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
720 if (!BL_ReadFlash(CurrentInterfaceMode
, &ioMem
))
722 ACK_OUT
= ACK_D_GENERAL_ERROR
;
727 #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
730 if (!Stk_ReadFlash(&ioMem
))
732 ACK_OUT
= ACK_D_GENERAL_ERROR
;
738 ACK_OUT
= ACK_I_INVALID_CMD
;
740 if (ACK_OUT
== ACK_OK
)
742 O_PARAM_LEN
= ioMem
.D_NUM_BYTES
;
743 O_PARAM
= (uint8_t *)&ParamBuf
;
748 case cmd_DeviceReadEEprom
:
750 ioMem
.D_NUM_BYTES
= ParamBuf
[0];
752 wtf.D_FLASH_ADDR_H = Adress_H;
753 wtf.D_FLASH_ADDR_L = Adress_L;
756 switch (CurrentInterfaceMode
)
758 #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
761 if (!BL_ReadEEprom(&ioMem
))
763 ACK_OUT
= ACK_D_GENERAL_ERROR
;
768 #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
771 if (!Stk_ReadEEprom(&ioMem
))
773 ACK_OUT
= ACK_D_GENERAL_ERROR
;
779 ACK_OUT
= ACK_I_INVALID_CMD
;
781 if (ACK_OUT
== ACK_OK
)
783 O_PARAM_LEN
= ioMem
.D_NUM_BYTES
;
784 O_PARAM
= (uint8_t *)&ParamBuf
;
789 //*** Device Memory Write Ops ***
790 case cmd_DeviceWrite
:
792 ioMem
.D_NUM_BYTES
= I_PARAM_LEN
;
794 wtf.D_FLASH_ADDR_H=Adress_H;
795 wtf.D_FLASH_ADDR_L=Adress_L;
798 switch (CurrentInterfaceMode
)
800 #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
805 if (!BL_WriteFlash(&ioMem
)) {
806 ACK_OUT
= ACK_D_GENERAL_ERROR
;
811 #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
814 if (!Stk_WriteFlash(&ioMem
))
816 ACK_OUT
= ACK_D_GENERAL_ERROR
;
825 case cmd_DeviceWriteEEprom
:
827 ioMem
.D_NUM_BYTES
= I_PARAM_LEN
;
828 ACK_OUT
= ACK_D_GENERAL_ERROR
;
830 wtf.D_FLASH_ADDR_H=Adress_H;
831 wtf.D_FLASH_ADDR_L=Adress_L;
834 switch (CurrentInterfaceMode
)
836 #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
839 ACK_OUT
= ACK_I_INVALID_CMD
;
844 if (BL_WriteEEprom(&ioMem
))
851 #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
854 if (Stk_WriteEEprom(&ioMem
))
864 //*** Device Memory Verify Ops ***
865 #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
866 case cmd_DeviceVerify
:
868 switch (CurrentInterfaceMode
)
872 ioMem
.D_NUM_BYTES
= I_PARAM_LEN
;
874 wtf.D_FLASH_ADDR_H=Adress_H;
875 wtf.D_FLASH_ADDR_L=Adress_L;
879 ACK_OUT
= BL_VerifyFlash(&ioMem
);
885 ACK_OUT
= ACK_I_VERIFY_ERROR
;
888 ACK_OUT
= ACK_D_GENERAL_ERROR
;
895 ACK_OUT
= ACK_I_INVALID_CMD
;
904 ACK_OUT
= ACK_I_INVALID_CMD
;
913 serialBeginWrite(port
);
914 WriteByteCrc(cmd_Remote_Escape
);
916 WriteByteCrc(ioMem
.D_FLASH_ADDR_H
);
917 WriteByteCrc(ioMem
.D_FLASH_ADDR_L
);
918 WriteByteCrc(O_PARAM_LEN
);
920 uint8_t i
= O_PARAM_LEN
;
922 while (!serialTxBytesFree(port
));
924 WriteByteCrc(*O_PARAM
);
929 WriteByteCrc(ACK_OUT
);
930 WriteByte(CRCout
.bytes
[1]);
931 WriteByte(CRCout
.bytes
[0]);
932 serialEndWrite(port
);
936 if (isExitScheduled
) {