Improved async noise model that considers all 9 dbx signals.
[SCSI2SD-V6.git] / src / firmware / scsiPhy.c
1 // Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
2 //
3 // This file is part of SCSI2SD.
4 //
5 // SCSI2SD is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // SCSI2SD is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
17
18 #include "stm32f2xx.h"
19 #include "stm32f2xx_hal.h"
20 #include "stm32f2xx_hal_dma.h"
21
22 #include "scsi.h"
23 #include "scsiPhy.h"
24 #include "time.h"
25 #include "fpga.h"
26 #include "led.h"
27
28 #include <string.h>
29
30 static uint8_t asyncTimings[][4] =
31 {
32 /* Speed, Assert, Deskew, Hold, Glitch */
33 {/*1.5MB/s*/ 28, 18, 13, 6},
34 {/*3.3MB/s*/ 13, 6, 6, 6},
35 {/*5MB/s*/ 9, 6, 6, 6}, // 80ns
36 {/*safe*/ 3, 6, 6, 6}, // Probably safe
37 {/*turbo*/ 3, 3, 3, 2}
38 };
39
40 #define SCSI_ASYNC_15 0
41 #define SCSI_ASYNC_33 1
42 #define SCSI_ASYNC_50 2
43 #define SCSI_ASYNC_SAFE 3
44 #define SCSI_ASYNC_TURBO 4
45
46 // 5MB/s synchronous timing
47 #define SCSI_FAST5_DESKEW 6 // 55ns
48 #define SCSI_FAST5_HOLD 6 // 53ns
49
50 // 10MB/s synchronous timing
51 // 2:0 Deskew count, 25ns
52 // 6:4 Hold count, 33ns
53 // 3:0 Assertion count, 30ns
54 // We want deskew + hold + assert + 3 to add up to 11 clocks
55 // the fpga code has 1 clock of overhead when transitioning from deskew to
56 // assert to hold
57
58 #define SCSI_FAST10_DESKEW 2 // 25ns
59 #define SCSI_FAST10_HOLD 3 // 33ns
60 #define SCSI_FAST10_WRITE_ASSERT 3 // 30ns. Overall clocks only works if fpga overhead is 3.
61
62 // Slow down the cycle to be valid. 2x assert period is TOO FAST when
63 // reading data. It's ok when writing due to the deskew.
64 // 50ns. ie. 100ns / 2. Rounded down because there's likely a few extra cycles
65 // here and there.
66 #define SCSI_FAST10_READ_ASSERT 5
67
68 // Fastest possible timing, probably not 20MB/s
69 #define SCSI_FAST20_DESKEW 1
70 #define SCSI_FAST20_HOLD 2
71 #define SCSI_FAST20_ASSERT 2
72
73
74 #define syncDeskew(period) ((period) < 35 ? \
75 SCSI_FAST10_DESKEW : SCSI_FAST5_DESKEW)
76
77 #define syncHold(period) ((period) < 35 ? \
78 ((period) == 25 ? SCSI_FAST10_HOLD : 4) /* 25ns/33ns */\
79 : SCSI_FAST5_HOLD)
80
81
82 // Number of overhead cycles per period.
83 #define FPGA_OVERHEAD 2
84 #define FPGA_CYCLES_PER_NS 9
85 #define SCSI_PERIOD_CLKS(period) ((((int)period * 4) + (FPGA_CYCLES_PER_NS/2)) / FPGA_CYCLES_PER_NS)
86
87 // 3.125MB/s (80 period) to < 10MB/s sync
88 // Assumes a 108MHz fpga clock. (9 ns)
89 // 3:0 Assertion count, variable
90 #define syncAssertionWrite(period,deskew) ((SCSI_PERIOD_CLKS(period) - deskew - FPGA_OVERHEAD + 1) / 2)
91 #define syncAssertionRead(period) syncAssertionWrite(period,0)
92
93
94 // Time until we consider ourselves selected
95 // 400ns at 108MHz
96 #define SCSI_DEFAULT_SELECTION 43
97 #define SCSI_FAST_SELECTION 5
98
99 // Private DMA variables.
100 static int dmaInProgress = 0;
101
102 static DMA_HandleTypeDef memToFSMC;
103 static DMA_HandleTypeDef fsmcToMem;
104
105
106 volatile uint8_t scsiRxDMAComplete;
107 volatile uint8_t scsiTxDMAComplete;
108
109 uint8_t scsiPhyFifoSel = 0; // global
110
111 // scsi IRQ handler is initialised by the STM32 HAL. Connected to
112 // PE4
113 // Note: naming is important to ensure this function is listed in the
114 // vector table.
115 void EXTI4_IRQHandler()
116 {
117 // Make sure that interrupt flag is set
118 if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_4) != RESET) {
119
120 // Clear interrupt flag
121 __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_4);
122
123 scsiDev.resetFlag = scsiDev.resetFlag || scsiStatusRST();
124
125 // selFlag is required for Philips P2000C which releases it after 600ns
126 // without waiting for BSY.
127 // Also required for some early Mac Plus roms
128 scsiDev.selFlag = *SCSI_STS_SELECTED;
129 }
130
131 __SEV(); // Set event. See corresponding __WFE() calls.
132 }
133
134 static void assertFail()
135 {
136 while (1)
137 {
138 s2s_ledOn();
139 s2s_delay_ms(100);
140 s2s_ledOff();
141 s2s_delay_ms(100);
142 }
143 }
144
145 void
146 scsiSetDataCount(uint32_t count)
147 {
148 *SCSI_DATA_CNT_HI = count >> 8;
149 *SCSI_DATA_CNT_LO = count & 0xff;
150 *SCSI_DATA_CNT_SET = 1;
151 }
152
153 uint8_t
154 scsiReadByte(void)
155 {
156 #if FIFODEBUG
157 if (!scsiPhyFifoAltEmpty()) {
158 // Force a lock-up.
159 assertFail();
160 }
161 #endif
162 scsiSetDataCount(1);
163
164 while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))
165 {
166 __WFE(); // Wait for event
167 }
168 scsiPhyFifoFlip();
169 uint8_t val = scsiPhyRx();
170 // TODO scsiDev.parityError = scsiDev.parityError || SCSI_Parity_Error_Read();
171
172 #if FIFODEBUG
173 if (!scsiPhyFifoEmpty()) {
174 int j = 0;
175 uint8_t k __attribute((unused));
176 while (!scsiPhyFifoEmpty()) { k = scsiPhyRx(); ++j; }
177
178 // Force a lock-up.
179 assertFail();
180 }
181 #endif
182 return val;
183 }
184
185
186 void
187 scsiReadPIO(uint8_t* data, uint32_t count)
188 {
189 uint16_t* fifoData = (uint16_t*)data;
190
191 for (int i = 0; i < (count + 1) / 2; ++i)
192 {
193 fifoData[i] = scsiPhyRx(); // TODO ASSUMES LITTLE ENDIAN
194 }
195 }
196
197 void
198 scsiReadDMA(uint8_t* data, uint32_t count)
199 {
200 // Prepare DMA transfer
201 dmaInProgress = 1;
202
203 scsiTxDMAComplete = 1; // TODO not used much
204 scsiRxDMAComplete = 0; // TODO not used much
205
206 HAL_DMA_Start(
207 &fsmcToMem,
208 (uint32_t) SCSI_FIFO_DATA,
209 (uint32_t) data,
210 (count + 1) / 2);
211 }
212
213 int
214 scsiReadDMAPoll()
215 {
216 int complete = __HAL_DMA_GET_COUNTER(&fsmcToMem) == 0;
217 complete = complete && (HAL_DMA_PollForTransfer(&fsmcToMem, HAL_DMA_FULL_TRANSFER, 0xffffffff) == HAL_OK);
218 if (complete)
219 {
220 scsiTxDMAComplete = 1; // TODO MM FIX IRQ
221 scsiRxDMAComplete = 1;
222
223 dmaInProgress = 0;
224 #if 0
225 // TODO MM scsiDev.parityError = scsiDev.parityError || SCSI_Parity_Error_Read();
226 #endif
227 return 1;
228
229 }
230 else
231 {
232 return 0;
233 }
234 }
235
236 void
237 scsiRead(uint8_t* data, uint32_t count, int* parityError)
238 {
239 int i = 0;
240 *parityError = 0;
241
242
243 uint32_t chunk = ((count - i) > SCSI_FIFO_DEPTH)
244 ? SCSI_FIFO_DEPTH : (count - i);
245 #ifdef SCSI_FSMC_DMA
246 if (chunk >= 16)
247 {
248 // DMA is doing 32bit transfers.
249 chunk = chunk & 0xFFFFFFF8;
250 }
251 #endif
252 scsiSetDataCount(chunk);
253
254 while (i < count && likely(!scsiDev.resetFlag))
255 {
256 while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))
257 {
258 __WFE(); // Wait for event
259 }
260 *parityError |= scsiParityError();
261 scsiPhyFifoFlip();
262
263 uint32_t nextChunk = ((count - i - chunk) > SCSI_FIFO_DEPTH)
264 ? SCSI_FIFO_DEPTH : (count - i - chunk);
265 #ifdef SCSI_FSMC_DMA
266 if (nextChunk >= 16)
267 {
268 nextChunk = nextChunk & 0xFFFFFFF8;
269 }
270 #endif
271 if (nextChunk > 0)
272 {
273 scsiSetDataCount(nextChunk);
274 }
275
276 #ifdef SCSI_FSMC_DMA
277 if (chunk < 16)
278 #endif
279 {
280 scsiReadPIO(data + i, chunk);
281 }
282 #ifdef SCSI_FSMC_DMA
283 else
284 {
285 scsiReadDMA(data + i, chunk);
286
287 while (!scsiReadDMAPoll() && likely(!scsiDev.resetFlag))
288 {
289 };
290 }
291 #endif
292
293
294 i += chunk;
295 chunk = nextChunk;
296 }
297 #if FIFODEBUG
298 if (!scsiPhyFifoEmpty() || !scsiPhyFifoAltEmpty()) {
299 int j = 0;
300 while (!scsiPhyFifoEmpty()) { scsiPhyRx(); ++j; }
301 scsiPhyFifoFlip();
302 int k = 0;
303 while (!scsiPhyFifoEmpty()) { scsiPhyRx(); ++k; }
304 // Force a lock-up.
305 assertFail();
306 }
307 #endif
308 }
309
310 void
311 scsiWriteByte(uint8_t value)
312 {
313 #if FIFODEBUG
314 if (!scsiPhyFifoEmpty()) {
315 // Force a lock-up.
316 assertFail();
317 }
318 #endif
319 scsiPhyTx(value);
320 scsiPhyFifoFlip();
321
322 scsiSetDataCount(1);
323
324 while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))
325 {
326 __WFE(); // Wait for event
327 }
328
329 #if FIFODEBUG
330 if (!scsiPhyFifoAltEmpty()) {
331 // Force a lock-up.
332 assertFail();
333 }
334 #endif
335 }
336
337 static void
338 scsiWritePIO(const uint8_t* data, uint32_t count)
339 {
340 uint16_t* fifoData = (uint16_t*)data;
341 for (int i = 0; i < (count + 1) / 2; ++i)
342 {
343 scsiPhyTx(fifoData[i]);
344 }
345 }
346
347 void
348 scsiWriteDMA(const uint8_t* data, uint32_t count)
349 {
350 // Prepare DMA transfer
351 dmaInProgress = 1;
352
353 scsiTxDMAComplete = 0;
354 scsiRxDMAComplete = 1;
355
356 HAL_DMA_Start(
357 &memToFSMC,
358 (uint32_t) data,
359 (uint32_t) SCSI_FIFO_DATA,
360 count / 4);
361 }
362
363 int
364 scsiWriteDMAPoll()
365 {
366 int complete = __HAL_DMA_GET_COUNTER(&memToFSMC) == 0;
367 complete = complete && (HAL_DMA_PollForTransfer(&memToFSMC, HAL_DMA_FULL_TRANSFER, 0xffffffff) == HAL_OK);
368 if (complete)
369 {
370 scsiTxDMAComplete = 1; // TODO MM FIX IRQ
371 scsiRxDMAComplete = 1;
372
373 dmaInProgress = 0;
374 return 1;
375 }
376 else
377 {
378 return 0;
379 }
380 }
381
382 void
383 scsiWrite(const uint8_t* data, uint32_t count)
384 {
385 int i = 0;
386 while (i < count && likely(!scsiDev.resetFlag))
387 {
388 uint32_t chunk = ((count - i) > SCSI_FIFO_DEPTH)
389 ? SCSI_FIFO_DEPTH : (count - i);
390
391 #if FIFODEBUG
392 if (!scsiPhyFifoEmpty()) {
393 // Force a lock-up.
394 assertFail();
395 }
396 #endif
397
398 #ifdef SCSI_FSMC_DMA
399 if (chunk < 16)
400 #endif
401 {
402 scsiWritePIO(data + i, chunk);
403 }
404 #ifdef SCSI_FSMC_DMA
405 else
406 {
407 // DMA is doing 32bit transfers.
408 chunk = chunk & 0xFFFFFFF8;
409 scsiWriteDMA(data + i, chunk);
410
411 while (!scsiWriteDMAPoll() && likely(!scsiDev.resetFlag))
412 {
413 }
414 }
415 #endif
416
417 while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))
418 {
419 __WFE(); // Wait for event
420 }
421
422 #if FIFODEBUG
423 if (!scsiPhyFifoAltEmpty()) {
424 // Force a lock-up.
425 assertFail();
426 }
427 #endif
428
429 scsiPhyFifoFlip();
430 scsiSetDataCount(chunk);
431 i += chunk;
432 }
433 while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))
434 {
435 __WFE(); // Wait for event
436 }
437
438 #if FIFODEBUG
439 if (!scsiPhyFifoAltEmpty()) {
440 // Force a lock-up.
441 assertFail();
442 }
443 #endif
444 }
445
446 static inline void busSettleDelay(void)
447 {
448 // Data Release time (switching IO) = 400ns
449 // + Bus Settle time (switching phase) = 400ns.
450 s2s_delay_us(1); // Close enough.
451 }
452
453 void scsiEnterBusFree()
454 {
455 *SCSI_CTRL_BSY = 0x00;
456 // We now have a Bus Clear Delay of 800ns to release remaining signals.
457 *SCSI_CTRL_PHASE = 0;
458 }
459
460 static void
461 scsiSetTiming(
462 uint8_t assertClocks,
463 uint8_t deskew,
464 uint8_t hold,
465 uint8_t glitch)
466 {
467 *SCSI_CTRL_DESKEW = ((hold & 7) << 5) | (deskew & 0x1F);
468 *SCSI_CTRL_TIMING = (assertClocks & 0x3F);
469 *SCSI_CTRL_TIMING3 = (glitch & 0xF);
470 }
471
472 static void
473 scsiSetDefaultTiming()
474 {
475 const uint8_t* asyncTiming = asyncTimings[0];
476 scsiSetTiming(
477 asyncTiming[0],
478 asyncTiming[1],
479 asyncTiming[2],
480 asyncTiming[3]);
481 }
482
483 void scsiEnterPhase(int newPhase)
484 {
485 // ANSI INCITS 362-2002 SPI-3 10.7.1:
486 // Phase changes are not allowed while REQ or ACK is asserted.
487 while (likely(!scsiDev.resetFlag) && scsiStatusACK()) {}
488
489 int oldPhase = *SCSI_CTRL_PHASE;
490
491 if (!scsiDev.resetFlag && (!scsiPhyFifoEmpty() || !scsiPhyFifoAltEmpty())) {
492 // Force a lock-up.
493 assertFail();
494 }
495 if (newPhase != oldPhase)
496 {
497 if ((newPhase == DATA_IN || newPhase == DATA_OUT) &&
498 scsiDev.target->syncOffset)
499 {
500 if (scsiDev.target->syncPeriod < 23)
501 {
502 scsiSetTiming(SCSI_FAST20_ASSERT, SCSI_FAST20_DESKEW, SCSI_FAST20_HOLD, 1);
503 }
504 else if (scsiDev.target->syncPeriod <= 25)
505 {
506 if (newPhase == DATA_IN)
507 {
508 scsiSetTiming(SCSI_FAST10_WRITE_ASSERT, SCSI_FAST10_DESKEW, SCSI_FAST10_HOLD, 1);
509 }
510 else
511 {
512 scsiSetTiming(SCSI_FAST10_READ_ASSERT, SCSI_FAST10_DESKEW, SCSI_FAST10_HOLD, 1);
513 }
514 }
515 else
516 {
517 // Amiga A3000 OS3.9 sets period to 35 and fails with
518 // glitch == 1.
519 int glitch =
520 scsiDev.target->syncPeriod < 35 ? 1 :
521 (scsiDev.target->syncPeriod < 45 ? 2 : 5);
522 int deskew = syncDeskew(scsiDev.target->syncPeriod);
523 int assertion;
524 if (newPhase == DATA_IN)
525 {
526 assertion = syncAssertionWrite(scsiDev.target->syncPeriod, deskew);
527 }
528 else
529 {
530 assertion = syncAssertionRead(scsiDev.target->syncPeriod);
531 }
532 scsiSetTiming(
533 assertion,
534 deskew,
535 syncHold(scsiDev.target->syncPeriod),
536 glitch);
537 }
538
539 *SCSI_CTRL_SYNC_OFFSET = scsiDev.target->syncOffset;
540 }
541 else if (newPhase >= 0)
542 {
543
544 *SCSI_CTRL_SYNC_OFFSET = 0;
545 const uint8_t* asyncTiming;
546
547 if (scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_NoLimit)
548 {
549 asyncTiming = asyncTimings[SCSI_ASYNC_SAFE];
550 }
551 else if (scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_TURBO)
552 {
553 asyncTiming = asyncTimings[SCSI_ASYNC_TURBO];
554 }
555 else if (scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_ASYNC_50)
556 {
557 asyncTiming = asyncTimings[SCSI_ASYNC_50];
558 } else if (scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_ASYNC_33) {
559
560 asyncTiming = asyncTimings[SCSI_ASYNC_33];
561
562 } else {
563 asyncTiming = asyncTimings[SCSI_ASYNC_15];
564 }
565 scsiSetTiming(
566 asyncTiming[0],
567 asyncTiming[1],
568 asyncTiming[2],
569 asyncTiming[3]);
570 }
571
572 if (newPhase >= 0)
573 {
574 *SCSI_CTRL_PHASE = newPhase;
575 busSettleDelay();
576
577 if (scsiDev.compatMode < COMPAT_SCSI2)
578 {
579 // EMU EMAX needs 100uS ! 10uS is not enough.
580 s2s_delay_us(100);
581 }
582 }
583 else
584 {
585 *SCSI_CTRL_PHASE = 0;
586 }
587 }
588 }
589
590 uint32_t s2s_getScsiRateMBs()
591 {
592 if (scsiDev.target->syncOffset)
593 {
594 if (scsiDev.target->syncPeriod < 23)
595 {
596 return 20;
597 }
598 else if (scsiDev.target->syncPeriod <= 25)
599 {
600 return 10;
601 }
602 else
603 {
604 return 1000 / (scsiDev.target->syncPeriod * 4);
605 }
606 }
607 else
608 {
609 return 0;
610 }
611 }
612
613 void scsiPhyReset()
614 {
615 if (dmaInProgress)
616 {
617 HAL_DMA_Abort(&memToFSMC);
618 HAL_DMA_Abort(&fsmcToMem);
619
620 dmaInProgress = 0;
621 }
622
623 s2s_fpgaReset(); // Clears fifos etc.
624
625 *SCSI_CTRL_PHASE = 0x00;
626 *SCSI_CTRL_BSY = 0x00;
627 scsiPhyFifoSel = 0;
628 *SCSI_FIFO_SEL = 0;
629 *SCSI_CTRL_DBX = 0;
630
631 *SCSI_CTRL_SYNC_OFFSET = 0;
632 scsiSetDefaultTiming();
633
634 // DMA Benchmark code
635 // Currently 14.9MB/s.
636 #ifdef DMA_BENCHMARK
637 while(1)
638 {
639 s2s_ledOn();
640 // 100MB
641 for (int i = 0; i < (100LL * 1024 * 1024 / SCSI_FIFO_DEPTH); ++i)
642 {
643 HAL_DMA_Start(
644 &memToFSMC,
645 (uint32_t) &scsiDev.data[0],
646 (uint32_t) SCSI_FIFO_DATA,
647 SCSI_FIFO_DEPTH / 4);
648
649 HAL_DMA_PollForTransfer(
650 &memToFSMC,
651 HAL_DMA_FULL_TRANSFER,
652 0xffffffff);
653
654 s2s_fpgaReset();
655 }
656 s2s_ledOff();
657
658 for(int i = 0; i < 10; ++i) s2s_delay_ms(1000);
659 }
660 #endif
661
662 #ifdef SCSI_FREQ_TEST
663 while(1)
664 {
665 *SCSI_CTRL_DBX = 0xAA;
666 *SCSI_CTRL_DBX = 0x55;
667 }
668 #endif
669
670 }
671
672 static void scsiPhyInitDMA()
673 {
674 // One-time init only.
675 static uint8_t init = 0;
676 if (init == 0)
677 {
678 init = 1;
679
680 // Memory to memory transfers can only be done using DMA2
681 __DMA2_CLK_ENABLE();
682
683 // Transmit SCSI data. The source data is treated as the
684 // peripheral (even though this is memory-to-memory)
685 memToFSMC.Instance = DMA2_Stream0;
686 memToFSMC.Init.Channel = DMA_CHANNEL_0;
687 memToFSMC.Init.Direction = DMA_MEMORY_TO_MEMORY;
688 memToFSMC.Init.PeriphInc = DMA_PINC_ENABLE;
689 memToFSMC.Init.MemInc = DMA_MINC_DISABLE;
690 memToFSMC.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
691 memToFSMC.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
692 memToFSMC.Init.Mode = DMA_NORMAL;
693 memToFSMC.Init.Priority = DMA_PRIORITY_LOW;
694 // FIFO mode is needed to allow conversion from 32bit words to the
695 // 16bit FSMC interface.
696 memToFSMC.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
697
698 // We only use 1 word (4 bytes) in the fifo at a time. Normally it's
699 // better to let the DMA fifo fill up then do burst transfers, but
700 // bursting out the FSMC interface will be very slow and may starve
701 // other (faster) transfers. We don't want to risk the SDIO transfers
702 // from overrun/underrun conditions.
703 memToFSMC.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
704 memToFSMC.Init.MemBurst = DMA_MBURST_SINGLE;
705 memToFSMC.Init.PeriphBurst = DMA_PBURST_SINGLE;
706 HAL_DMA_Init(&memToFSMC);
707
708 // Receive SCSI data. The source data (fsmc) is treated as the
709 // peripheral (even though this is memory-to-memory)
710 fsmcToMem.Instance = DMA2_Stream1;
711 fsmcToMem.Init.Channel = DMA_CHANNEL_0;
712 fsmcToMem.Init.Direction = DMA_MEMORY_TO_MEMORY;
713 fsmcToMem.Init.PeriphInc = DMA_PINC_DISABLE;
714 fsmcToMem.Init.MemInc = DMA_MINC_ENABLE;
715 fsmcToMem.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
716 fsmcToMem.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
717 fsmcToMem.Init.Mode = DMA_NORMAL;
718 fsmcToMem.Init.Priority = DMA_PRIORITY_LOW;
719 fsmcToMem.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
720 fsmcToMem.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
721 fsmcToMem.Init.MemBurst = DMA_MBURST_SINGLE;
722 fsmcToMem.Init.PeriphBurst = DMA_PBURST_SINGLE;
723 HAL_DMA_Init(&fsmcToMem);
724
725 // TODO configure IRQs
726 }
727 }
728
729
730 void scsiPhyInit()
731 {
732 scsiPhyInitDMA();
733
734 *SCSI_CTRL_IDMASK = 0x00; // Reset in scsiPhyConfig
735 *SCSI_CTRL_PHASE = 0x00;
736 *SCSI_CTRL_BSY = 0x00;
737 scsiPhyFifoSel = 0;
738 *SCSI_FIFO_SEL = 0;
739 *SCSI_CTRL_DBX = 0;
740
741 *SCSI_CTRL_SYNC_OFFSET = 0;
742 scsiSetDefaultTiming();
743
744 *SCSI_CTRL_SEL_TIMING = SCSI_DEFAULT_SELECTION;
745
746 }
747
748 void scsiPhyConfig()
749 {
750 if (scsiDev.boardCfg.flags6 & S2S_CFG_ENABLE_TERMINATOR)
751 {
752 HAL_GPIO_WritePin(nTERM_EN_GPIO_Port, nTERM_EN_Pin, GPIO_PIN_RESET);
753 }
754 else
755 {
756 HAL_GPIO_WritePin(nTERM_EN_GPIO_Port, nTERM_EN_Pin, GPIO_PIN_SET);
757 }
758
759
760 uint8_t idMask = 0;
761 for (int i = 0; i < 8; ++i)
762 {
763 const S2S_TargetCfg* cfg = s2s_getConfigById(i);
764 if (cfg && (cfg->scsiId & S2S_CFG_TARGET_ENABLED))
765 {
766 idMask |= (1 << i);
767 }
768 }
769 *SCSI_CTRL_IDMASK = idMask;
770
771 *SCSI_CTRL_FLAGS =
772 ((scsiDev.boardCfg.flags & S2S_CFG_DISABLE_GLITCH) ?
773 SCSI_CTRL_FLAGS_DISABLE_GLITCH : 0) |
774 ((scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY) ?
775 SCSI_CTRL_FLAGS_ENABLE_PARITY : 0);
776
777 *SCSI_CTRL_SEL_TIMING =
778 (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_SEL_LATCH) ?
779 SCSI_FAST_SELECTION : SCSI_DEFAULT_SELECTION;
780 }
781
782
783 // 1 = DBx error
784 // 2 = Parity error
785 // 4 = MSG error
786 // 8 = CD error
787 // 16 = IO error
788 // 32 = other error
789 // 64 = fpga comms error
790 int scsiSelfTest()
791 {
792 if (scsiDev.phase != BUS_FREE)
793 {
794 return 32;
795 }
796
797 // Acquire the SCSI bus.
798 for (int i = 0; i < 100; ++i)
799 {
800 if (scsiStatusBSY())
801 {
802 s2s_delay_ms(1);
803 }
804 }
805 if (scsiStatusBSY())
806 {
807 // Error, couldn't acquire scsi bus
808 return 32;
809 }
810 *SCSI_CTRL_BSY = 1;
811 s2s_delay_ms(1);
812 if (! scsiStatusBSY())
813 {
814 *SCSI_CTRL_BSY = 0;
815
816 // Error, BSY doesn't work.
817 return 32;
818 }
819
820 // Should be safe to use the bus now.
821
822 int result = 0;
823
824 *SCSI_CTRL_DBX = 0;
825 busSettleDelay();
826 if ((*SCSI_STS_DBX & 0xff) != 0)
827 {
828 result = 1;
829 }
830
831 // TEST DBx
832 int i;
833 for (i = 0; i < 8; ++i)
834 {
835 uint8_t data = 1 << i;
836 *SCSI_CTRL_DBX = 0;
837 busSettleDelay();
838 *SCSI_CTRL_DBX = data;
839 busSettleDelay();
840 // STS_DBX is 16 bit!
841 if ((*SCSI_STS_DBX & 0xff) != data)
842 {
843 result = i + 2;
844 }
845 }
846
847 // TODO Test DBP
848 *SCSI_CTRL_DBX = 0;
849
850 // FPGA comms test code
851 for(i = 0; i < 10000; ++i)
852 {
853 for (int j = 0; j < SCSI_FIFO_DEPTH; ++j)
854 {
855 scsiDev.data[j] = j;
856 }
857
858 if (!scsiPhyFifoEmpty())
859 {
860 assertFail();
861 }
862
863 *SCSI_CTRL_PHASE = DATA_IN;
864 HAL_DMA_Start(
865 &memToFSMC,
866 (uint32_t) &scsiDev.data[0],
867 (uint32_t) SCSI_FIFO_DATA,
868 SCSI_FIFO_DEPTH / 4);
869
870 HAL_DMA_PollForTransfer(
871 &memToFSMC,
872 HAL_DMA_FULL_TRANSFER,
873 0xffffffff);
874
875 if (!scsiPhyFifoFull())
876 {
877 assertFail();
878 }
879
880 memset(&scsiDev.data[0], 0, SCSI_FIFO_DEPTH);
881
882 *SCSI_CTRL_PHASE = DATA_OUT;
883 HAL_DMA_Start(
884 &fsmcToMem,
885 (uint32_t) SCSI_FIFO_DATA,
886 (uint32_t) &scsiDev.data[0],
887 SCSI_FIFO_DEPTH / 2);
888
889 HAL_DMA_PollForTransfer(
890 &fsmcToMem,
891 HAL_DMA_FULL_TRANSFER,
892 0xffffffff);
893
894 if (!scsiPhyFifoEmpty())
895 {
896 assertFail();
897 }
898
899
900 for (int j = 0; j < SCSI_FIFO_DEPTH; ++j)
901 {
902 if (scsiDev.data[j] != (uint8_t) j)
903 {
904 result |= 64;
905 }
906 }
907
908 s2s_fpgaReset();
909
910 }
911
912 *SCSI_CTRL_BSY = 0;
913 return result;
914 }
915