APM:Libraries
HAL_F4Light_Class.cpp
Go to the documentation of this file.
1 /*
2 (c) 2017 night_ghost@ykoctpa.ru
3 
4 */
5 
6 #pragma GCC optimize ("O2")
7 
8 #include <AP_HAL/AP_HAL.h>
9 
10 #if CONFIG_HAL_BOARD == HAL_BOARD_F4LIGHT
11 #include <assert.h>
14 #include "AP_HAL_F4Light_Private.h"
15 #include "HAL_F4Light_Class.h"
16 #include "RCInput.h"
17 #include "Util.h"
18 
20 
21 #include "UART_PPM.h"
22 
23 #if defined(USE_SOFTSERIAL)
24 #include "UART_SoftDriver.h"
25 #endif
26 
27 
28 
29 #if defined(BOARD_SDCARD_NAME) || defined(BOARD_DATAFLASH_FATFS)
30 #include "sd/SD.h"
31 #endif
32 
33 #if defined(BOARD_OSD_CS_PIN)
34 #include "UART_OSD.h"
35 #endif
36 
37 #if defined(USB_MASSSTORAGE)
39 #endif
40 
41 using namespace F4Light;
42 
43 
45 
46 // XXX make sure these are assigned correctly
47 static USBDriver USB_Driver(1); // ACM
48 static UARTDriver uart1Driver(_USART1); // main port
49 
50 #if defined(BOARD_USART6_RX_PIN) && defined(BOARD_USART6_TX_PIN)
51 static UARTDriver uart6Driver(_USART6); // pin 7&8(REVO)/5&6(RevoMini) of input port
52 #endif
53 
54 
55 #ifdef BOARD_HAS_UART3
56  static UARTDriver uart3Driver(_USART3); // flexi port
57 // static SerialDriver IN_CCM softDriver(BOARD_SOFTSERIAL_TX, BOARD_SOFTSERIAL_RX, false); // pin 7&8 of input port
58 #endif
59 
60 #if defined(BOARD_SOFT_UART3) || defined(USE_SOFTSERIAL)
61  static SerialDriver IN_CCM softDriver(BOARD_SOFTSERIAL_TX, BOARD_SOFTSERIAL_RX, false);
62 #endif
63 
64 
65 #ifdef BOARD_OSD_CS_PIN
66  static UART_OSD uartOSDdriver;
67 #endif
68 
69 #if defined(BOARD_USART4_RX_PIN) && defined( BOARD_USART4_TX_PIN)
70  static UARTDriver uart4Driver(_UART4); // pin 5&6 of servo port
71 #endif
72 
73 #if defined(BOARD_USART5_RX_PIN) && defined( BOARD_USART5_TX_PIN)
74  static UARTDriver uart5Driver(_UART5);
75 #endif
76 
77 static UART_PPM uartPPM2(1); // PPM2 input
78 static UART_PPM uartPPM1(0); // PPM1 input
79 
80 
81 
82 // only for DSM satellite, served in rc_input
83 //static UARTDriver uart5Driver(_UART5,0); // D26/PD2 6 EXTI_RFM22B / UART5_RX input-only UART for DSM satellite
84 
85 /*
86  input port pinout
87  1 2 3 4 5 6 7 8
88 pin b14 b15 c6 c7 c8 c9
89  gnd vcc PPM buzz 6_tx 6_rx Sscl Ssda
90 USE_SOFTSERIAL -> S_tx S_rx
91 servos -> srv7 srv8 srv9 srv10 srv11 srv12
92 */
93 
94 
95 /* OPLINK AIR port pinout
96 1 2 3 4 5 6 7
97 
98 gnd +5 26 103
99  rx pow
100 */
101 
110 
112 
113 //const AP_HAL::UARTDriver** HAL_F4Light::uarts[] = { &uartA, &uartB, &uartC, &uartD, &uartE, &uartF };
114 
115 /*
116  AP_HAL::UARTDriver* _uartA, // console
117  AP_HAL::UARTDriver* _uartB, // 1st GPS
118  AP_HAL::UARTDriver* _uartC, // telem1
119  AP_HAL::UARTDriver* _uartD, // telem2
120  AP_HAL::UARTDriver* _uartE, // 2nd GPS
121  AP_HAL::UARTDriver* _uartF, // extra1
122 
123 
124 AP_SerialManager.cpp line 159
125  // initialise pointers to serial ports
126  state[1].uart = hal.uartC; // serial1, uartC, normally telem1
127  state[2].uart = hal.uartD; // serial2, uartD, normally telem2
128  state[3].uart = hal.uartB; // serial3, uartB, normally 1st GPS
129  state[4].uart = hal.uartE; // serial4, uartE, normally 2nd GPS
130  state[5].uart = hal.uartF; // serial5
131 
132 
133 
134 */
135 
136 
137 
139  AP_HAL::HAL(
140  &USB_Driver, // uartA - USB console - Serial0
141 
142 #if BOARD_UARTS_LAYOUT == 1 // Revolution
143 
144  &uart6Driver, // uartB - pin 7&8(REVO)/5&6(RevoMini) of input port - for GPS - Serial3
145  &uart1Driver, // uartC - main port - for telemetry - Serial1
146  &uart3Driver, // uartD - flexi port - Serial2
147  &uart4Driver, // uartE - PWM pins 5&6 - Serial4
148  &softDriver, // uartF - soft UART on pins 7&8 - Serial5
149 
150 #elif BOARD_UARTS_LAYOUT == 2 // Airbot
151 
152  &uart6Driver, // uartB - pin 7&8(REVO)/5&6(RevoMini) of input port - for GPS - Serial3
153  &uart1Driver, // uartC - main port - for telemetry - Serial1
154  &uart4Driver, // uartD - PWM pins 5&6 - Serial2
155  &uartPPM2, // uartE - input data from PPM2 pin - Serial4
156  &uartPPM1, // uartF - input data from PPM1 pin - Serial5
157 
158 #elif BOARD_UARTS_LAYOUT == 3 // AirbotV2
159 
160  &uart6Driver, // uartB - pin 7&8(REVO)/5&6(RevoMini) of input port - for GPS - Serial3
161  &uart1Driver, // uartC - main port - for telemetry - Serial1
162  &uartOSDdriver, // uartD - OSD emulated UART - Serial2
163  &uart4Driver, // uartE - PWM pins 5&6 - Serial4
164  &uartPPM2, // uartF - input data from PPM2 pin - Serial5
165 
166 #elif BOARD_UARTS_LAYOUT == 4 // MiniOSD
167 
168  &uart6Driver, // uartB - pin 7&8(REVO)/5&6(RevoMini) of input port - for GPS - Serial3
169  &uart1Driver, // uartC - main port - for telemetry - Serial1
170  NULL,
171  NULL,
172  NULL,
173 
174 #elif BOARD_UARTS_LAYOUT == 5 // MicroOSD
175 
176  &uart6Driver, // uartB - pin 7&8(REVO)/5&6(RevoMini) of input port - for GPS - Serial3
177  &uart1Driver, // uartC - main port - for telemetry - Serial1
178  NULL,
179  NULL,
180  NULL,
181 
182 #elif BOARD_UARTS_LAYOUT == 6 // MatekF405_CTR
183 
184  &uart4Driver, // uartB - UART4 for GPS - Serial3
185  &uart1Driver, // uartC - UART1 for telemetry - Serial1
186  &uartOSDdriver, // uartD - OSD emulated UART - Serial2
187  &uart3Driver, // uartE - UART3 - Serial4
188  &uart5Driver, // uartF - UART5 - Serial5
189 
190 #elif BOARD_UARTS_LAYOUT == 7 // Cl_Racing F4
191 
192  &uart6Driver, // uartB - pin 7&8(REVO)/5&6(RevoMini) of input port - for GPS - Serial3
193  &uart1Driver, // uartC - main port - for telemetry - Serial1
194  &uartOSDdriver, // uartD - OSD emulated UART - Serial2
195  &uartPPM1, // uartE - input data from PPM1 pin - Serial4
196  NULL, // no uartF
197 
198 #else
200 #endif
201 
202  &i2c_mgr_instance, // I2C
203  &spiDeviceManager, // spi
204  &analogIn, // analogin
205  &storageDriver, // storage
206  &HAL_CONSOLE, // console via radio or USB on per-board basis
207  &gpioDriver, // gpio
208  &rcinDriver, // rcinput
209  &rcoutDriver, // rcoutput
210  &schedulerInstance, // scheduler
211  &utilInstance, // util
212  nullptr, // no onboard optical flow
213  nullptr // no CAN
214  )
215 
216  // 0 1 2 3 4 5
217  // USB Main Flexi/OSD Uart4 UART6 Soft/Uart4
218  , uarts{ &uartA, &uartC, &uartD, &uartE, &uartB, &uartF }
219 
220 {
221 
222  uint32_t sig = board_get_rtc_register(RTC_CONSOLE_REG);
223  if( (sig & ~CONSOLE_PORT_MASK) == CONSOLE_PORT_SIGNATURE) {
225  if(up){
226  console = *up;
227  }
228  }
229 }
230 
231 extern const AP_HAL::HAL& hal;
232 
233 
234 void HAL_F4Light::run(int argc,char* const argv[], Callbacks* callbacks) const
235 {
236  assert(callbacks);
237 
238  /* initialize all drivers and private members here.
239  * up to the programmer to do this in the correct order.
240  * Scheduler should likely come first. */
241 
242  scheduler->init();
243 
244  uint32_t start_t = AP_HAL::millis();
245 
246  gpio->init();
247 
248  rcout->init();
249 
251 
252  {
253 #if defined(USB_MASSSTORAGE)
255  if( sig == MASS_STORAGE_SIGNATURE) {
257 
258 #if defined(BOARD_SDCARD_NAME) && defined(BOARD_SDCARD_CS_PIN)
260 #elif defined(BOARD_DATAFLASH_FATFS)
261  SD.begin(F4Light::SPIDeviceManager::_get_device(HAL_DATAFLASH_NAME));
262 #endif
263  state.sd_busy=true;
264  massstorage.setup(); // init USB as mass-storage
265  }
266  else
267 #endif
268  {
269  extern void usb_init(); // init as VCP
270  usb_init(); // moved from boards.cpp
271 
272  uartA->begin(115200); // uartA is the USB serial port used for the console, so lets make sure it is initialized at boot
273  }
274  }
275 
276 
277  if(console != uartA) {
278  console->begin(57600); // init telemetry port as console
279  }
280 
281 
282  rcin->init();
283 
284  storage->init(); // Uses EEPROM.*, flash_stm* reworked
285  analogin->init();
286 
287  printf("\nHAL startup at %ldms\n", start_t);
288 
289  if(!state.sd_busy) {
290 
291 
292 #if defined(BOARD_SDCARD_NAME) && defined(BOARD_SDCARD_CS_PIN)
293  printf("\nEnabling SD at %ldms\n", AP_HAL::millis());
295 #elif defined(BOARD_DATAFLASH_FATFS)
296  printf("\nEnabling DataFlash as SD at %ldms\n", AP_HAL::millis());
297  SD.begin(F4Light::SPIDeviceManager::_get_device(HAL_DATAFLASH_NAME));
298 #endif
299 
300 #if defined(BOARD_OSD_NAME)
301  uartOSDdriver.begin(57600); // init OSD after SD but before call to lateInit(), but only if not in USB_STORAGE
302 #endif
303 
304  }
305 
306 
307  printf("\nHAL init done at %ldms\n", AP_HAL::millis());
308 
309  callbacks->setup();
310 
311 #if 0 //[ here is too late :( so we need a small hack and call lateInit from Scheduler::register_delay_callback
312 // which called when parameters already initialized
313 
314  lateInit();
315 #endif //]
316 
317 
318  scheduler->system_initialized(); // clear bootloader flag
319 
320  Scheduler::start_stats_task();
321 
322  printf("\nLoop started at %ldms\n", AP_HAL::millis());
323 
324 
325 // main application loop hosted here!
326  for (;;) {
327  callbacks->loop();
328 // ((F4Light::Scheduler *)scheduler)->loop(); // to execute stats in main loop
329 // ((F4Light::RCInput *)rcin)->loop(); // to execute debug in main loop
330  }
331 }
332 
333 
334 static bool lateInitDone=false;
335 
337 
338  if(lateInitDone) return;
339 
340  lateInitDone=true;
341 
342  {
343  uint32_t sig = board_get_rtc_register(RTC_CONSOLE_REG);
344  uint8_t port = hal_param_helper->_console_uart;
345 
346  if(port < sizeof(uarts)/sizeof(AP_HAL::UARTDriver**) ){
347 
348  if( (sig & ~CONSOLE_PORT_MASK) == CONSOLE_PORT_SIGNATURE) {
349  if(port != (sig & CONSOLE_PORT_MASK)) { // wrong console - reboot needed
350  board_set_rtc_register(CONSOLE_PORT_SIGNATURE | (port & CONSOLE_PORT_MASK), RTC_CONSOLE_REG);
351  board_set_rtc_register(FORCE_APP_RTC_SIGNATURE, RTC_SIGNATURE_REG); // force bootloader to not wait
352  Scheduler::_reboot(false);
353  }
354  } else { // no signature - set and check console
356 
357  AP_HAL::UARTDriver** up = uarts[port];
358  if(up && *up != console) {
359  board_set_rtc_register(FORCE_APP_RTC_SIGNATURE, RTC_SIGNATURE_REG); // force bootloader to not wait
360  Scheduler::_reboot(false);
361  }
362  }
363  }
364  }
365  {
368  uint8_t oc = hal_param_helper->_overclock;
369 
370  if(g==OV_GUARD_FAIL_SIGNATURE) {
371  if(oc==0) {
373  board_set_rtc_register(0, RTC_OV_GUARD_REG); // and reset failure
374  } else printf("\noverclocking failed!\n");
375  } else {
376 
377  if((sig & ~OVERCLOCK_SIG_MASK ) == OVERCLOCK_SIGNATURE ) { // if correct signature
378  board_set_rtc_register(OVERCLOCK_SIGNATURE | oc, RTC_OVERCLOCK_REG); // set required clock in any case
379  if((sig & OVERCLOCK_SIG_MASK) != oc) { // if wrong clock
380  board_set_rtc_register(FORCE_APP_RTC_SIGNATURE, RTC_SIGNATURE_REG); // force bootloader to not wait
381  Scheduler::_reboot(false); // then reboot required
382  }
383  } else { // no signature, write only if needed
384  if(oc) board_set_rtc_register(OVERCLOCK_SIGNATURE | oc, RTC_OVERCLOCK_REG); // set required clock
385  }
386  }
387  }
388 
389  { // one-time connection to COM-port
390  uint8_t conn = hal_param_helper->_connect_com;
391  if(conn) {
392  hal_param_helper->_connect_com = 0;
393  hal_param_helper->_connect_com.save();
394 
395  if(conn < sizeof(uarts)/sizeof(AP_HAL::UARTDriver**) ){
396  AP_HAL::UARTDriver** up = uarts[conn];
397  if(up && *up){
398  connect_uart(uartA,*up, NULL);
399  }
400  } else printf("\nWrong HAL_CONNECT_COM selected!");
401 
402  }
403  }
404 
405 #if defined(USB_MASSSTORAGE)
406  if(!state.sd_busy){
407  uint8_t conn=hal_param_helper->_usb_storage;
408 
409  if(conn){
410  hal_param_helper->_usb_storage=0;
411  hal_param_helper->_usb_storage.save();
412 
414  board_set_rtc_register(FORCE_APP_RTC_SIGNATURE, RTC_SIGNATURE_REG); // force bootloader to not wait
415  Scheduler::_reboot(false);
416  }
417  }
418 #endif
419 
420 #ifdef USE_SERIAL_4WAY_BLHELI_INTERFACE
421  { // one-time connection to ESC
422  uint8_t conn = hal_param_helper->_connect_esc;
423 
424  if(conn){
425  hal_param_helper->_connect_esc = 0;
426  hal_param_helper->_connect_esc.save();
427 
428  conn-=1;
429 
430  if(conn < sizeof(uarts)/sizeof(AP_HAL::UARTDriver**) ){
431  AP_HAL::UARTDriver** up = uarts[conn];
432  if(up && *up){
433  RCOutput::do_4way_if(*up);
434  }
435  } else printf("\nWrong HAL_CONNECT_ESC selected!");
436  }
437  }
438 #endif
439 
440  RCOutput::lateInit(); // 2nd stage - now with loaded parameters
441 
442  // all another parameter-dependent inits
443 
444 #ifdef BOARD_I2C_FLEXI
445  if(hal_param_helper->_flexi_i2c) {
446  uart3Driver.end();
447  uart3Driver.disable(); // uses Flexi port occupied by I2C
448  printf("\nUART3 disabled by I2C2\n");
449  }
450 #endif
451  I2CDevice::lateInit();
452 
453  Storage::late_init(hal_param_helper->_eeprom_deferred);
454 
455  uint8_t flags=0;
456 
457  if(hal_param_helper->_rc_fs) flags |= BOARD_RC_FAILSAFE;
458 
459  RCInput::late_init(flags);
460 }
461 
462 // 57600 gives ~6500 chars per second or 6 chars per ms
464  while(1){
465  bool got=false;
466  if(uartL->available() && uartR->txspace()) { uartR->write(uartL->read()); got=true; }
467  if(uartR->available() && uartL->txspace()) { uartL->write(uartR->read()); got=true; }
468  if(proc) proc();
469  if(!got) Scheduler::yield(100); // give a chance to other threads
470  if(state.disconnect) break; // if USB disconnected
471  }
472 }
473 
474 static const HAL_F4Light hal_revo;
475 
476 const AP_HAL::HAL& AP_HAL::get_HAL() {
477  return hal_revo;
478 }
479 
480 
481 extern "C" void usb_mass_mal_USBdisconnect();
482 
484  HAL_F4Light::state.sd_busy=false;
485  HAL_F4Light::state.disconnect=true;
486 }
487 
488 #endif
const AP_HAL::HAL & hal
-*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
Definition: AC_PID_test.cpp:14
static UART_PPM uartPPM2(1)
virtual void init()=0
int printf(const char *fmt,...)
Definition: stdio.c:113
virtual void setup()=0
#define RTC_MASS_STORAGE_REG
Definition: boards.h:314
static void usart_disable_all(void)
Disable all serial ports.
Definition: usart.h:206
#define OV_GUARD_FAIL_SIGNATURE
Definition: boards.h:309
static Scheduler schedulerInstance
AP_HAL::UARTDriver * uartE
Definition: HAL.h:104
void usb_mass_mal_USBdisconnect()
virtual void init()=0
virtual void loop()=0
#define FORCE_APP_RTC_SIGNATURE
Definition: boards.h:293
static RCInput rcinDriver
static const HAL_F4Light hal_revo
#define BOARD_SOFTSERIAL_TX
Definition: board.h:92
AP_HAL::UARTDriver * console
Definition: HAL.h:110
virtual void begin(uint32_t baud)=0
#define RTC_OVERCLOCK_REG
Definition: boards.h:316
#define OVERCLOCK_SIG_MASK
Definition: boards.h:307
static Util utilInstance
static USBDriver USB_Driver(1)
#define CONSOLE_PORT_SIGNATURE
Definition: boards.h:299
AP_HAL::UARTDriver * uartB
Definition: HAL.h:101
virtual uint32_t txspace()=0
void(* Proc)(void)
const usart_dev *const _UART4
uint8_t disconnect
static HAL_state state
static AP_HAL::OwnPtr< F4Light::SPIDevice > _get_device(const char *name)
Definition: SPIDevice.cpp:429
#define MASS_STORAGE_SIGNATURE
Definition: boards.h:303
void begin(uint32_t b)
-*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
static AnalogIn analogIn IN_CCM
static ChibiOS::AnalogIn analogIn
AP_HAL::UARTDriver * uartC
Definition: HAL.h:102
static UART_PPM uartPPM1(0)
virtual void init()=0
void yield(uint32_t us)
Definition: system.cpp:99
#define BOARD_SDCARD_NAME
Definition: board.h:136
void run(int argc, char *const argv[], Callbacks *callbacks) const override
#define BOARD_SOFTSERIAL_RX
Definition: board.h:93
#define BOARD_RC_FAILSAFE
Definition: RCInput.h:13
virtual void init()=0
#define RTC_CONSOLE_REG
Definition: boards.h:315
AP_HAL::UARTDriver * uartF
Definition: HAL.h:105
#define HAL_CONSOLE
Definition: board.h:183
virtual void init()=0
virtual size_t write(uint8_t)=0
uint32_t millis()
Definition: system.cpp:157
static F4Light::SPIDeviceManager spiDeviceManager
AP_HAL::UARTDriver ** uarts[6]
AP_HAL::UARTDriver * uartD
Definition: HAL.h:103
AP_HAL::Storage * storage
Definition: HAL.h:109
#define RTC_OV_GUARD_REG
Definition: boards.h:317
virtual int16_t read()=0
#define NULL
Definition: hal_types.h:59
const HAL & get_HAL()
const usart_dev *const _USART1
Definition: usart.c:34
const usart_dev *const _USART3
Definition: usart.c:74
static GPIO gpioDriver
virtual uint32_t available()=0
virtual void init()=0
static F4Light::I2CDeviceManager i2c_mgr_instance
static Storage storageDriver
AP_HAL::UARTDriver * uartA
Definition: HAL.h:100
const usart_dev *const _UART5
AP_HAL::GPIO * gpio
Definition: HAL.h:111
uint32_t board_get_rtc_register(uint16_t reg)
Definition: boards.cpp:151
static UARTDriver uart1Driver(_USART1)
#define CONSOLE_PORT_MASK
Definition: boards.h:300
#define error(fmt, args ...)
void board_set_rtc_register(uint32_t sig, uint16_t reg)
Definition: boards.cpp:141
AP_HAL::RCOutput * rcout
Definition: HAL.h:113
void connect_uart(AP_HAL::UARTDriver *uartL, AP_HAL::UARTDriver *uartR, AP_HAL::Proc proc)
static bool lateInitDone
AP_HAL::RCInput * rcin
Definition: HAL.h:112
#define RTC_SIGNATURE_REG
Definition: boards.h:312
#define OVERCLOCK_SIGNATURE
Definition: boards.h:306
static RCOutput rcoutDriver
void usb_init(void)
Definition: boards.cpp:51
#define BOARD_UARTS_LAYOUT
Definition: board.h:149
AP_HAL::Scheduler * scheduler
Definition: HAL.h:114
uint8_t sd_busy
AP_HAL::AnalogIn * analogin
Definition: HAL.h:108
const usart_dev *const _USART6
virtual void system_initialized()=0