Fix bug in using nor flash storage without SD
[SCSI2SD.git] / software / SCSI2SD / src / 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 #include "device.h"\r
18 #include "scsi.h"\r
19 #include "scsiPhy.h"\r
20 #include "config.h"\r
21 #include "debug.h"\r
22 #include "disk.h"\r
23 #include "led.h"\r
24 #include "time.h"\r
25 #include "trace.h"\r
26 \r
27 const char* Notice = "Copyright (C) 2015-2021 Michael McMaster <michael@codesrc.com>";\r
28 \r
29 int main()\r
30 {\r
31         timeInit();\r
32         ledInit();\r
33         s2s_deviceEarlyInit();\r
34         traceInit();\r
35 \r
36         // Enable global interrupts.\r
37         // Needed for RST and ATN interrupt handlers.\r
38         CyGlobalIntEnable;\r
39 \r
40         // Set interrupt handlers.\r
41         scsiPhyInit();\r
42 \r
43         configInit(&scsiDev.boardCfg);\r
44         debugInit();\r
45 \r
46         scsiPhyConfig();\r
47 \r
48         scsiInit();\r
49         scsiDiskInit();\r
50 \r
51         // Optional bootup delay\r
52         int delaySeconds = 0;\r
53         while (delaySeconds < scsiDev.boardCfg.startupDelay) {\r
54                 // Keep the USB connection working, otherwise it's very hard to revert\r
55                 // silly extra-long startup delay settings.\r
56                 int i;\r
57                 for (i = 0; i < 200; i++) {\r
58                         CyDelay(5);\r
59                         scsiDev.watchdogTick++;\r
60                         configPoll();\r
61                 }\r
62                 ++delaySeconds;\r
63         }\r
64 \r
65     s2s_deviceInit();\r
66 \r
67         while (1)\r
68         {\r
69                 scsiDev.watchdogTick++;\r
70 \r
71                 scsiPoll();\r
72                 scsiDiskPoll();\r
73                 configPoll();\r
74                 sdPoll();\r
75 \r
76                 if (unlikely(scsiDev.phase == BUS_FREE))\r
77                 {\r
78                         if (s2s_pollMediaChange())\r
79                         {\r
80                                 scsiPhyConfig();\r
81                                 scsiInit();\r
82                         }\r
83             \r
84             // If USB is connected we could be busy transferring data\r
85             // Note: The same flag is used for the config USB interface and\r
86             // therefore SPI flash writes\r
87                         else if (!isDebugEnabled())\r
88                         {\r
89                                 // Wait for our 1ms timer to save some power.\r
90                                 // There's an interrupt on the SEL signal to ensure we respond\r
91                                 // quickly to any SCSI commands. The selection abort time is\r
92                                 // only 250us, and new SCSI-3 controllers time-out very\r
93                                 // not long after that, so we need to ensure we wake up quickly.\r
94                                 uint8_t interruptState = CyEnterCriticalSection();\r
95                                 if (!SCSI_ReadFilt(SCSI_Filt_SEL))\r
96                                 {\r
97                                         __WFI(); // Will wake on interrupt, regardless of mask\r
98                                 }\r
99                                 CyExitCriticalSection(interruptState);\r
100                         }\r
101                 }\r
102                 else if ((scsiDev.phase >= 0) &&\r
103                         scsiDev.target &&\r
104                         (scsiDev.target->device->mediaState & MEDIA_PRESENT))\r
105                 {\r
106                         scsiDev.target->device->pollMediaBusy(scsiDev.target->device);\r
107                 }\r
108         }\r
109         return 0;\r
110 }\r
111 \r