[SITL] Enable telemetry: LTM and MAVLink (#8940)
[inav.git] / src / main / drivers / usb_msc_at32f43x.c
blobfbeef809b839248543c810064de4f31393a56432
1 /*
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)
8 * any later version.
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/>.
22 * Author: Chris Hockuba (https://github.com/conkerkh)
26 #include <stdint.h>
27 #include <stdbool.h>
28 #include <string.h>
30 #include "platform.h"
32 #if defined(USE_USB_MSC)
34 #include "build/build_config.h"
36 #include "common/utils.h"
38 #include "blackbox/blackbox.h"
39 #include "blackbox/blackbox_io.h"
41 #include "drivers/io.h"
42 #include "drivers/light_led.h"
43 #include "drivers/nvic.h"
44 #include "drivers/persistent.h"
45 #include "drivers/sdcard/sdmmc_sdio.h"
46 #include "drivers/time.h"
47 #include "drivers/usb_msc.h"
49 #include "usb_conf.h"
50 #include "usb_core.h"
51 #include "usbd_int.h"
52 #include "msc_class.h"
53 #include "msc_desc.h"
54 #include "usb_io.h"
56 #define DEBOUNCE_TIME_MS 20
58 extern otg_core_type otg_core_struct;
61 #if defined(MSC_USE_BUTTON)
62 static IO_t mscButton;
63 #endif
65 void mscInit(void)
67 #if defined(MSC_USE_BUTTON)
68 if (usbDevConfig()->mscButtonPin) {
69 mscButton = IOGetByTag(usbDevConfig()->mscButtonPin);
70 IOInit(mscButton, OWNER_USB_MSC_PIN, 0);
71 if (usbDevConfig()->mscButtonUsePullup) {
72 IOConfigGPIO(mscButton, IOCFG_IPU);
73 } else {
74 IOConfigGPIO(mscButton, IOCFG_IPD);
77 #endif
81 /**
82 * @brief this function config gpio.
83 * @param none
84 * @retval none
86 void msc_usb_gpio_config(void)
88 gpio_init_type gpio_init_struct;
90 crm_periph_clock_enable(OTG_PIN_GPIO_CLOCK, TRUE);
91 gpio_default_para_init(&gpio_init_struct);
93 gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
94 gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
95 gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
96 gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
98 /* dp and dm */
99 gpio_init_struct.gpio_pins = OTG_PIN_DP | OTG_PIN_DM;
100 gpio_init(OTG_PIN_GPIO, &gpio_init_struct);
102 gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_DP_SOURCE, OTG_PIN_MUX);
103 gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_DM_SOURCE, OTG_PIN_MUX);
105 #ifdef USB_SOF_OUTPUT_ENABLE
106 crm_periph_clock_enable(OTG_PIN_SOF_GPIO_CLOCK, TRUE);
107 gpio_init_struct.gpio_pins = OTG_PIN_SOF;
108 gpio_init(OTG_PIN_SOF_GPIO, &gpio_init_struct);
109 gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_SOF_SOURCE, OTG_PIN_MUX);
110 #endif
112 /* otgfs use vbus pin */
113 #ifndef USB_VBUS_IGNORE
114 gpio_init_struct.gpio_pins = OTG_PIN_VBUS;
115 gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
116 gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_VBUS_SOURCE, OTG_PIN_MUX);
117 gpio_init(OTG_PIN_GPIO, &gpio_init_struct);
118 #endif
124 * @brief usb 48M clock select
125 * @param clk_s:USB_CLK_HICK, USB_CLK_HEXT
126 * @retval none
128 void msc_usb_clock48m_select(usb_clk48_s clk_s)
130 if(clk_s == USB_CLK_HICK)
132 crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_HICK);
134 /* enable the acc calibration ready interrupt */
135 crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, TRUE);
137 /* update the c1\c2\c3 value */
138 acc_write_c1(7980);
139 acc_write_c2(8000);
140 acc_write_c3(8020);
141 #if (USB_ID == 0)
142 acc_sof_select(ACC_SOF_OTG1);
143 #else
144 acc_sof_select(ACC_SOF_OTG2);
145 #endif
146 /* open acc calibration */
147 acc_calibration_mode_enable(ACC_CAL_HICKTRIM, TRUE);
149 else
151 switch(system_core_clock)
153 /* 48MHz */
154 case 48000000:
155 crm_usb_clock_div_set(CRM_USB_DIV_1);
156 break;
158 /* 72MHz */
159 case 72000000:
160 crm_usb_clock_div_set(CRM_USB_DIV_1_5);
161 break;
163 /* 96MHz */
164 case 96000000:
165 crm_usb_clock_div_set(CRM_USB_DIV_2);
166 break;
168 /* 120MHz */
169 case 120000000:
170 crm_usb_clock_div_set(CRM_USB_DIV_2_5);
171 break;
173 /* 144MHz */
174 case 144000000:
175 crm_usb_clock_div_set(CRM_USB_DIV_3);
176 break;
178 /* 168MHz */
179 case 168000000:
180 crm_usb_clock_div_set(CRM_USB_DIV_3_5);
181 break;
183 /* 192MHz */
184 case 192000000:
185 crm_usb_clock_div_set(CRM_USB_DIV_4);
186 break;
188 /* 216MHz */
189 case 216000000:
190 crm_usb_clock_div_set(CRM_USB_DIV_4_5);
191 break;
193 /* 240MHz */
194 case 240000000:
195 crm_usb_clock_div_set(CRM_USB_DIV_5);
196 break;
198 /* 264MHz */
199 case 264000000:
200 crm_usb_clock_div_set(CRM_USB_DIV_5_5);
201 break;
203 /* 288MHz */
204 case 288000000:
205 crm_usb_clock_div_set(CRM_USB_DIV_6);
206 break;
208 default:
209 break;
216 uint8_t mscStart(void)
218 ledInit(false);
220 // Start USB
221 usbGenerateDisconnectPulse();
223 IOInit(IOGetByTag(IO_TAG(PA11)), OWNER_USB, 0, 0);
224 IOInit(IOGetByTag(IO_TAG(PA12)), OWNER_USB, 0, 0);
226 // The SD card is not supported
227 /* switch (blackboxConfig()->device) {
228 #ifdef USE_SDCARD
229 case BLACKBOX_DEVICE_SDCARD:
230 USBD_STORAGE_fops = &USBD_MSC_MICRO_SDIO_fops;
231 break;
232 #endif
234 #ifdef USE_FLASHFS
235 case BLACKBOX_DEVICE_FLASH:
236 USBD_STORAGE_fops = &USBD_MSC_EMFAT_fops;
237 break;
238 #endif
239 default:
240 return 1;
244 /* init usb */
245 /* usb gpio config */
246 msc_usb_gpio_config();
248 /* enable otgfs clock */
249 crm_periph_clock_enable(OTG_CLOCK, TRUE);
251 /* select usb 48m clcok source */
252 msc_usb_clock48m_select(USB_CLK_HEXT);
254 /* enable otgfs irq,Priority NVIC_PRIO_USB must be used */
255 nvic_irq_enable(OTG_IRQ, NVIC_PRIO_USB, 0);
257 usbd_init(&otg_core_struct,
258 USB_FULL_SPEED_CORE_ID,
259 USB_ID,
260 &msc_class_handler,
261 &msc_desc_handler);
263 // NVIC configuration for SYSTick
264 nvic_irq_disable(SysTick_IRQn);
266 nvic_irq_enable(SysTick_IRQn, 0, 0);
267 return 0;
270 bool mscCheckButton(void)
272 bool result = false;
273 #if defined(MSC_USE_BUTTON)
274 if (mscButton) {
275 uint8_t state = IORead(mscButton);
276 if (usbDevConfig()->mscButtonUsePullup) {
277 result = state == 0;
278 } else {
279 result = state == 1;
282 #endif
283 return result;
286 void mscWaitForButton(void)
288 // In order to exit MSC mode simply disconnect the board, or push the button again.
289 while (mscCheckButton());
290 delay(DEBOUNCE_TIME_MS);
291 while (true) {
292 asm("NOP");
293 if (mscCheckButton()) {
294 delay(1);
295 NVIC_SystemReset();
299 #endif