Updated firmware for PCB Revision 3.0
[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                 // We write using Active High\r
76                 SCSI_Out_DBx_Write(0xFF);\r
77                 CyDelayCycles(3);\r
78                 // And expect an Active Low response.\r
79                 uint8 dbx = SCSI_In_DBx_Read();\r
80                 result = result && (dbx == 0);\r
81                 \r
82                 // We write using Active High\r
83                 SCSI_Out_DBx_Write(0);\r
84                 CyDelayCycles(3);\r
85                 // And expect an Active Low response.\r
86                 dbx = SCSI_In_DBx_Read();\r
87                 result = result && (dbx == 0xFF);\r
88         }\r
89         SCSI_Out_DBx_Write(0);\r
90         return result;\r
91 }\r
92 \r
93 static int test_ATN_interrupt(void)\r
94 {\r
95         int result = 1;\r
96         int i;\r
97         \r
98         scsiDev.atnFlag = 0;\r
99         for (i = 0; i < 100 && result; ++i)\r
100         {\r
101                 // We write using Active High\r
102                 CyPins_SetPin(SCSI_Out_ATN);\r
103                 CyDelayCycles(2);\r
104                 result &= scsiDev.atnFlag == 1;\r
105                 scsiDev.atnFlag = 0;\r
106                 CyPins_ClearPin(SCSI_Out_ATN);\r
107                 result &= scsiDev.atnFlag == 0;\r
108         }\r
109         return result;\r
110 }\r
111 \r
112 static void test_error(void)\r
113 {\r
114         // Toggle LED.\r
115         while (1)\r
116         {\r
117                 LED1_Write(0);\r
118                 CyDelay(250); // ms\r
119                 LED1_Write(1);\r
120                 CyDelay(250); // ms\r
121         }\r
122 }\r
123 \r
124 static void test_success(void)\r
125 {\r
126         // Toggle LED.\r
127         while (1)\r
128         {\r
129                 LED1_Write(0);\r
130                 CyDelay(1000); // ms\r
131                 LED1_Write(1);\r
132                 CyDelay(1000); // ms\r
133         }\r
134 }\r
135 void scsi2sd_test_loopback(void)\r
136 {\r
137         if (!test_initial_inputs() ||\r
138                 //!test_data_lines() ||\r
139                 !test_data_10MHz() ||\r
140                 !test_ATN_interrupt())\r
141         {\r
142                 test_error();\r
143         }\r
144         else\r
145         {\r
146                 test_success();\r
147         }\r
148 }