Synch transfer fix
[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 #include "stm32f2xx.h"\r
19 \r
20 #include "config.h"\r
21 #include "bsp.h"\r
22 #include "disk.h"\r
23 #include "fpga.h"\r
24 #include "led.h"\r
25 #include "sd.h"\r
26 #include "scsi.h"\r
27 #include "scsiPhy.h"\r
28 #include "time.h"\r
29 #include "trace.h"\r
30 #include "sdio.h"\r
31 #include "usb_device/usb_device.h"\r
32 #include "usb_device/usbd_composite.h"\r
33 #include "usb_device/usbd_msc_storage_sd.h"\r
34 \r
35 \r
36 const char* Notice = "Copyright (C) 2016 Michael McMaster <michael@codesrc.com>";\r
37 uint32_t lastSDPoll;\r
38 \r
39 static int isUsbStarted;\r
40 \r
41 void mainEarlyInit()\r
42 {\r
43         // USB device is initialised before mainInit is called\r
44         s2s_initUsbDeviceStorage();\r
45 }\r
46 \r
47 void mainInit()\r
48 {\r
49         traceInit();\r
50         s2s_timeInit();\r
51         s2s_ledInit();\r
52         s2s_fpgaInit();\r
53 \r
54         scsiPhyInit();\r
55 \r
56         scsiDiskInit();\r
57         sdInit();\r
58         s2s_configInit(&scsiDev.boardCfg);\r
59         scsiPhyConfig();\r
60         scsiInit();\r
61 \r
62         MX_USB_DEVICE_Init(); // USB lun config now available.\r
63         isUsbStarted = 1;\r
64 \r
65         // Optional bootup delay\r
66         int delaySeconds = 0;\r
67         while (delaySeconds < scsiDev.boardCfg.startupDelay) {\r
68                 // Keep the USB connection working, otherwise it's very hard to revert\r
69                 // silly extra-long startup delay settings.\r
70                 int i;\r
71                 for (i = 0; i < 200; i++) {\r
72                         s2s_delay_ms(5);\r
73                         scsiDev.watchdogTick++;\r
74                         s2s_configPoll();\r
75                 }\r
76                 ++delaySeconds;\r
77         }\r
78 \r
79         lastSDPoll = s2s_getTime_ms();\r
80 }\r
81 \r
82 void mainLoop()\r
83 {\r
84         scsiDev.watchdogTick++;\r
85 \r
86         scsiPoll();\r
87         scsiDiskPoll();\r
88         s2s_configPoll();\r
89         s2s_usbDevicePoll();\r
90 \r
91 #if 0\r
92         sdPoll();\r
93 #endif\r
94 \r
95         if (unlikely(scsiDev.phase == BUS_FREE))\r
96         {\r
97                 if (unlikely(s2s_elapsedTime_ms(lastSDPoll) > 200))\r
98                 {\r
99                         lastSDPoll = s2s_getTime_ms();\r
100                         if (sdInit())\r
101                         {\r
102                                 s2s_configInit(&scsiDev.boardCfg);\r
103                                 scsiPhyConfig();\r
104                                 scsiInit();\r
105 \r
106                                 // Is a USB host connected ?\r
107                                 if (isUsbStarted)\r
108                                 {\r
109                                         USBD_Stop(&hUsbDeviceFS);\r
110                                         s2s_delay_ms(128);\r
111                                         USBD_Start(&hUsbDeviceFS);\r
112                                 }\r
113                         }\r
114 \r
115                         // Can we speed up the SD card ?\r
116                         // Don't combine with the above block because that won't\r
117                         // run if the SD card is present at startup.\r
118                         // Don't use VBUS monitoring because that just tells us about\r
119                         // power, which could be from a charger\r
120 #if 0\r
121                         if ((blockDev.state & DISK_PRESENT) &&\r
122                                 isUsbStarted &&\r
123                                 (scsiDev.cmdCount > 0) && // no need for speed without scsi\r
124                                 !USBD_Composite_IsConfigured(&hUsbDeviceFS))\r
125                         {\r
126                                 if (HAL_SD_HighSpeed(&hsd) == SD_OK)\r
127                                 {\r
128                                         USBD_Stop(&hUsbDeviceFS);\r
129                                         s2s_setFastClock();\r
130                                         isUsbStarted = 0;\r
131                                 }\r
132                         }\r
133 #endif\r
134 \r
135                         else if (!(blockDev.state & DISK_PRESENT) && !isUsbStarted)\r
136                         {\r
137                                 // Good time to restart USB.\r
138                                 s2s_setNormalClock();\r
139                                 USBD_Start(&hUsbDeviceFS);\r
140                                 isUsbStarted = 1;\r
141                         }\r
142                 }\r
143                 else\r
144                 {\r
145                         // TODO this hurts performance significantly! Work out why __WFI()\r
146                         // doesn't wake up immediately !\r
147 #if 0\r
148                         // Wait for our 1ms timer to save some power.\r
149                         // There's an interrupt on the SEL signal to ensure we respond\r
150                         // quickly to any SCSI commands. The selection abort time is\r
151                         // only 250us, and new SCSI-3 controllers time-out very\r
152                         // not long after that, so we need to ensure we wake up quickly.\r
153                         uint32_t interruptState = __get_PRIMASK();\r
154                         __disable_irq();\r
155 \r
156                         if (!*SCSI_STS_SELECTED)\r
157                         {\r
158                                 //__WFI(); // Will wake on interrupt, regardless of mask\r
159                         }\r
160                         if (!interruptState)\r
161                         {\r
162                                 __enable_irq();\r
163                         }\r
164 #endif\r
165                 }\r
166         }\r
167         else if (scsiDev.phase >= 0)\r
168         {\r
169                 // don't waste time scanning SD cards while we're doing disk IO\r
170                 lastSDPoll = s2s_getTime_ms();\r
171         }\r
172 }\r
173 \r