Read performance improvements
[SCSI2SD-V6.git] / software / SCSI2SD / SCSI2SD.cydsn / loopback.c
1 //      Copyright (C) 2013 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 "loopback.h"\r
19 #include "scsi.h"\r
20 #include "device.h"\r
21 #include "scsiPhy.h"\r
22 \r
23 // Return true if all inputs are un-asserted (1)\r
24 // Note that CyPins returns non-zero if pin is active. It does NOT\r
25 // necessarily return 1.\r
26 static int test_initial_inputs(void)\r
27 {\r
28         uint8 dbx = scsiReadDBxPins();\r
29         int result =\r
30                 (dbx == 0xFF) &&\r
31                 CyPins_ReadPin(SCSI_In_DBP) &&\r
32                 CyPins_ReadPin(SCSI_ATN_INT) &&\r
33                 CyPins_ReadPin(SCSI_In_BSY)     &&\r
34                 CyPins_ReadPin(SCSI_In_ACK) &&\r
35                 CyPins_ReadPin(SCSI_RST_INT) &&\r
36                 CyPins_ReadPin(SCSI_In_MSG) &&\r
37                 CyPins_ReadPin(SCSI_In_SEL) &&\r
38                 CyPins_ReadPin(SCSI_In_CD) &&\r
39                 CyPins_ReadPin(SCSI_In_REQ) &&\r
40                 CyPins_ReadPin(SCSI_In_IO);\r
41 \r
42         return result;\r
43 }\r
44 \r
45 /* Not currently possible to write directly to the output pins\r
46 static int test_data_lines(void)\r
47 {\r
48         int result = 1;\r
49         int i;\r
50         for (i = 0; i < 8; ++i)\r
51         {\r
52                 // We write using Active High\r
53                 SCSI_Out_DBx_Write(1 << i);\r
54                 CyDelay(1); // ms\r
55                 \r
56                 // And expect an Active Low response.\r
57                 uint8 dbx = SCSI_In_DBx_Read();\r
58                 result = result && (dbx == (0xFF ^ (1 << i)));\r
59         }\r
60         SCSI_Out_DBx_Write(0);\r
61         return result;\r
62 }\r
63 */\r
64 \r
65 static int test_data_10MHz(void)\r
66 {\r
67         // 10MHz = 100ns period.\r
68         // We'll try and go high -> low -> high in 100ns.\r
69         // At 66MHz, 50ns ~= 3 cycles.\r
70         \r
71         int result = 1;\r
72         int i;\r
73         for (i = 0; i < 100; ++i)\r
74         {\r
75                 uint8 dbx;\r
76                 // We write using Active High\r
77                 SCSI_Out_DBx_Write(0xFF);\r
78                 CyDelayCycles(3);\r
79                 // And expect an Active Low response.\r
80                 dbx = SCSI_In_DBx_Read();\r
81                 result = result && (dbx == 0);\r
82                 \r
83                 // We write using Active High\r
84                 SCSI_Out_DBx_Write(0);\r
85                 CyDelayCycles(3);\r
86                 // And expect an Active Low response.\r
87                 dbx = SCSI_In_DBx_Read();\r
88                 result = result && (dbx == 0xFF);\r
89         }\r
90         SCSI_Out_DBx_Write(0);\r
91         return result;\r
92 }\r
93 \r
94 static int test_ATN_interrupt(void)\r
95 {\r
96         int result = 1;\r
97         int i;\r
98         \r
99         scsiDev.atnFlag = 0;\r
100         for (i = 0; i < 100 && result; ++i)\r
101         {\r
102                 // We write using Active High\r
103                 CyPins_SetPin(SCSI_Out_ATN);\r
104                 CyDelayCycles(2);\r
105                 result &= scsiDev.atnFlag == 1;\r
106                 scsiDev.atnFlag = 0;\r
107                 CyPins_ClearPin(SCSI_Out_ATN);\r
108                 result &= scsiDev.atnFlag == 0;\r
109         }\r
110         return result;\r
111 }\r
112 \r
113 static void test_error(void)\r
114 {\r
115         // Toggle LED.\r
116         while (1)\r
117         {\r
118                 LED1_Write(0);\r
119                 CyDelay(250); // ms\r
120                 LED1_Write(1);\r
121                 CyDelay(250); // ms\r
122         }\r
123 }\r
124 \r
125 static void test_success(void)\r
126 {\r
127         // Toggle LED.\r
128         while (1)\r
129         {\r
130                 LED1_Write(0);\r
131                 CyDelay(1000); // ms\r
132                 LED1_Write(1);\r
133                 CyDelay(1000); // ms\r
134         }\r
135 }\r
136 void scsi2sd_test_loopback(void)\r
137 {\r
138         if (!test_initial_inputs() ||\r
139                 //!test_data_lines() ||\r
140                 !test_data_10MHz() ||\r
141                 !test_ATN_interrupt())\r
142         {\r
143                 test_error();\r
144         }\r
145         else\r
146         {\r
147                 test_success();\r
148         }\r
149 }\r