dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
platform.h
Go to the documentation of this file.
1 #ifndef _BF_PLATFORM_H
2 #define _BF_PLATFORM_H
3 
4 #include <pios.h>
5 #include <pios_thread.h>
6 
7 #ifdef PIOS_INCLUDE_4WAY
8 
9 #include <openpilot.h>
10 
11 #include <pios_inlinedelay.h>
12 #include <pios_dio.h>
13 
14 #include <mixersettings.h>
15 
16 #define USE_SERIAL_4WAY_BLHELI_INTERFACE
17 
18 #define MAX_SUPPORTED_MOTORS 10
19 
20 typedef dio_tag_t IO_t;
21 
22 typedef struct serialPort_s serialPort_t;
23 typedef int ioConfig_t;
24 
25 // NONE initializer for IO_t variable
26 #define IO_NONE ((IO_t)0)
27 
28 struct serialPort_s {
29  uintptr_t com;
30 };
31 
32 typedef struct {
33  bool enabled;
34  IO_t io;
35 } pwmOutputPort_t;
36 
37 #define IOCFG_IPU 0
38 #define IOCFG_OUT_PP 1
39 #define IOCFG_AF_PP 2
40 
41 /* We'll implement the IO and PWM calls last, as they are not needed to
42  * do confirmation of "hello world" serial protocol signalling.
43  */
44 static inline bool IORead(IO_t io)
45 {
46  return dio_read(io);
47 }
48 
49 static inline void IOLo(IO_t io)
50 {
51  dio_low(io);
52 }
53 
54 static inline void IOHi(IO_t io)
55 {
56  dio_high(io);
57 }
58 
59 static inline void IOConfigGPIO(IO_t io, ioConfig_t cfg)
60 {
61  if (cfg) {
62  dio_set_output(io, false, DIO_DRIVE_MEDIUM, true);
63  } else {
65  }
66 }
67 
68 // Handled by the layer above-- the UAVO MSP Bridge-- in our code
69 static inline void pwmDisableMotors(void)
70 {
71 }
72 
73 static inline void pwmEnableMotors(void)
74 {
75 }
76 
77 static inline bool should_be_enabled(int type)
78 {
79  switch (type) {
80  case MIXERSETTINGS_MIXER1TYPE_DISABLED:
81  case MIXERSETTINGS_MIXER1TYPE_MOTOR:
82  return true;
83  default:
84  return false;
85  }
86 }
87 
88 /* Here be dragons */
89 #define set_disabled_token_paste(b) \
90  do { \
91  int saved_idx = (b) - 1; \
92  if (saved_idx < MAX_SUPPORTED_MOTORS) { \
93  pwm_val[saved_idx].enabled = pwm_val[saved_idx].enabled && \
94  should_be_enabled(mixerSettings.Mixer ## b ## Type); \
95  } \
96  } while (0)
97 
98 static inline pwmOutputPort_t *pwmGetMotors(void)
99 {
100  static pwmOutputPort_t pwm_val[MAX_SUPPORTED_MOTORS];
101  dio_tag_t dios_tmp[MAX_SUPPORTED_MOTORS];
102  int num_mot = PIOS_Servo_GetPins(dios_tmp, MAX_SUPPORTED_MOTORS);
103 
104  MixerSettingsData mixerSettings;
105  MixerSettingsGet(&mixerSettings);
106 
107  int i;
108 
109  for (i = 0; i < num_mot; i++) {
110  if (dios_tmp[i] != DIO_NULL) {
111  pwm_val[i].enabled = true;
112  pwm_val[i].io = dios_tmp[i];
113  } else {
114  pwm_val[i].enabled = false;
115  pwm_val[i].io = dios_tmp[i];
116  }
117  }
118 
119  for (; i < MAX_SUPPORTED_MOTORS; i++) {
120  pwm_val[i].enabled = false;
121  pwm_val[i].io = IO_NONE;
122  }
123 
124  set_disabled_token_paste(1);
125  set_disabled_token_paste(2);
126  set_disabled_token_paste(3);
127  set_disabled_token_paste(4);
128  set_disabled_token_paste(5);
129  set_disabled_token_paste(6);
130  set_disabled_token_paste(7);
131  set_disabled_token_paste(8);
132  set_disabled_token_paste(9);
133  set_disabled_token_paste(10);
134 
135  return pwm_val;
136 }
137 
138 /* Trivial wrappers on top of current delay mechanisms */
139 static inline void delayMicroseconds(uint32_t us)
140 {
141  PIOS_WDG_Clear();
142  PIOS_DELAY_WaituS(us);
143  PIOS_WDG_Clear();
144 }
145 
146 static inline uint32_t micros(void)
147 {
148  return PIOS_DELAY_GetuS();
149 }
150 
151 static inline uint32_t millis(void)
152 {
153  /* Can't use the thread time because interrupts disabled */
154  return micros() / 1000;
155 }
156 
157 /* Need these first */
158 static inline uint8_t serialRead(serialPort_t *instance)
159 {
160  uint8_t c;
161 
162  while (PIOS_COM_ReceiveBuffer(instance->com, &c, 1, 3000) < 1);
163 
164  return c;
165 }
166 
167 static inline void serialWrite(serialPort_t *instance, uint8_t ch)
168 {
169  PIOS_COM_SendBuffer(instance->com, &ch, sizeof(ch));
170 }
171 
172 /* These two are just used for blocking, so we make the above calls block */
173 static inline uint32_t serialRxBytesWaiting(const serialPort_t *instance)
174 {
175  return 1;
176 }
177 
178 static inline uint32_t serialTxBytesFree(const serialPort_t *instance)
179 {
180  return 1;
181 }
182 
183 /* These are used to cork/uncork VCP packets. We don't have this infrastructure
184  * (and really it isn't a win) -- omitting... */
185 static inline void serialBeginWrite(serialPort_t *instance)
186 {
187 }
188 
189 static inline void serialEndWrite(serialPort_t *instance)
190 {
191 }
192 
193 #endif /* PIOS_INCLUDE_4WAY */
194 
195 #endif /* _BF_PLATFORM_H */
static void dio_low(dio_tag_t t)
Sets an output GPIO low.
Definition: pios_dio.h:205
uint32_t PIOS_DELAY_GetuS()
Query the Delay timer for the current uS.
Definition: pios_delay.c:173
Main PiOS header to include all the compiled in PiOS options.
static void dio_set_input(dio_tag_t t, enum dio_pull pull)
Configures a GPIO as an input.
Definition: pios_dio.h:376
void PIOS_WDG_Clear(void)
Clear the watchdog timer.
Definition: pios_wdg.c:147
static struct flyingpicmd_cfg_fa cfg
Definition: main.c:49
int PIOS_Servo_GetPins(dio_tag_t *dios, int max_dio)
Definition: pios_servo.c:163
uint16_t PIOS_COM_ReceiveBuffer(uintptr_t com_id, uint8_t *buf, uint16_t buf_len, uint32_t timeout_ms)
static void dio_high(dio_tag_t t)
Sets an output GPIO high.
Definition: pios_dio.h:194
uint8_t i
Definition: msp_messages.h:97
static void dio_set_output(dio_tag_t t, bool open_collector, enum dio_drive_strength strength, bool first_value)
Configures a GPIO as an output.
Definition: pios_dio.h:334
PIOS_COM_SendBuffer(shub_global->frsky_port, shub_global->serial_buf, msg_length)
uint8_t type
void * dio_tag_t
Definition: pios_dio.h:12
Includes PiOS and core architecture components.
static bool dio_read(dio_tag_t t)
Reads a GPIO logical value.
Definition: pios_dio.h:407
int32_t PIOS_DELAY_WaituS(uint32_t uS)
Definition: pios_delay.c:116
uint8_t instance[]
#define DIO_NULL
Definition: pios_dio.h:86