1 // Copyright (C) 2014 Michael McMaster <michael@codesrc.com>
\r
3 // This file is part of SCSI2SD.
\r
5 // SCSI2SD is free software: you can redistribute it and/or modify
\r
6 // it under the terms of the GNU General Public License as published by
\r
7 // the Free Software Foundation, either version 3 of the License, or
\r
8 // (at your option) any later version.
\r
10 // SCSI2SD is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
\r
18 #include "stm32f2xx.h"
\r
26 #include "scsiPhy.h"
\r
29 #include "usb_device/usb_device.h"
\r
30 #include "usb_device/usbd_composite.h"
\r
31 #include "usb_device/usbd_msc_storage_sd.h"
\r
34 const char* Notice = "Copyright (C) 2016 Michael McMaster <michael@codesrc.com>";
\r
35 uint32_t lastSDPoll;
\r
37 void mainEarlyInit()
\r
39 // USB device is initialised before mainInit is called
\r
40 s2s_initUsbDeviceStorage();
\r
54 s2s_configInit(&scsiDev.boardCfg);
\r
61 MX_USB_DEVICE_Init(); // USB lun config now available.
\r
63 // Optional bootup delay
\r
64 int delaySeconds = 0;
\r
65 while (delaySeconds < scsiDev.boardCfg.startupDelay) {
\r
66 // Keep the USB connection working, otherwise it's very hard to revert
\r
67 // silly extra-long startup delay settings.
\r
69 for (i = 0; i < 200; i++) {
\r
71 scsiDev.watchdogTick++;
\r
77 lastSDPoll = s2s_getTime_ms();
\r
82 scsiDev.watchdogTick++;
\r
87 s2s_usbDevicePoll();
\r
93 if (unlikely(scsiDev.phase == BUS_FREE))
\r
95 if (unlikely(s2s_elapsedTime_ms(lastSDPoll) > 200))
\r
97 lastSDPoll = s2s_getTime_ms();
\r
100 s2s_configInit(&scsiDev.boardCfg);
\r
105 USBD_Stop(&hUsbDeviceFS);
\r
107 USBD_Start(&hUsbDeviceFS);
\r
113 // Wait for our 1ms timer to save some power.
\r
114 // There's an interrupt on the SEL signal to ensure we respond
\r
115 // quickly to any SCSI commands. The selection abort time is
\r
116 // only 250us, and new SCSI-3 controllers time-out very
\r
117 // not long after that, so we need to ensure we wake up quickly.
\r
118 uint8_t interruptState = CyEnterCriticalSection();
\r
119 if (!SCSI_ReadFilt(SCSI_Filt_SEL))
\r
121 __WFI(); // Will wake on interrupt, regardless of mask
\r
123 CyExitCriticalSection(interruptState);
\r
127 else if (scsiDev.phase >= 0)
\r
129 // don't waste time scanning SD cards while we're doing disk IO
\r
130 lastSDPoll = s2s_getTime_ms();
\r