APM:Libraries
serial_4way.cpp
Go to the documentation of this file.
1 /*
2 (c) 2017 night_ghost@ykoctpa.ru
3 
4 based on:
5 
6  * Cleanflight 4way driver
7 */
8 
9 #include <AP_HAL/AP_HAL.h>
10 
11 #ifdef USE_SERIAL_4WAY_BLHELI_INTERFACE
12 
13 #include <stdbool.h>
14 #include <stdint.h>
15 #include <string.h>
16 
17 
18 
19 #include "serial_4way.h"
20 
21 #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
23 #endif
24 
25 #if defined(USE_SERIAL_4WAY_SK_BOOTLOADER)
26 #include "serial_4way_stk500v2.h"
27 #endif
28 
29 //#define USE_TXRX_LED
30 
31 #ifdef USE_TXRX_LED
32 #define RX_LED_OFF LED0_OFF
33 #define RX_LED_ON LED0_ON
34 #ifdef LED1
35 #define TX_LED_OFF LED1_OFF
36 #define TX_LED_ON LED1_ON
37 #else
38 #define TX_LED_OFF LED0_OFF
39 #define TX_LED_ON LED0_ON
40 #endif
41 #else
42 #define RX_LED_OFF
43 #define RX_LED_ON
44 #define TX_LED_OFF
45 #define TX_LED_ON
46 #endif
47 
48 #define SERIAL_4WAY_INTERFACE_NAME_STR "m4wFCIntf"
49 // *** change to adapt Revision
50 #define SERIAL_4WAY_VER_MAIN 20
51 #define SERIAL_4WAY_VER_SUB_1 (uint8_t) 0
52 #define SERIAL_4WAY_VER_SUB_2 (uint8_t) 02
53 
54 #define SERIAL_4WAY_PROTOCOL_VER 107
55 // *** end
56 
57 #if (SERIAL_4WAY_VER_MAIN > 24)
58 #error "beware of SERIAL_4WAY_VER_SUB_1 is uint8_t"
59 #endif
60 
61 #define SERIAL_4WAY_VERSION (uint16_t) ((SERIAL_4WAY_VER_MAIN * 1000) + (SERIAL_4WAY_VER_SUB_1 * 100) + SERIAL_4WAY_VER_SUB_2)
62 
63 #define SERIAL_4WAY_VERSION_HI (uint8_t) (SERIAL_4WAY_VERSION / 100)
64 #define SERIAL_4WAY_VERSION_LO (uint8_t) (SERIAL_4WAY_VERSION % 100)
65 
66 static uint8_t escCount;
67 
68 static escHardware_t escHardware[MAX_SUPPORTED_MOTORS];
69 
70 uint8_t selected_esc;
71 
72 uint8_32_u DeviceInfo;
73 #define DeviceInfoSize 4
74 
75 
76 bool isMcuConnected(void){
77  return (DeviceInfo.bytes[0] > 0);
78 }
79 
80 bool isEscHi(uint8_t selEsc)
81 {
82  escHardware_t &pp = escHardware[selEsc];
83  return gpio_read_bit(pp.gpio_device, pp.gpio_bit) != 0;
84 
85 }
86 bool isEscLo(uint8_t selEsc)
87 {
88  escHardware_t &pp = escHardware[selEsc];
89  return gpio_read_bit(pp.gpio_device, pp.gpio_bit) == 0;
90 }
91 
92 void setEscHi(uint8_t selEsc)
93 {
94  escHardware_t &pp = escHardware[selEsc];
96 }
97 
98 void setEscLo(uint8_t selEsc)
99 {
100  escHardware_t &pp = escHardware[selEsc];
102 
103 }
104 
105 void setEscInput(uint8_t selEsc)
106 {
107  escHardware_t &pp = escHardware[selEsc];
109 }
110 
111 void setEscOutput(uint8_t selEsc)
112 {
113  escHardware_t &pp = escHardware[selEsc];
115 }
116 
117 uint8_t esc4wayInit(const uint8_t *output_channels, uint8_t nm)
118 {
119  escCount = 0;
120  memset(&escHardware, 0, sizeof(escHardware));
121  for (volatile uint8_t i = 0; i < nm; i++) {
122  uint8_t pin = output_channels[i];
123  const stm32_pin_info &pp = PIN_MAP[pin];
124 
125  escHardware[escCount].gpio_device = pp.gpio_device;
126  escHardware[escCount].gpio_bit = pp.gpio_bit;
127 
128  setEscInput(escCount);
129  setEscHi(escCount);
130  escCount++;
131  }
132  return escCount;
133 }
134 
135 
136 void esc4wayRelease(void)
137 {
138  while (escCount > 0) {
139  escCount--;
140 
141 // F4LightRCOutput::_set_pin_output_mode(escCount); let just reboot
142  }
143 }
144 
145 #define SET_DISCONNECTED DeviceInfo.words[0] = 0
146 
147 #define INTF_MODE_IDX 3 // index for DeviceInfostate
148 
149 // Interface related only
150 // establish and test connection to the Interface
151 
152 // Send Structure
153 // ESC + CMD PARAM_LEN [PARAM (if len > 0)] CRC16_Hi CRC16_Lo
154 // Return
155 // ESC CMD PARAM_LEN [PARAM (if len > 0)] + ACK (uint8_t OK or ERR) + CRC16_Hi CRC16_Lo
156 
157 #define cmd_Remote_Escape 0x2E // '.'
158 #define cmd_Local_Escape 0x2F // '/'
159 
160 // Test Interface still present
161 #define cmd_InterfaceTestAlive 0x30 // '0' alive
162 // RETURN: ACK
163 
164 // get Protocol Version Number 01..255
165 #define cmd_ProtocolGetVersion 0x31 // '1' version
166 // RETURN: uint8_t VersionNumber + ACK
167 
168 // get Version String
169 #define cmd_InterfaceGetName 0x32 // '2' name
170 // RETURN: String + ACK
171 
172 //get Version Number 01..255
173 #define cmd_InterfaceGetVersion 0x33 // '3' version
174 // RETURN: uint8_t AVersionNumber + ACK
175 
176 
177 // Exit / Restart Interface - can be used to switch to Box Mode
178 #define cmd_InterfaceExit 0x34 // '4' exit
179 // RETURN: ACK
180 
181 // Reset the Device connected to the Interface
182 #define cmd_DeviceReset 0x35 // '5' reset
183 // RETURN: ACK
184 
185 // Get the Device ID connected
186 // #define cmd_DeviceGetID 0x36 //'6' device id removed since 06/106
187 // RETURN: uint8_t DeviceID + ACK
188 
189 // Initialize Flash Access for Device connected
190 #define cmd_DeviceInitFlash 0x37 // '7' init flash access
191 // RETURN: ACK
192 
193 // Erase the whole Device Memory of connected Device
194 #define cmd_DeviceEraseAll 0x38 // '8' erase all
195 // RETURN: ACK
196 
197 // Erase one Page of Device Memory of connected Device
198 #define cmd_DevicePageErase 0x39 // '9' page erase
199 // PARAM: uint8_t APageNumber
200 // RETURN: ACK
201 
202 // Read to Buffer from Device Memory of connected Device // Buffer Len is Max 256 Bytes
203 // BuffLen = 0 means 256 Bytes
204 #define cmd_DeviceRead 0x3A // ':' read Device
205 // PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BuffLen[0..255]
206 // RETURN: PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BUffLen + Buffer[0..255] ACK
207 
208 // Write to Buffer for Device Memory of connected Device // Buffer Len is Max 256 Bytes
209 // BuffLen = 0 means 256 Bytes
210 #define cmd_DeviceWrite 0x3B // ';' write
211 // PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BUffLen + Buffer[0..255]
212 // RETURN: ACK
213 
214 // Set C2CK low infinite ) permanent Reset state
215 #define cmd_DeviceC2CK_LOW 0x3C // '<'
216 // RETURN: ACK
217 
218 // Read to Buffer from Device Memory of connected Device //Buffer Len is Max 256 Bytes
219 // BuffLen = 0 means 256 Bytes
220 #define cmd_DeviceReadEEprom 0x3D // '=' read Device
221 // PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BuffLen[0..255]
222 // RETURN: PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BUffLen + Buffer[0..255] ACK
223 
224 // Write to Buffer for Device Memory of connected Device // Buffer Len is Max 256 Bytes
225 // BuffLen = 0 means 256 Bytes
226 #define cmd_DeviceWriteEEprom 0x3E // '>' write
227 // PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BUffLen + Buffer[0..255]
228 // RETURN: ACK
229 
230 // Set Interface Mode
231 #define cmd_InterfaceSetMode 0x3F // '?'
232 // #define imC2 0
233 // #define imSIL_BLB 1
234 // #define imATM_BLB 2
235 // #define imSK 3
236 // PARAM: uint8_t Mode
237 // RETURN: ACK or ACK_I_INVALID_CHANNEL
238 
239 //Write to Buffer for Verify Device Memory of connected Device //Buffer Len is Max 256 Bytes
240 //BuffLen = 0 means 256 Bytes
241 #define cmd_DeviceVerify 0x40 //'@' write
242 //PARAM: uint8_t ADRESS_Hi + ADRESS_Lo + BUffLen + Buffer[0..255]
243 //RETURN: ACK
244 
245 // responses
246 #define ACK_OK 0x00
247 // #define ACK_I_UNKNOWN_ERROR 0x01
248 #define ACK_I_INVALID_CMD 0x02
249 #define ACK_I_INVALID_CRC 0x03
250 #define ACK_I_VERIFY_ERROR 0x04
251 // #define ACK_D_INVALID_COMMAND 0x05
252 // #define ACK_D_COMMAND_FAILED 0x06
253 // #define ACK_D_UNKNOWN_ERROR 0x07
254 
255 #define ACK_I_INVALID_CHANNEL 0x08
256 #define ACK_I_INVALID_PARAM 0x09
257 #define ACK_D_GENERAL_ERROR 0x0F
258 
259 /* Copyright (c) 2002, 2003, 2004 Marek Michalkiewicz
260  Copyright (c) 2005, 2007 Joerg Wunsch
261  Copyright (c) 2013 Dave Hylands
262  Copyright (c) 2013 Frederic Nadeau
263  All rights reserved.
264 
265  Redistribution and use in source and binary forms, with or without
266  modification, are permitted provided that the following conditions are met:
267 
268  * Redistributions of source code must retain the above copyright
269  notice, this list of conditions and the following disclaimer.
270 
271  * Redistributions in binary form must reproduce the above copyright
272  notice, this list of conditions and the following disclaimer in
273  the documentation and/or other materials provided with the
274  distribution.
275 
276  * Neither the name of the copyright holders nor the names of
277  contributors may be used to endorse or promote products derived
278  from this software without specific prior written permission.
279 
280  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
281  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
282  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
283  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
284  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
285  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
286  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
287  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
288  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
289  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
290  POSSIBILITY OF SUCH DAMAGE. */
291 uint16_t _crc_xmodem_update (uint16_t crc, uint8_t data) {
292  int i;
293 
294  crc = crc ^ ((uint16_t)data << 8);
295  for (i=0; i < 8; i++){
296  if (crc & 0x8000)
297  crc = (crc << 1) ^ 0x1021;
298  else
299  crc <<= 1;
300  }
301  return crc;
302 }
303 // * End copyright
304 
305 
306 #define ATMEL_DEVICE_MATCH ((pDeviceInfo->words[0] == 0x9307) || (pDeviceInfo->words[0] == 0x930A) || \
307  (pDeviceInfo->words[0] == 0x930F) || (pDeviceInfo->words[0] == 0x940B))
308 
309 #define SILABS_DEVICE_MATCH ((pDeviceInfo->words[0] == 0xF310)||(pDeviceInfo->words[0] ==0xF330) || \
310  (pDeviceInfo->words[0] == 0xF410) || (pDeviceInfo->words[0] == 0xF390) || \
311  (pDeviceInfo->words[0] == 0xF850) || (pDeviceInfo->words[0] == 0xE8B1) || \
312  (pDeviceInfo->words[0] == 0xE8B2))
313 
314 #define ARM_DEVICE_MATCH ((pDeviceInfo->words[0] == 0x1F06) || \
315  (pDeviceInfo->words[0] == 0x3306) || (pDeviceInfo->words[0] == 0x3406) || (pDeviceInfo->words[0] == 0x3506))
316 
317 static uint8_t CurrentInterfaceMode;
318 
319 static uint8_t Connect(uint8_32_u *pDeviceInfo)
320 {
321  for (uint8_t I = 0; I < 3; ++I) {
322  #if (defined(USE_SERIAL_4WAY_BLHELI_BOOTLOADER) && defined(USE_SERIAL_4WAY_SK_BOOTLOADER))
323  if ((CurrentInterfaceMode != imARM_BLB) && Stk_ConnectEx(pDeviceInfo) && ATMEL_DEVICE_MATCH) {
324  CurrentInterfaceMode = imSK;
325  return 1;
326  } else {
327  if (BL_ConnectEx(pDeviceInfo)) {
328  if SILABS_DEVICE_MATCH {
329  CurrentInterfaceMode = imSIL_BLB;
330  return 1;
331  } else if ATMEL_DEVICE_MATCH {
332  CurrentInterfaceMode = imATM_BLB;
333  return 1;
334  } else if ARM_DEVICE_MATCH {
335  CurrentInterfaceMode = imARM_BLB;
336  return 1;
337  }
338  }
339  }
340  #elif defined(USE_SERIAL_4WAY_BLHELI_BOOTLOADER)
341  if (BL_ConnectEx(pDeviceInfo)) {
342  if SILABS_DEVICE_MATCH {
343  CurrentInterfaceMode = imSIL_BLB;
344  return 1;
345  } else if ATMEL_DEVICE_MATCH {
346  CurrentInterfaceMode = imATM_BLB;
347  return 1;
348  } else if ARM_DEVICE_MATCH {
349  CurrentInterfaceMode = imARM_BLB;
350  return 1;
351  }
352  }
353  #elif defined(USE_SERIAL_4WAY_SK_BOOTLOADER)
354  if (Stk_ConnectEx(pDeviceInfo)) {
355  CurrentInterfaceMode = imSK;
356  if ATMEL_DEVICE_MATCH return 1;
357  }
358  #endif
359  }
360  return 0;
361 }
362 
363 static AP_HAL::UARTDriver *uart;
364 
365 static uint8_t ReadByte(void)
366 {
367  // need timeout?
368  while (!uart->available());
369  return uart->read();
370 }
371 
372 static uint8_16_u CRC_in;
373 static uint8_16_u CRCout;
374 
375 static uint8_t ReadByteCrc(void)
376 {
377  uint8_t b = ReadByte();
378  CRC_in.word = _crc_xmodem_update(CRC_in.word, b);
379  return b;
380 }
381 
382 static void WriteByte(uint8_t b)
383 {
384  uart->write(b);
385 }
386 
387 static void WriteByteCrc(uint8_t b)
388 {
389  WriteByte(b);
390  CRCout.word = _crc_xmodem_update(CRCout.word, b);
391 }
392 
393 static bool UartTxPending() {
394  return uart->tx_pending();
395 }
396 
397 void esc4wayProcess(AP_HAL::UARTDriver *uartPort)
398 {
399 
400  uint8_t ParamBuf[256];
401  uint8_t ESC;
402  uint8_t I_PARAM_LEN;
403  uint8_t CMD;
404  uint8_t ACK_OUT;
405  uint8_16_u CRC_check;
406  uint8_16_u Dummy;
407  uint8_t O_PARAM_LEN;
408  uint8_t *O_PARAM;
409  uint8_t *InBuff;
410  ioMem_t ioMem;
411 
412  uart = uartPort;
413 
414  // Start here with UART Main loop
415  bool isExitScheduled = false;
416 
417  while(1) {
418  // restart looking for new sequence from host
419  do {
420  CRC_in.word = 0;
421  ESC = ReadByteCrc();
422  } while (ESC != cmd_Local_Escape);
423 
424  RX_LED_ON;
425 
426  Dummy.word = 0;
427  O_PARAM = &Dummy.bytes[0];
428  O_PARAM_LEN = 1;
429  CMD = ReadByteCrc();
430  ioMem.D_FLASH_ADDR_H = ReadByteCrc();
431  ioMem.D_FLASH_ADDR_L = ReadByteCrc();
432  I_PARAM_LEN = ReadByteCrc();
433 
434  InBuff = ParamBuf;
435  uint8_t i = I_PARAM_LEN;
436  do {
437  *InBuff = ReadByteCrc();
438  InBuff++;
439  i--;
440  } while (i != 0);
441 
442  CRC_check.bytes[1] = ReadByte();
443  CRC_check.bytes[0] = ReadByte();
444 
445  if(CRC_check.word == CRC_in.word) {
446  ACK_OUT = ACK_OK;
447  } else {
448  ACK_OUT = ACK_I_INVALID_CRC;
449  }
450 
451  TX_LED_ON;
452 
453  if (ACK_OUT == ACK_OK) {
454  // wtf.D_FLASH_ADDR_H=Adress_H;
455  // wtf.D_FLASH_ADDR_L=Adress_L;
456  ioMem.D_PTR_I = ParamBuf;
457 
458 
459  switch(CMD) {
460  // ******* Interface related stuff *******
462  {
463  if (isMcuConnected()){
464  switch(CurrentInterfaceMode)
465  {
466  #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
467  case imATM_BLB:
468  case imSIL_BLB:
469  case imARM_BLB:
470  {
471  if (!BL_SendCMDKeepAlive()) { // SetStateDisconnected() included
472  ACK_OUT = ACK_D_GENERAL_ERROR;
473  }
474  break;
475  }
476  #endif
477  #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
478  case imSK:
479  {
480  if (!Stk_SignOn()) { // SetStateDisconnected();
481  ACK_OUT = ACK_D_GENERAL_ERROR;
482  }
483  break;
484  }
485  #endif
486  default:
487  ACK_OUT = ACK_D_GENERAL_ERROR;
488  }
489  if ( ACK_OUT != ACK_OK) SET_DISCONNECTED;
490  }
491  break;
492  }
494  {
495  // Only interface itself, no matter what Device
496  Dummy.bytes[0] = SERIAL_4WAY_PROTOCOL_VER;
497  break;
498  }
499 
501  {
502  // Only interface itself, no matter what Device
503  // O_PARAM_LEN=16;
504  O_PARAM_LEN = strlen(SERIAL_4WAY_INTERFACE_NAME_STR);
505  O_PARAM = (uint8_t *)SERIAL_4WAY_INTERFACE_NAME_STR;
506  break;
507  }
508 
510  {
511  // Only interface itself, no matter what Device
512  // Dummy = iUart_res_InterfVersion;
513  O_PARAM_LEN = 2;
514  Dummy.bytes[0] = SERIAL_4WAY_VERSION_HI;
515  Dummy.bytes[1] = SERIAL_4WAY_VERSION_LO;
516  break;
517  }
518  case cmd_InterfaceExit:
519  {
520  isExitScheduled = true;
521  break;
522  }
524  {
525 #if defined(USE_SERIAL_4WAY_BLHELI_BOOTLOADER) && defined(USE_SERIAL_4WAY_SK_BOOTLOADER)
526  if ((ParamBuf[0] <= imARM_BLB) && (ParamBuf[0] >= imSIL_BLB)) {
527 #elif defined(USE_SERIAL_4WAY_BLHELI_BOOTLOADER)
528  if (((ParamBuf[0] <= imATM_BLB)||(ParamBuf[0] == imARM_BLB)) && (ParamBuf[0] >= imSIL_BLB)) {
529 #elif defined(USE_SERIAL_4WAY_SK_BOOTLOADER)
530  if (ParamBuf[0] == imSK) {
531 #endif
532  CurrentInterfaceMode = ParamBuf[0];
533  } else {
534  ACK_OUT = ACK_I_INVALID_PARAM;
535  }
536  break;
537  }
538 
539  case cmd_DeviceReset:
540  {
541  if (ParamBuf[0] < escCount) {
542  // Channel may change here
543  selected_esc = ParamBuf[0];
544  }
545  else {
546  ACK_OUT = ACK_I_INVALID_CHANNEL;
547  break;
548  }
549  switch (CurrentInterfaceMode)
550  {
551  case imSIL_BLB:
552  #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
553  case imATM_BLB:
554  case imARM_BLB:
555  {
556  BL_SendCMDRunRestartBootloader(&DeviceInfo);
557  break;
558  }
559  #endif
560  #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
561  case imSK:
562  {
563  break;
564  }
565  #endif
566  }
567  SET_DISCONNECTED;
568  break;
569  }
570  case cmd_DeviceInitFlash:
571  {
572  SET_DISCONNECTED;
573  if (ParamBuf[0] < escCount) {
574  //Channel may change here
575  //ESC_LO or ESC_HI; Halt state for prev channel
576  selected_esc = ParamBuf[0];
577  } else {
578  ACK_OUT = ACK_I_INVALID_CHANNEL;
579  break;
580  }
581  O_PARAM_LEN = DeviceInfoSize; //4
582  O_PARAM = (uint8_t *)&DeviceInfo;
583  if(Connect(&DeviceInfo)) {
584  DeviceInfo.bytes[INTF_MODE_IDX] = CurrentInterfaceMode;
585  } else {
586  SET_DISCONNECTED;
587  ACK_OUT = ACK_D_GENERAL_ERROR;
588  }
589  break;
590  }
591 
592  #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
593  case cmd_DeviceEraseAll:
594  {
595  switch(CurrentInterfaceMode)
596  {
597  case imSK:
598  {
599  if (!Stk_Chip_Erase()) ACK_OUT=ACK_D_GENERAL_ERROR;
600  break;
601  }
602  default:
603  ACK_OUT = ACK_I_INVALID_CMD;
604  }
605  break;
606  }
607  #endif
608 
609  #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
610  case cmd_DevicePageErase:
611  {
612  switch (CurrentInterfaceMode)
613  {
614  case imSIL_BLB:
615  case imARM_BLB:
616  {
617  Dummy.bytes[0] = ParamBuf[0];
618  if (CurrentInterfaceMode == imARM_BLB) {
619  // Address =Page * 1024
620  ioMem.D_FLASH_ADDR_H = (Dummy.bytes[0] << 2);
621  } else {
622  //Address = Page * 512
623  ioMem.D_FLASH_ADDR_H = (Dummy.bytes[0] << 1);
624  }
625  ioMem.D_FLASH_ADDR_L = 0;
626  if (!BL_PageErase(&ioMem)) ACK_OUT = ACK_D_GENERAL_ERROR;
627  break;
628  }
629  default:
630  ACK_OUT = ACK_I_INVALID_CMD;
631  }
632  break;
633  }
634  #endif
635 
636  //*** Device Memory Read Ops ***
637  case cmd_DeviceRead:
638  {
639  ioMem.D_NUM_BYTES = ParamBuf[0];
640  /*
641  wtf.D_FLASH_ADDR_H=Adress_H;
642  wtf.D_FLASH_ADDR_L=Adress_L;
643  wtf.D_PTR_I = BUF_I;
644  */
645  switch(CurrentInterfaceMode)
646  {
647  #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
648  case imSIL_BLB:
649  case imATM_BLB:
650  case imARM_BLB:
651  {
652  if(!BL_ReadFlash(CurrentInterfaceMode, &ioMem))
653  {
654  ACK_OUT = ACK_D_GENERAL_ERROR;
655  }
656  break;
657  }
658  #endif
659  #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
660  case imSK:
661  {
662  if(!Stk_ReadFlash(&ioMem))
663  {
664  ACK_OUT = ACK_D_GENERAL_ERROR;
665  }
666  break;
667  }
668  #endif
669  default:
670  ACK_OUT = ACK_I_INVALID_CMD;
671  }
672  if (ACK_OUT == ACK_OK)
673  {
674  O_PARAM_LEN = ioMem.D_NUM_BYTES;
675  O_PARAM = (uint8_t *)&ParamBuf;
676  }
677  break;
678  }
679 
681  {
682  ioMem.D_NUM_BYTES = ParamBuf[0];
683  /*
684  wtf.D_FLASH_ADDR_H = Adress_H;
685  wtf.D_FLASH_ADDR_L = Adress_L;
686  wtf.D_PTR_I = BUF_I;
687  */
688  switch (CurrentInterfaceMode)
689  {
690  #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
691  case imATM_BLB:
692  case imARM_BLB:
693  {
694  if (!BL_ReadEEprom(&ioMem))
695  {
696  ACK_OUT = ACK_D_GENERAL_ERROR;
697  }
698  break;
699  }
700  #endif
701  #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
702  case imSK:
703  {
704  if (!Stk_ReadEEprom(&ioMem))
705  {
706  ACK_OUT = ACK_D_GENERAL_ERROR;
707  }
708  break;
709  }
710  #endif
711  default:
712  ACK_OUT = ACK_I_INVALID_CMD;
713  }
714  if(ACK_OUT == ACK_OK)
715  {
716  O_PARAM_LEN = ioMem.D_NUM_BYTES;
717  O_PARAM = (uint8_t *)&ParamBuf;
718  }
719  break;
720  }
721 
722  //*** Device Memory Write Ops ***
723  case cmd_DeviceWrite:
724  {
725  ioMem.D_NUM_BYTES = I_PARAM_LEN;
726  /*
727  wtf.D_FLASH_ADDR_H=Adress_H;
728  wtf.D_FLASH_ADDR_L=Adress_L;
729  wtf.D_PTR_I = BUF_I;
730  */
731  switch (CurrentInterfaceMode)
732  {
733  #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
734  case imSIL_BLB:
735  case imATM_BLB:
736  {
737  if (!BL_WriteFlash(&ioMem)) {
738  ACK_OUT = ACK_D_GENERAL_ERROR;
739  }
740  break;
741  }
742  #endif
743  #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
744  case imSK:
745  {
746  if (!Stk_WriteFlash(&ioMem))
747  {
748  ACK_OUT = ACK_D_GENERAL_ERROR;
749  }
750  break;
751  }
752  #endif
753  }
754  break;
755  }
756 
758  {
759  ioMem.D_NUM_BYTES = I_PARAM_LEN;
760  ACK_OUT = ACK_D_GENERAL_ERROR;
761  /*
762  wtf.D_FLASH_ADDR_H=Adress_H;
763  wtf.D_FLASH_ADDR_L=Adress_L;
764  wtf.D_PTR_I = BUF_I;
765  */
766  switch (CurrentInterfaceMode)
767  {
768  #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
769  case imSIL_BLB:
770  {
771  ACK_OUT = ACK_I_INVALID_CMD;
772  break;
773  }
774  case imATM_BLB:
775  {
776  if (BL_WriteEEprom(&ioMem))
777  {
778  ACK_OUT = ACK_OK;
779  }
780  break;
781  }
782  #endif
783  #ifdef USE_SERIAL_4WAY_SK_BOOTLOADER
784  case imSK:
785  {
786  if (Stk_WriteEEprom(&ioMem))
787  {
788  ACK_OUT = ACK_OK;
789  }
790  break;
791  }
792  #endif
793  }
794  break;
795  }
796  //*** Device Memory Verify Ops ***
797  #ifdef USE_SERIAL_4WAY_BLHELI_BOOTLOADER
798  case cmd_DeviceVerify:
799  {
800  switch (CurrentInterfaceMode)
801  {
802  case imARM_BLB:
803  {
804  ioMem.D_NUM_BYTES = I_PARAM_LEN;
805  /*
806  wtf.D_FLASH_ADDR_H=Adress_H;
807  wtf.D_FLASH_ADDR_L=Adress_L;
808  wtf.D_PTR_I = BUF_I;
809  */
810 
811  ACK_OUT = BL_VerifyFlash(&ioMem);
812  switch (ACK_OUT) {
813  case brSUCCESS:
814  ACK_OUT = ACK_OK;
815  break;
816  case brERRORVERIFY:
817  ACK_OUT = ACK_I_VERIFY_ERROR;
818  break;
819  default:
820  ACK_OUT = ACK_D_GENERAL_ERROR;
821  break;
822  }
823  break;
824  }
825  default:
826  {
827  ACK_OUT = ACK_I_INVALID_CMD;
828  break;
829  }
830  }
831  break;
832  }
833  #endif
834  default:
835  {
836  ACK_OUT = ACK_I_INVALID_CMD;
837  }
838  }
839  }
840 
841  CRCout.word = 0;
842 
843  RX_LED_OFF;
844 
845 // serialBeginWrite(port);
846  WriteByteCrc(cmd_Remote_Escape);
847  WriteByteCrc(CMD);
848  WriteByteCrc(ioMem.D_FLASH_ADDR_H);
849  WriteByteCrc(ioMem.D_FLASH_ADDR_L);
850  WriteByteCrc(O_PARAM_LEN);
851 
852  i=O_PARAM_LEN;
853  do {
854  while(UartTxPending()) hal_yield(0);
855  WriteByteCrc(*O_PARAM);
856  O_PARAM++;
857  i--;
858  } while (i > 0);
859 
860  WriteByteCrc(ACK_OUT);
861  WriteByte(CRCout.bytes[1]);
862  WriteByte(CRCout.bytes[0]);
863  //serialEndWrite(port);
864 
865  TX_LED_OFF;
866  if (isExitScheduled) {
867  esc4wayRelease();
868  return;
869  }
870  };
871 }
872 
873 
874 
875 #endif
uint8_t * D_PTR_I
uint8_t D_NUM_BYTES
uint8_t D_FLASH_ADDR_L
uint8_t BL_VerifyFlash(ioMem_t *pMem)
#define ACK_I_INVALID_CHANNEL
#define cmd_InterfaceGetName
#define ACK_I_INVALID_PARAM
virtual bool tx_pending()=0
#define ACK_D_GENERAL_ERROR
#define ACK_OK
#define cmd_InterfaceSetMode
void setEscInput(uint8_t selEsc)
uint8_32_u
Definition: serial_4way.h:36
#define imATM_BLB
uint8_t D_FLASH_ADDR_H
uint8_t Stk_WriteEEprom(ioMem_t *pMem)
uint8_t BL_ReadEEprom(ioMem_t *pMem)
#define brERRORVERIFY
#define cmd_DeviceWriteEEprom
void setEscHi(uint8_t selEsc)
const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS]
#define imSK
void BL_SendCMDRunRestartBootloader(uint8_32_u *pDeviceInfo)
#define imSIL_BLB
uint8_t Stk_WriteFlash(ioMem_t *pMem)
#define SERIAL_4WAY_VERSION_HI
bool isEscLo(uint8_t selEsc)
#define cmd_Local_Escape
#define ACK_I_INVALID_CMD
#define cmd_InterfaceTestAlive
void gpio_set_mode(const gpio_dev *const dev, uint8_t pin, gpio_pin_mode mode)
Definition: gpio_hal.c:125
bool isMcuConnected(void)
uint8_t BL_WriteEEprom(ioMem_t *pMem)
uint8_t BL_SendCMDKeepAlive(void)
static const uint8_t * output_channels
Definition: RCOutput.cpp:143
#define HIGH
Definition: board.h:34
uint8_16_u
Definition: serial_4way.h:30
uint8_t Stk_ConnectEx(uint8_32_u *pDeviceInfo)
#define cmd_ProtocolGetVersion
#define cmd_InterfaceGetVersion
#define cmd_DeviceReadEEprom
virtual size_t write(uint8_t)=0
uint8_t BL_PageErase(ioMem_t *pMem)
bool isEscHi(uint8_t selEsc)
#define cmd_DeviceVerify
#define cmd_DeviceReset
#define LOW
Definition: board.h:31
uint8_t Stk_Chip_Erase(void)
uint8_t Stk_ReadFlash(ioMem_t *pMem)
#define SERIAL_4WAY_VERSION_LO
virtual int16_t read()=0
uint8_t BL_ReadFlash(uint8_t interface_mode, ioMem_t *pMem)
#define cmd_DeviceInitFlash
#define cmd_DeviceWrite
void setEscLo(uint8_t selEsc)
uint8_t selected_esc
virtual uint32_t available()=0
const gpio_dev * gpio_device
static INLINE uint8_t gpio_read_bit(const gpio_dev *const dev, uint8_t pin)
Definition: gpio_hal.h:130
void esc4wayProcess(AP_HAL::UARTDriver *uartPort)
uint8_t Stk_SignOn(void)
uint8_t BL_WriteFlash(ioMem_t *pMem)
uint16_t _crc_xmodem_update(uint16_t crc, uint8_t data)
#define cmd_InterfaceExit
static int8_t pin
Definition: AnalogIn.cpp:15
#define SERIAL_4WAY_PROTOCOL_VER
#define ACK_I_INVALID_CRC
#define cmd_DeviceEraseAll
uint8_t BL_ConnectEx(uint8_32_u *pDeviceInfo)
#define cmd_Remote_Escape
uint8_t gpio_bit
Definition: boards.h:92
uint8_t Stk_ReadEEprom(ioMem_t *pMem)
Stores STM32-specific information related to a given Maple pin.
Definition: boards.h:88
#define cmd_DeviceRead
const gpio_dev *const gpio_device
Definition: boards.h:89
#define imARM_BLB
#define ACK_I_VERIFY_ERROR
void hal_yield(uint16_t ttw)
Definition: Scheduler.cpp:1430
void setEscOutput(uint8_t selEsc)
#define brSUCCESS
#define cmd_DevicePageErase
#define MAX_SUPPORTED_MOTORS
static INLINE void gpio_write_bit(const gpio_dev *const dev, uint8_t pin, uint8_t val)
Definition: gpio_hal.h:115
uint8_t esc4wayInit(const uint8_t *output_channels, uint8_t nm)