Fix implementation of USB MSC READ FORMAT CAPACITIES command to handle no SD card...
[SCSI2SD-V6.git] / src / firmware / main.c
1 //      Copyright (C) 2014 Michael McMaster <michael@codesrc.com>\r
2 //\r
3 //      This file is part of SCSI2SD.\r
4 //\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
9 //\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
14 //\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
17 \r
18 #ifdef STM32F2xx\r
19 #include "stm32f2xx.h"\r
20 #endif\r
21 \r
22 #ifdef STM32F4xx\r
23 #include "stm32f4xx.h"\r
24 #endif\r
25 \r
26 \r
27 #include "config.h"\r
28 #include "disk.h"\r
29 #include "fpga.h"\r
30 #include "hwversion.h"\r
31 #include "led.h"\r
32 #include "sd.h"\r
33 #include "scsi.h"\r
34 #include "scsiPhy.h"\r
35 #include "time.h"\r
36 #include "sdio.h"\r
37 #include "usb_device/usb_device.h"\r
38 #include "usb_device/usbd_composite.h"\r
39 #include "usb_device/usbd_msc_storage_sd.h"\r
40 \r
41 const char* Notice = "Copyright (C) 2020 Michael McMaster <michael@codesrc.com>";\r
42 uint32_t lastSDPoll;\r
43 \r
44 static int isUsbStarted;\r
45 \r
46 // Note that the chip clocking isn't fully configured at this stage.\r
47 void mainEarlyInit()\r
48 {\r
49 #ifdef nULPI_RESET_GPIO_Port\r
50         // Disable the ULPI chip\r
51         HAL_GPIO_WritePin(nULPI_RESET_GPIO_Port, nULPI_RESET_Pin, GPIO_PIN_RESET);\r
52 #endif\r
53 \r
54         // Sets up function pointers only\r
55         s2s_initUsbDeviceStorage();\r
56 }\r
57 \r
58 void mainInit()\r
59 {\r
60         s2s_timeInit();\r
61         s2s_checkHwVersion();\r
62 \r
63         s2s_ledInit();\r
64         s2s_fpgaInit();\r
65 \r
66         scsiPhyInit();\r
67 \r
68         scsiDiskInit();\r
69         sdInit();\r
70         s2s_configInit(&scsiDev.boardCfg);\r
71         scsiPhyConfig();\r
72         scsiInit();\r
73 \r
74         #ifdef S2S_USB_HS\r
75                 // Enable the ULPI chip\r
76                 HAL_GPIO_WritePin(nULPI_RESET_GPIO_Port, nULPI_RESET_Pin, GPIO_PIN_SET);\r
77                 s2s_delay_ms(5);\r
78         #endif\r
79 \r
80         MX_USB_DEVICE_Init(); // USB lun config now available.\r
81         isUsbStarted = 1;\r
82 \r
83         // Optional bootup delay\r
84         int delaySeconds = 0;\r
85         while (delaySeconds < scsiDev.boardCfg.startupDelay) {\r
86                 // Keep the USB connection working, otherwise it's very hard to revert\r
87                 // silly extra-long startup delay settings.\r
88                 int i;\r
89                 for (i = 0; i < 200; i++) {\r
90                         s2s_delay_ms(5);\r
91                         scsiDev.watchdogTick++;\r
92                         s2s_configPoll();\r
93                 }\r
94                 ++delaySeconds;\r
95         }\r
96 \r
97         lastSDPoll = s2s_getTime_ms();\r
98 }\r
99 \r
100 void mainLoop()\r
101 {\r
102         scsiDev.watchdogTick++;\r
103 \r
104         scsiPoll();\r
105         scsiDiskPoll();\r
106         s2s_configPoll();\r
107 \r
108 #ifdef S2S_USB_FS\r
109         int usbBusy = s2s_usbDevicePoll(&hUsbDeviceFS);\r
110 #endif\r
111 #ifdef S2S_USB_HS\r
112         int usbBusy = s2s_usbDevicePoll(&hUsbDeviceHS);\r
113 #endif\r
114 \r
115 #if 0\r
116         sdPoll();\r
117 #endif\r
118 \r
119     // TODO test if USB transfer is in progress\r
120         if (unlikely(scsiDev.phase == BUS_FREE) && !usbBusy)\r
121         {\r
122                 if (unlikely(s2s_elapsedTime_ms(lastSDPoll) > 200))\r
123                 {\r
124                         lastSDPoll = s2s_getTime_ms();\r
125                         if (sdInit())\r
126                         {\r
127                                 s2s_configInit(&scsiDev.boardCfg);\r
128                                 scsiPhyConfig();\r
129                                 scsiInit();\r
130 \r
131                                 if (isUsbStarted)\r
132                                 {\r
133 #ifdef S2S_USB_FS\r
134                                         USBD_Stop(&hUsbDeviceFS);\r
135                                         s2s_delay_ms(128);\r
136                                         USBD_Start(&hUsbDeviceFS);\r
137 #endif\r
138 #ifdef S2S_USB_HS\r
139                                         USBD_Stop(&hUsbDeviceHS);\r
140                                         s2s_delay_ms(128);\r
141                                         USBD_Start(&hUsbDeviceHS);\r
142 #endif\r
143                                 }\r
144                         }\r
145                 }\r
146         }\r
147         else if (usbBusy || ((scsiDev.phase >= 0) && (blockDev.state & DISK_PRESENT)))\r
148         {\r
149                 // don't waste time scanning SD cards while we're doing disk IO\r
150                 lastSDPoll = s2s_getTime_ms();\r
151         }\r
152 }\r
153 \r