Преглед изворни кода

Fix floating pins, SD high speed mode, and SCSI performance improvements

Michael McMaster пре 9 година
родитељ
комит
926dd5f5dc

+ 5 - 0
lib/SCSI2SD/CHANGELOG

@@ -1,3 +1,8 @@
+2016100X		?
+	- Enable synchronous transfers on SCSI1 hosts
+	- Support 4MB/s sync transfers for Amiga A590 (WD33C93)
+	- Faster SD performance, but cannot use USB + SD at the same time.
+
 20161006		6.0.13
 	- Fixed SCSI timing issue
 	- Added glitch filter on SCSI signals.

+ 1 - 6
lib/SCSI2SD/Makefile

@@ -34,7 +34,6 @@ build/stm32cubemx/gpio.o: STM32CubeMX/SCSI2SD-V6/Src/gpio.c
 build/stm32cubemx/main.o: STM32CubeMX/SCSI2SD-V6/Src/main.c
 build/stm32cubemx/sdio.o: STM32CubeMX/SCSI2SD-V6/Src/sdio.c
 build/stm32cubemx/spi.o: STM32CubeMX/SCSI2SD-V6/Src/spi.c
-build/stm32cubemx/tim.o: STM32CubeMX/SCSI2SD-V6/Src/tim.c
 build/stm32cubemx/stm32f2xx_hal_msp.o: STM32CubeMX/SCSI2SD-V6/Src/stm32f2xx_hal_msp.c
 build/stm32cubemx/stm32f2xx_it.o: STM32CubeMX/SCSI2SD-V6/Src/stm32f2xx_it.c
 build/stm32cubemx/usart.o: STM32CubeMX/SCSI2SD-V6/Src/usart.c
@@ -52,8 +51,6 @@ build/stm32cubemx/stm32f2xx_hal_rcc.o: STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_
 build/stm32cubemx/stm32f2xx_hal_sd.o: STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_sd.c
 build/stm32cubemx/stm32f2xx_hal_spi.o: STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_spi.c
 build/stm32cubemx/stm32f2xx_hal_sram.o: STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_sram.c
-build/stm32cubemx/stm32f2xx_hal_tim.o: STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_tim.c
-build/stm32cubemx/stm32f2xx_hal_tim_ex.o: STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_tim_ex.c
 build/stm32cubemx/stm32f2xx_hal_uart.o: STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_uart.c
 build/stm32cubemx/stm32f2xx_ll_fsmc.o: STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_ll_fsmc.c
 build/stm32cubemx/stm32f2xx_ll_sdmmc.o: STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_ll_sdmmc.c
@@ -78,7 +75,6 @@ STM32OBJS = \
 	build/stm32cubemx/main.o \
 	build/stm32cubemx/sdio.o \
 	build/stm32cubemx/spi.o \
-	build/stm32cubemx/tim.o \
 	build/stm32cubemx/stm32f2xx_hal_msp.o \
 	build/stm32cubemx/stm32f2xx_it.o \
 	build/stm32cubemx/usart.o \
@@ -96,8 +92,6 @@ STM32OBJS = \
 	build/stm32cubemx/stm32f2xx_hal_sd.o \
 	build/stm32cubemx/stm32f2xx_hal_spi.o \
 	build/stm32cubemx/stm32f2xx_hal_sram.o \
-	build/stm32cubemx/stm32f2xx_hal_tim.o \
-	build/stm32cubemx/stm32f2xx_hal_tim_ex.o \
 	build/stm32cubemx/stm32f2xx_hal_uart.o \
 	build/stm32cubemx/stm32f2xx_ll_fsmc.o \
 	build/stm32cubemx/stm32f2xx_ll_sdmmc.o \
@@ -130,6 +124,7 @@ USBCOMPOSITE_SRC= \
 
 SRC = \
 	src/firmware/bootloader.c \
+	src/firmware/bsp.c \
 	src/firmware/cdrom.c \
 	src/firmware/config.c \
 	src/firmware/disk.c \

+ 6 - 4
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_sd.c

@@ -1953,10 +1953,12 @@ HAL_SD_ErrorTypedef HAL_SD_HighSpeed (SD_HandleTypeDef *hsd)
     __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
     
     /* Test if the switch mode HS is ok */
-    if ((SD_hs[13]& 2) != 2)
-    {
-      errorstate = SD_UNSUPPORTED_FEATURE;
-    } 
+    // MM: These bits (0 to 271) are reserved in the spec I'm looking at ???
+    // Should be safe to ignore the result.
+    //if ((SD_hs[13]& 2) != 2)
+    //{
+      //errorstate = SD_UNSUPPORTED_FEATURE;
+    //} 
   }
   
   return errorstate;

+ 0 - 73
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/Inc/tim.h

@@ -1,73 +0,0 @@
-/**
-  ******************************************************************************
-  * File Name          : TIM.h
-  * Description        : This file provides code for the configuration
-  *                      of the TIM instances.
-  ******************************************************************************
-  *
-  * COPYRIGHT(c) 2016 STMicroelectronics
-  *
-  * Redistribution and use in source and binary forms, with or without modification,
-  * are permitted provided that the following conditions are met:
-  *   1. Redistributions of source code must retain the above copyright notice,
-  *      this list of conditions and the following disclaimer.
-  *   2. Redistributions in binary form must reproduce the above copyright notice,
-  *      this list of conditions and the following disclaimer in the documentation
-  *      and/or other materials provided with the distribution.
-  *   3. Neither the name of STMicroelectronics nor the names of its contributors
-  *      may be used to endorse or promote products derived from this software
-  *      without specific prior written permission.
-  *
-  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-  *
-  ******************************************************************************
-  */
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __tim_H
-#define __tim_H
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f2xx_hal.h"
-
-/* USER CODE BEGIN Includes */
-
-/* USER CODE END Includes */
-
-extern TIM_HandleTypeDef htim4;
-
-/* USER CODE BEGIN Private defines */
-
-/* USER CODE END Private defines */
-
-void MX_TIM4_Init(void);
-
-/* USER CODE BEGIN Prototypes */
-
-/* USER CODE END Prototypes */
-
-#ifdef __cplusplus
-}
-#endif
-#endif /*__ tim_H */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 19 - 16
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/SCSI2SD-V6.ioc

@@ -455,36 +455,39 @@ ProjectManager.ProjectName=SCSI2SD-V6
 ProjectManager.TargetToolchain=TrueSTUDIO
 ProjectManager.ToolChainLocation=
 RCC.48MHZClocksFreq_Value=48000000
-RCC.AHBFreq_Value=96000000
+RCC.AHBFreq_Value=108000000
 RCC.APB1CLKDivider=RCC_HCLK_DIV4
-RCC.APB1Freq_Value=24000000
-RCC.APB1TimFreq_Value=48000000
+RCC.APB1Freq_Value=27000000
+RCC.APB1TimFreq_Value=54000000
 RCC.APB2CLKDivider=RCC_HCLK_DIV2
-RCC.APB2Freq_Value=48000000
-RCC.APB2TimFreq_Value=96000000
-RCC.CortexFreq_Value=96000000
-RCC.EthernetFreq_Value=96000000
-RCC.FCLKCortexFreq_Value=96000000
+RCC.APB2Freq_Value=54000000
+RCC.APB2TimFreq_Value=108000000
+RCC.CortexFreq_Value=108000000
+RCC.EthernetFreq_Value=108000000
+RCC.FCLKCortexFreq_Value=108000000
 RCC.FamilyName=M
-RCC.HCLKFreq_Value=96000000
+RCC.HCLKFreq_Value=108000000
 RCC.HSE_VALUE=20000000
 RCC.HSI_VALUE=16000000
 RCC.I2SClocksFreq_Value=96000000
-RCC.IPParameters=FamilyName,LSE_VALUE,HSI_VALUE,SYSCLKFreq_VALUE,AHBFreq_Value,CortexFreq_Value,APB1Freq_Value,APB2Freq_Value,HSE_VALUE,RTCHSEDivFreq_Value,LSI_VALUE,RTCFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,PLLCLKFreq_Value,48MHZClocksFreq_Value,VCOI2SOutputFreq_Value,VcooutputI2S,I2SClocksFreq_Value,RCC_MCO1Source,HCLKFreq_Value,FCLKCortexFreq_Value,APB1TimFreq_Value,APB2TimFreq_Value,EthernetFreq_Value,MCO2PinFreq_Value,APB1CLKDivider,APB2CLKDivider,MCO1PinFreq_Value,SYSCLKSource,PLLM
+RCC.IPParameters=FamilyName,LSE_VALUE,HSI_VALUE,SYSCLKFreq_VALUE,AHBFreq_Value,CortexFreq_Value,APB1Freq_Value,APB2Freq_Value,HSE_VALUE,RTCHSEDivFreq_Value,LSI_VALUE,RTCFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,PLLCLKFreq_Value,48MHZClocksFreq_Value,VCOI2SOutputFreq_Value,VcooutputI2S,I2SClocksFreq_Value,RCC_MCO1Source,HCLKFreq_Value,FCLKCortexFreq_Value,APB1TimFreq_Value,APB2TimFreq_Value,EthernetFreq_Value,MCO2PinFreq_Value,APB1CLKDivider,APB2CLKDivider,MCO1PinFreq_Value,SYSCLKSource,PLLM,PLLN,PLLQ,PLLP
 RCC.LSE_VALUE=32768
 RCC.LSI_VALUE=32000
-RCC.MCO1PinFreq_Value=96000000
-RCC.MCO2PinFreq_Value=96000000
-RCC.PLLCLKFreq_Value=96000000
+RCC.MCO1PinFreq_Value=108000000
+RCC.MCO2PinFreq_Value=108000000
+RCC.PLLCLKFreq_Value=108000000
 RCC.PLLM=20
+RCC.PLLN=432
+RCC.PLLP=RCC_PLLP_DIV4
+RCC.PLLQ=9
 RCC.RCC_MCO1Source=RCC_MCO1SOURCE_PLLCLK
 RCC.RTCFreq_Value=32000
 RCC.RTCHSEDivFreq_Value=10000000
-RCC.SYSCLKFreq_VALUE=96000000
+RCC.SYSCLKFreq_VALUE=108000000
 RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
 RCC.VCOI2SOutputFreq_Value=192000000
 RCC.VCOInputFreq_Value=1000000
-RCC.VCOOutputFreq_Value=192000000
+RCC.VCOOutputFreq_Value=432000000
 RCC.VcooutputI2S=96000000
 SDIO.BusWide=SDIO_BUS_WIDE_1B
 SDIO.IPParameters=BusWide,WideMode
@@ -498,7 +501,7 @@ SH.S_TIM4_CH1.ConfNb=1
 SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16
 SPI1.CLKPhase=SPI_PHASE_2EDGE
 SPI1.CLKPolarity=SPI_POLARITY_HIGH
-SPI1.CalculateBaudRate=3.0 MBits/s
+SPI1.CalculateBaudRate=3.375 MBits/s
 SPI1.IPParameters=Mode,CalculateBaudRate,BaudRatePrescaler,CLKPolarity,CLKPhase
 SPI1.Mode=SPI_MODE_MASTER
 USB_DEVICE.CLASS_NAME-HID_FS=HID

+ 18 - 16
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/Src/gpio.c

@@ -98,8 +98,9 @@ void MX_GPIO_Init(void)
 
   /*Configure GPIO pin : PtPin */
   GPIO_InitStruct.Pin = nSPICFG_CS_Pin;
-  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
   HAL_GPIO_Init(nSPICFG_CS_GPIO_Port, &GPIO_InitStruct);
 
   /*Configure GPIO pin : PtPin */
@@ -119,27 +120,21 @@ void MX_GPIO_Init(void)
   /*Configure GPIO pins : PBPin PBPin PBPin */
   GPIO_InitStruct.Pin = BOOT1_Pin|UNUSED_PB5_Pin|UNUSED_PB6_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
-  /*Configure GPIO pins : PE11 PE12 PE13 PE14 
-                           PE15 PE0 PE1 */
-  GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 
-                          |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
-  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
-
   /*Configure GPIO pins : PBPin PBPin */
   GPIO_InitStruct.Pin = UNUSED_PB12_Pin|UNUSED_PB13_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Pull = GPIO_PULLDOWN;
   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
-  /*Configure GPIO pins : PD8 PD9 PD10 PD6 */
-  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_6;
-  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  /*Configure GPIO pins : PD6, PD12 */
+  // PD6: FSMC NWAIT, not used yet.PULLED UP in fpga pin config
+  // PD12: FPGA_GPIO1, not used.
+  GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_12;
+  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
   HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
   /*Configure GPIO pins : PDPin PDPin */
@@ -170,11 +165,18 @@ void MX_GPIO_Init(void)
   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
   /*Configure GPIO pin : PA10 */
+  // USB Host OTG ID pin
   GPIO_InitStruct.Pin = GPIO_PIN_10;
-  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
+  // USB Host pins, currently unused.
+  GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
+  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
   /*Configure GPIO pins : PBPin PBPin */
   GPIO_InitStruct.Pin = nSD_WP_Pin|nSD_CD_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

+ 6 - 8
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/Src/main.c

@@ -34,7 +34,6 @@
 #include "stm32f2xx_hal.h"
 #include "sdio.h"
 #include "spi.h"
-#include "tim.h"
 #include "usart.h"
 #include "usb_device.h"
 #include "usb_host.h"
@@ -91,9 +90,8 @@ int main(void)
   MX_FSMC_Init();
   MX_SDIO_SD_Init();
   MX_SPI1_Init();
-  // TODO re-enable MX_TIM4_Init();
-  // TODO re-enable MX_USART3_UART_Init();
-  // TODO re-enable MX_USB_HOST_Init();
+  MX_USART3_UART_Init(); // Not used, but we don't want the pins floating.
+  // MX_USB_HOST_Init(); // Not used, pins set to GPIO
 
   /* USER CODE BEGIN 2 */
   mainInit();
@@ -105,7 +103,7 @@ int main(void)
   while (1)
   {
   /* USER CODE END WHILE */
-    // TODO re-enable MX_USB_HOST_Process();
+    //MX_USB_HOST_Process();
 
   /* USER CODE BEGIN 3 */
   mainLoop();
@@ -130,9 +128,9 @@ void SystemClock_Config(void)
   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 
   RCC_OscInitStruct.PLL.PLLM = 20;
-  RCC_OscInitStruct.PLL.PLLN = 192;
-  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
-  RCC_OscInitStruct.PLL.PLLQ = 4;
+  RCC_OscInitStruct.PLL.PLLN = 432;
+  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
+  RCC_OscInitStruct.PLL.PLLQ = 9;
   HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1

+ 0 - 133
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/Src/tim.c

@@ -1,133 +0,0 @@
-/**
-  ******************************************************************************
-  * File Name          : TIM.c
-  * Description        : This file provides code for the configuration
-  *                      of the TIM instances.
-  ******************************************************************************
-  *
-  * COPYRIGHT(c) 2016 STMicroelectronics
-  *
-  * Redistribution and use in source and binary forms, with or without modification,
-  * are permitted provided that the following conditions are met:
-  *   1. Redistributions of source code must retain the above copyright notice,
-  *      this list of conditions and the following disclaimer.
-  *   2. Redistributions in binary form must reproduce the above copyright notice,
-  *      this list of conditions and the following disclaimer in the documentation
-  *      and/or other materials provided with the distribution.
-  *   3. Neither the name of STMicroelectronics nor the names of its contributors
-  *      may be used to endorse or promote products derived from this software
-  *      without specific prior written permission.
-  *
-  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-  *
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "tim.h"
-
-#include "gpio.h"
-
-/* USER CODE BEGIN 0 */
-
-/* USER CODE END 0 */
-
-TIM_HandleTypeDef htim4;
-
-/* TIM4 init function */
-void MX_TIM4_Init(void)
-{
-  TIM_SlaveConfigTypeDef sSlaveConfig;
-  TIM_MasterConfigTypeDef sMasterConfig;
-
-  htim4.Instance = TIM4;
-  htim4.Init.Prescaler = 0;
-  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
-  htim4.Init.Period = 0;
-  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-  HAL_TIM_Base_Init(&htim4);
-
-  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;
-  sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
-  sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;
-  sSlaveConfig.TriggerFilter = 0;
-  HAL_TIM_SlaveConfigSynchronization(&htim4, &sSlaveConfig);
-
-  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
-  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
-  HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig);
-
-}
-
-void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
-{
-
-  GPIO_InitTypeDef GPIO_InitStruct;
-  if(htim_base->Instance==TIM4)
-  {
-  /* USER CODE BEGIN TIM4_MspInit 0 */
-
-  /* USER CODE END TIM4_MspInit 0 */
-    /* Peripheral clock enable */
-    __TIM4_CLK_ENABLE();
-  
-    /**TIM4 GPIO Configuration    
-    PD12     ------> TIM4_CH1 
-    */
-    GPIO_InitStruct.Pin = GPIO_PIN_12;
-    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
-    GPIO_InitStruct.Pull = GPIO_NOPULL;
-    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
-    GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
-    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
-
-  /* USER CODE BEGIN TIM4_MspInit 1 */
-
-  /* USER CODE END TIM4_MspInit 1 */
-  }
-}
-
-void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
-{
-
-  if(htim_base->Instance==TIM4)
-  {
-  /* USER CODE BEGIN TIM4_MspDeInit 0 */
-
-  /* USER CODE END TIM4_MspDeInit 0 */
-    /* Peripheral clock disable */
-    __TIM4_CLK_DISABLE();
-  
-    /**TIM4 GPIO Configuration    
-    PD12     ------> TIM4_CH1 
-    */
-    HAL_GPIO_DeInit(GPIOD, GPIO_PIN_12);
-
-  }
-  /* USER CODE BEGIN TIM4_MspDeInit 1 */
-
-  /* USER CODE END TIM4_MspDeInit 1 */
-} 
-
-/* USER CODE BEGIN 1 */
-
-/* USER CODE END 1 */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 12 - 1
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/Src/usbd_conf.c

@@ -108,7 +108,18 @@ void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd)
     PA11     ------> USB_OTG_FS_DM
     PA12     ------> USB_OTG_FS_DP 
     */
-    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_11|GPIO_PIN_12);
+	// HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_11|GPIO_PIN_12);
+	// MM: Don't let pins float.
+	GPIO_InitTypeDef GPIO_InitStruct;
+	GPIO_InitStruct.Pin = GPIO_PIN_9;
+	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+	GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+	GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
+	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+	GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
     /* Peripheral interrupt Deinit*/
     HAL_NVIC_DisableIRQ(OTG_FS_IRQn);

BIN
lib/SCSI2SD/rtl/fpga_bitmap.o


+ 2 - 0
lib/SCSI2SD/src/firmware/bsp.h

@@ -22,6 +22,8 @@
 // The maximum burst is 16 bytes.
 #define S2S_DMA_ALIGN __attribute__((aligned(1024)))
 
+void s2s_setNormalClock();
+void s2s_setFastClock();
 
 #endif
 

+ 6 - 6
lib/SCSI2SD/src/firmware/config.c

@@ -37,7 +37,7 @@
 
 #include <string.h>
 
-static const uint16_t FIRMWARE_VERSION = 0x060D;
+static const uint16_t FIRMWARE_VERSION = 0x060E;
 
 // 1 flash row
 static const uint8_t DEFAULT_CONFIG[128] =
@@ -170,10 +170,10 @@ debugCommand()
 	response[14] = scsiDev.lastStatus;
 	response[15] = scsiDev.lastSense;
 	response[16] = scsiDev.phase;
-	response[17] = scsiStatusBSY();
-	response[18] = scsiStatusSEL();
-	response[19] = scsiStatusATN();
-	response[20] = scsiStatusRST();
+	response[17] = *SCSI_STS_SCSI;
+	response[18] = scsiDev.target != NULL ? scsiDev.target->syncOffset : 0;
+	response[19] = scsiDev.target != NULL ? scsiDev.target->syncPeriod : 0;
+	response[20] = scsiDev.minSyncPeriod;
 	response[21] = scsiDev.rstCount;
 	response[22] = scsiDev.selCount;
 	response[23] = scsiDev.msgCount;
@@ -184,7 +184,7 @@ debugCommand()
 	response[28] = scsiDev.lastSenseASC;
 	response[29] = *SCSI_STS_DBX;
 	response[30] = LastTrace;
-	response[31] = scsiStatusACK();
+	response[31] = 0; // Unused
 	hidPacket_send(response, sizeof(response));
 }
 

+ 23 - 4
lib/SCSI2SD/src/firmware/disk.c

@@ -558,8 +558,11 @@ void scsiDiskPoll()
 			{
 				prep += completedDmaSectors;
 				sdActive -= completedDmaSectors;
-			} else if (sdActive > 1) {
-				if (scsiDev.data[SD_SECTOR_SIZE * (prep % buffers) + 511] != 0x33) {
+			} else if (sdActive > 1)
+			{
+				if ((scsiDev.data[SD_SECTOR_SIZE * (prep % buffers) + 510] != 0xAA) ||
+					(scsiDev.data[SD_SECTOR_SIZE * (prep % buffers) + 511] != 0x33))
+				{
 					prep += 1;
 					sdActive -= 1;
 				}
@@ -584,6 +587,7 @@ void scsiDiskPoll()
 
 				for (int dodgy = 0; dodgy < sectors; dodgy++)
 				{
+					scsiDev.data[SD_SECTOR_SIZE * (startBuffer + dodgy) + 510] = 0xAA;
 					scsiDev.data[SD_SECTOR_SIZE * (startBuffer + dodgy) + 511] = 0x33;
 				}
 
@@ -621,12 +625,26 @@ void scsiDiskPoll()
 				}
 
 				uint16_t* scsiDmaData = (uint16_t*) &(scsiDev.data[SD_SECTOR_SIZE * (i % buffers)]);
-				for (int k = 0; k < (dmaBytes + 1) / 2; ++k)
+				// Manually unrolled loop for performance.
+				// -Os won't unroll this for us automatically,
+				// especially since scsiPhyTx does volatile stuff.
+				// Reduces bus utilisation by making the fsmc split
+				// 32bits into 2 16 bit writes.
+				int k = 0;
+				for (; k + 4 < (dmaBytes + 1) / 2; k += 4)
+				{
+					scsiPhyTx32(scsiDmaData[k], scsiDmaData[k+1]);
+					scsiPhyTx32(scsiDmaData[k+2], scsiDmaData[k+3]);
+				}
+				for (; k < (dmaBytes + 1) / 2; ++k)
 				{
 					scsiPhyTx(scsiDmaData[k]);
 				}
 				i++;
-				while (!scsiPhyComplete() && !scsiDev.resetFlag) {}
+				while (!scsiPhyComplete() && !scsiDev.resetFlag)
+				{
+					__WFE(); // Wait for event
+				}
 				scsiPhyFifoFlip();
 				scsiSetDataCount(dmaBytes);
 			}
@@ -639,6 +657,7 @@ void scsiDiskPoll()
 			likely(scsiDev.phase == DATA_IN) &&
 			likely(!scsiDev.resetFlag))
 		{
+			__WFE(); // Wait for event
 		}
 
 

+ 36 - 2
lib/SCSI2SD/src/firmware/main.c

@@ -18,6 +18,7 @@
 #include "stm32f2xx.h"
 
 #include "config.h"
+#include "bsp.h"
 #include "disk.h"
 #include "fpga.h"
 #include "led.h"
@@ -26,6 +27,7 @@
 #include "scsiPhy.h"
 #include "time.h"
 #include "trace.h"
+#include "sdio.h"
 #include "usb_device/usb_device.h"
 #include "usb_device/usbd_composite.h"
 #include "usb_device/usbd_msc_storage_sd.h"
@@ -34,6 +36,8 @@
 const char* Notice = "Copyright (C) 2016 Michael McMaster <michael@codesrc.com>";
 uint32_t lastSDPoll;
 
+static int isUsbStarted;
+
 void mainEarlyInit()
 {
 	// USB device is initialised before mainInit is called
@@ -56,6 +60,7 @@ void mainInit()
 	scsiInit();
 
 	MX_USB_DEVICE_Init(); // USB lun config now available.
+	isUsbStarted = 1;
 
 	// Optional bootup delay
 	int delaySeconds = 0;
@@ -98,10 +103,39 @@ void mainLoop()
 				scsiPhyConfig();
 				scsiInit();
 
+				// Is a USB host connected ?
+				if (isUsbStarted)
+				{
+					USBD_Stop(&hUsbDeviceFS);
+					s2s_delay_ms(128);
+					USBD_Start(&hUsbDeviceFS);
+				}
+			}
+
+			// Can we speed up the SD card ?
+			// Don't combine with the above block because that won't
+			// run if the SD card is present at startup.
+			// Don't use VBUS monitoring because that just tells us about
+			// power, which could be from a charger
+			if ((blockDev.state & DISK_PRESENT) &&
+				isUsbStarted &&
+				(scsiDev.cmdCount > 0) && // no need for speed without scsi
+				!USBD_Composite_IsConfigured(&hUsbDeviceFS))
+			{
+				if (HAL_SD_HighSpeed(&hsd) == SD_OK)
+				{
+					USBD_Stop(&hUsbDeviceFS);
+					s2s_setFastClock();
+					isUsbStarted = 0;
+				}
+			}
 
-				USBD_Stop(&hUsbDeviceFS);
-				s2s_delay_ms(128);
+			else if (!(blockDev.state & DISK_PRESENT) && !isUsbStarted)
+			{
+				// Good time to restart USB.
+				s2s_setNormalClock();
 				USBD_Start(&hUsbDeviceFS);
+				isUsbStarted = 1;
 			}
 		}
 		else

+ 24 - 6
lib/SCSI2SD/src/firmware/scsi.c

@@ -73,6 +73,7 @@ static void enter_BusFree()
 
 	s2s_ledOff();
 	scsiDev.phase = BUS_FREE;
+	scsiDev.selFlag = 0;
 }
 
 static void enter_MessageIn(uint8_t message)
@@ -467,6 +468,7 @@ static void scsiReset()
 	scsiDev.phase = BUS_FREE;
 	scsiDev.atnFlag = 0;
 	scsiDev.resetFlag = 0;
+	scsiDev.selFlag = 0;
 	scsiDev.lun = -1;
 	scsiDev.compatMode = COMPAT_UNKNOWN;
 
@@ -488,6 +490,7 @@ static void scsiReset()
 		scsiDev.target[i].syncOffset = 0;
 		scsiDev.target[i].syncPeriod = 0;
 	}
+	scsiDev.minSyncPeriod = 0;
 
 	scsiDiskReset();
 
@@ -548,6 +551,10 @@ static void process_SelectionPhase()
 	}
 
 	uint8_t selStatus = *SCSI_STS_SELECTED;
+	if ((selStatus == 0) && (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_SEL_LATCH))
+	{
+		selStatus = scsiDev.selFlag;
+	}
 
 	int tgtIndex;
 	TargetState* target = NULL;
@@ -615,6 +622,7 @@ static void process_SelectionPhase()
 	{
 		scsiDev.phase = BUS_BUSY;
 	}
+	scsiDev.selFlag = 0;
 }
 
 static void process_MessageOut()
@@ -757,13 +765,22 @@ static void process_MessageOut()
 			int transferPeriod = extmsg[1];
 			int offset = extmsg[2];
 
-			if ((scsiDev.compatMode < COMPAT_SCSI2) ||
-				(transferPeriod > 50)) // 200ns, 5MB/s
+			if ((transferPeriod < scsiDev.minSyncPeriod) ||
+				(scsiDev.minSyncPeriod == 0))
+			{
+				scsiDev.minSyncPeriod = transferPeriod;
+			}
+
+			if ((transferPeriod > 80) || // 320ns, 3.125MB/s
+				// Amiga A590 (WD33C93 chip) only does 3.5MB/s sync
+				// After 80 we start to run out of bits in the fpga timing
+				// register.
+				(transferPeriod == 0))
 			{
 				scsiDev.target->syncOffset = 0;
 				scsiDev.target->syncPeriod = 0;
 			} else {
-				scsiDev.target->syncOffset = offset < 15 ? offset : 15;
+				scsiDev.target->syncOffset = offset < 63 ? offset : 63;
 				// FAST20 / 50ns / 20MHz is disabled for now due to
 				// data corruption while reading data. We can count the
 				// ACK's correctly, but can't save the data to a register
@@ -778,7 +795,7 @@ static void process_MessageOut()
 				{
 					scsiDev.target->syncPeriod = 25; // 100ns, 10MB/s
 				} else {
-					scsiDev.target->syncPeriod = 50; // 200ns, 5MB/s
+					scsiDev.target->syncPeriod = transferPeriod;
 				}
 			}
 
@@ -831,7 +848,7 @@ void scsiPoll(void)
 		// one initiator in the chain. Support this by moving
 		// straight to selection if SEL is asserted.
 		// ie. the initiator won't assert BSY and it's own ID before moving to selection.
-		else if (*SCSI_STS_SELECTED)
+		else if (scsiDev.selFlag || *SCSI_STS_SELECTED)
 		{
 			enter_SelectionPhase();
 		}
@@ -840,7 +857,7 @@ void scsiPoll(void)
 	case BUS_BUSY:
 		// Someone is using the bus. Perhaps they are trying to
 		// select us.
-		if (*SCSI_STS_SELECTED)
+		if (scsiDev.selFlag || *SCSI_STS_SELECTED)
 		{
 			enter_SelectionPhase();
 		}
@@ -937,6 +954,7 @@ void scsiInit()
 
 	scsiDev.atnFlag = 0;
 	scsiDev.resetFlag = 1;
+	scsiDev.selFlag = 0;
 	scsiDev.phase = BUS_FREE;
 	scsiDev.target = NULL;
 	scsiDev.compatMode = COMPAT_UNKNOWN;

+ 4 - 0
lib/SCSI2SD/src/firmware/scsi.h

@@ -115,6 +115,9 @@ typedef struct
 	// Set to true (1) if the RST flag was set.
 	volatile int resetFlag;
 
+	// Set to sel register if the SEL flag was set.
+	volatile int selFlag;
+
 	// Set to true (1) if a parity error was observed.
 	int parityError;
 
@@ -151,6 +154,7 @@ typedef struct
 	uint8_t lastStatus;
 	uint8_t lastSense;
 	uint16_t lastSenseASC;
+	uint8_t minSyncPeriod; // Debug use only.
 
 	int needSyncNegotiationAck;
 } ScsiDevice;

+ 54 - 29
lib/SCSI2SD/src/firmware/scsiPhy.c

@@ -28,26 +28,44 @@
 
 #include <string.h>
 
-// 5MB/s sync and async.
-// Assumes a 96MHz fpga clock.
+// Time until we consider ourselves selected
+// 400ns at 108MHz
+#define SCSI_DEFAULT_SELECTION 43
+#define SCSI_FAST_SELECTION 5
+
+// async.
+// Assumes a 108MHz fpga clock.
 // 2:0 Deskew count, 55ns
 // 6:4 Hold count, 53ns
 // 3:0 Assertion count, 80ns
 #define SCSI_DEFAULT_DESKEW 0x6
-#define SCSI_DEFAULT_TIMING ((0x5 << 4) | 0x8)
+#define SCSI_DEFAULT_TIMING ((0x6 << 4) | 0x9)
+
+// 3.125MB/s (80 period) to < 10MB/s sync
+// Assumes a 108MHz fpga clock. (9 ns)
+// (((period * 4) / 2) * 0.8) / 9
+// Done using 3 fixed point math.
+// 2:0 Deskew count, 55ns normal, or 25ns if faster than 5.5MB/s
+// 6:4 Hold count, 53ns normal, or 33ns if faster than 5.5MB/s
+// 3:0 Assertion count, variable
+#define SCSI_SYNC_DESKEW(period) (period < 45 ? SCSI_FAST10_DESKEW : SCSI_DEFAULT_DESKEW)
+#define SCSI_SYNC_TIMING(period) (((period < 45 ? 0x4 : 0x6) << 4) | ((((((int)period) * 177) + 750)/1000) & 0xF))
 
 // 10MB/s
 // 2:0 Deskew count, 25ns
 // 6:4 Hold count, 33ns
 // 3:0 Assertion count, 30ns
-#define SCSI_FAST10_DESKEW 3
+// We want deskew + hold + assert + 3 to add up to 11 clocks
+// the fpga code has 1 clock of overhead when transitioning from deskew to
+// assert to hold
+#define SCSI_FAST10_DESKEW 2
 #define SCSI_FAST10_TIMING ((0x3 << 4) | 0x3)
 
 // 20MB/s
 // 2:0 Deskew count, 12ns
 // 6:4 Hold count, 17ns
 // 3:0 Assertion count, 15ns
-#define SCSI_FAST20_DESKEW 2
+#define SCSI_FAST20_DESKEW 1
 #define SCSI_FAST20_TIMING ((0x2 << 4) | 0x2)
 
 // Private DMA variables.
@@ -60,22 +78,6 @@ static DMA_HandleTypeDef fsmcToMem;
 volatile uint8_t scsiRxDMAComplete;
 volatile uint8_t scsiTxDMAComplete;
 
-#if 0
-CY_ISR_PROTO(scsiRxCompleteISR);
-CY_ISR(scsiRxCompleteISR)
-{
-	traceIrq(trace_scsiRxCompleteISR);
-	scsiRxDMAComplete = 1;
-}
-
-CY_ISR_PROTO(scsiTxCompleteISR);
-CY_ISR(scsiTxCompleteISR)
-{
-	traceIrq(trace_scsiTxCompleteISR);
-	scsiTxDMAComplete = 1;
-}
-#endif
-
 uint8_t scsiPhyFifoSel = 0; // global
 
 // scsi IRQ handler is initialised by the STM32 HAL. Connected to
@@ -93,9 +95,14 @@ void EXTI4_IRQHandler()
 		__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_4);
 
 		scsiDev.resetFlag = scsiDev.resetFlag || scsiStatusRST();
-		// TODO grab SEL status as well
 
+		// selFlag is required for Philips P2000C which releases it after 600ns
+		// without waiting for BSY.
+		// Also required for some early Mac Plus roms
+		scsiDev.selFlag = *SCSI_STS_SELECTED;
 	}
+
+	__SEV(); // Set event. See corresponding __WFE() calls.
 }
 
 static void assertFail()
@@ -129,7 +136,10 @@ scsiReadByte(void)
 	scsiSetDataCount(1);
 
 	trace(trace_spinPhyRxFifo);
-	while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}
+	while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))
+	{
+		__WFE(); // Wait for event
+	}
 	scsiPhyFifoFlip();
 	uint8_t val = scsiPhyRx();
 	// TODO scsiDev.parityError = scsiDev.parityError || SCSI_Parity_Error_Read();
@@ -152,6 +162,7 @@ static void
 scsiReadPIO(uint8_t* data, uint32_t count)
 {
 	uint16_t* fifoData = (uint16_t*)data;
+
 	for (int i = 0; i < (count + 1) / 2; ++i)
 	{
 		fifoData[i] = scsiPhyRx(); // TODO ASSUMES LITTLE ENDIAN
@@ -218,7 +229,10 @@ scsiRead(uint8_t* data, uint32_t count, int* parityError)
 
 	while (i < count && likely(!scsiDev.resetFlag))
 	{
-		while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}
+		while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))
+		{
+			__WFE(); // Wait for event
+		}
 		*parityError |= scsiParityError();
 		scsiPhyFifoFlip();
 
@@ -287,7 +301,10 @@ scsiWriteByte(uint8_t value)
 	scsiSetDataCount(1);
 
 	trace(trace_spinTxComplete);
-	while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}
+	while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))
+	{
+		__WFE(); // Wait for event
+	}
 
 #if FIFODEBUG
 	if (!scsiPhyFifoAltEmpty()) {
@@ -382,6 +399,7 @@ scsiWrite(const uint8_t* data, uint32_t count)
 
 		while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))
 		{
+			__WFE(); // Wait for event
 		}
 
 #if FIFODEBUG
@@ -397,6 +415,7 @@ scsiWrite(const uint8_t* data, uint32_t count)
 	}
 	while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))
 	{
+		__WFE(); // Wait for event
 	}
 
 #if FIFODEBUG
@@ -450,10 +469,11 @@ void scsiEnterPhase(int phase)
 				// SCSI2 FAST Timing. 10MB/s.
 				*SCSI_CTRL_DESKEW = SCSI_FAST10_DESKEW;
 				*SCSI_CTRL_TIMING = SCSI_FAST10_TIMING;
-			} else {
-				// 5MB/s Timing
-				*SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW;
-				*SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;
+			}
+			else
+			{
+				*SCSI_CTRL_DESKEW = SCSI_SYNC_DESKEW(scsiDev.target->syncPeriod);
+				*SCSI_CTRL_TIMING = SCSI_SYNC_TIMING(scsiDev.target->syncPeriod);
 			}
 
 			*SCSI_CTRL_SYNC_OFFSET = scsiDev.target->syncOffset;
@@ -675,6 +695,8 @@ void scsiPhyInit()
 	*SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW;
 	*SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;
 
+	*SCSI_CTRL_SEL_TIMING = SCSI_DEFAULT_SELECTION;
+
 }
 
 void scsiPhyConfig()
@@ -706,6 +728,9 @@ void scsiPhyConfig()
 		((scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY) ?
 			SCSI_CTRL_FLAGS_ENABLE_PARITY : 0);
 
+	*SCSI_CTRL_SEL_TIMING =
+		(scsiDev.boardCfg.flags & S2S_CFG_ENABLE_SEL_LATCH) ?
+			SCSI_FAST_SELECTION : SCSI_DEFAULT_SELECTION;
 }
 
 

+ 6 - 0
lib/SCSI2SD/src/firmware/scsiPhy.h

@@ -31,6 +31,7 @@
 #define SCSI_CTRL_FLAGS ((volatile uint8_t*)0x60000016)
 #define SCSI_CTRL_FLAGS_DISABLE_GLITCH 0x1
 #define SCSI_CTRL_FLAGS_ENABLE_PARITY 0x2
+#define SCSI_CTRL_SEL_TIMING ((volatile uint8_t*)0x60000018)
 
 #define SCSI_STS_FIFO ((volatile uint8_t*)0x60000020)
 #define SCSI_STS_ALTFIFO ((volatile uint8_t*)0x60000022)
@@ -55,6 +56,11 @@
 }
 
 #define scsiPhyTx(val) *SCSI_FIFO_DATA = (val)
+
+// little endian specific !. Also relies on the fsmc outputting the lower
+// half-word first.
+#define scsiPhyTx32(a,b) *((volatile uint32_t*)SCSI_FIFO_DATA) = (((uint32_t)(b)) << 16) | (a)
+
 #define scsiPhyRx() *SCSI_FIFO_DATA
 #define scsiPhyComplete() ((*SCSI_STS_FIFO_COMPLETE & 0x01) == 0x01)
 

+ 6 - 208
lib/SCSI2SD/src/firmware/sd.c

@@ -96,155 +96,6 @@ void sdCompleteTransfer()
 }
 
 
-#if 0
-void
-sdWriteMultiSectorDMA(uint8_t* outputBuffer)
-{
-	static uint8_t dmaRxTd[2] = { CY_DMA_INVALID_TD, CY_DMA_INVALID_TD};
-	static uint8_t dmaTxTd[3] = { CY_DMA_INVALID_TD, CY_DMA_INVALID_TD, CY_DMA_INVALID_TD};
-	if (unlikely(dmaRxTd[0] == CY_DMA_INVALID_TD))
-	{
-		dmaRxTd[0] = CyDmaTdAllocate();
-		dmaRxTd[1] = CyDmaTdAllocate();
-		dmaTxTd[0] = CyDmaTdAllocate();
-		dmaTxTd[1] = CyDmaTdAllocate();
-		dmaTxTd[2] = CyDmaTdAllocate();
-
-		// Transmit 512 bytes of data and then 2 bytes CRC, and then get the response byte
-		// We need to do this without stopping the clock
-		CyDmaTdSetConfiguration(dmaTxTd[0], 2, dmaTxTd[1], TD_INC_SRC_ADR);
-		CyDmaTdSetAddress(dmaTxTd[0], LO16((uint32)&writeStartToken), LO16((uint32)SDCard_TXDATA_PTR));
-
-		CyDmaTdSetConfiguration(dmaTxTd[1], SD_SECTOR_SIZE, dmaTxTd[2], TD_INC_SRC_ADR);
-
-		CyDmaTdSetConfiguration(dmaTxTd[2], 2 + sizeof(writeResponseBuffer), CY_DMA_DISABLE_TD, SD_TX_DMA__TD_TERMOUT_EN);
-		CyDmaTdSetAddress(dmaTxTd[2], LO16((uint32)&dummyBuffer), LO16((uint32)SDCard_TXDATA_PTR));
-
-		CyDmaTdSetConfiguration(dmaRxTd[0], SD_SECTOR_SIZE + 4, dmaRxTd[1], 0);
-		CyDmaTdSetAddress(dmaRxTd[0], LO16((uint32)SDCard_RXDATA_PTR), LO16((uint32)&discardBuffer));
-		CyDmaTdSetConfiguration(dmaRxTd[1], sizeof(writeResponseBuffer), CY_DMA_DISABLE_TD, SD_RX_DMA__TD_TERMOUT_EN|TD_INC_DST_ADR);
-		CyDmaTdSetAddress(dmaRxTd[1], LO16((uint32)SDCard_RXDATA_PTR), LO16((uint32)&writeResponseBuffer));
-	}
-	CyDmaTdSetAddress(dmaTxTd[1], LO16((uint32)outputBuffer), LO16((uint32)SDCard_TXDATA_PTR));
-
-
-	// The DMA controller is a bit trigger-happy. It will retain
-	// a drq request that was triggered while the channel was
-	// disabled.
-	CyDmaChSetRequest(sdDMATxChan, CY_DMA_CPU_REQ);
-	CyDmaClearPendingDrq(sdDMARxChan);
-
-	sdTxDMAComplete = 0;
-	sdRxDMAComplete = 0;
-
-	// Re-loading the initial TD's here is very important, or else
-	// we'll be re-using the last-used TD, which would be the last
-	// in the chain (ie. CRC TD)
-	CyDmaChSetInitialTd(sdDMARxChan, dmaRxTd[0]);
-	CyDmaChSetInitialTd(sdDMATxChan, dmaTxTd[0]);
-
-	// There is no flow control, so we must ensure we can read the bytes
-	// before we start transmitting
-	CyDmaChEnable(sdDMARxChan, 1);
-	CyDmaChEnable(sdDMATxChan, 1);
-}
-
-int
-sdWriteSectorDMAPoll()
-{
-	if (sdRxDMAComplete && sdTxDMAComplete)
-	{
-		if (sdIOState == SD_DMA)
-		{
-			// Retry a few times. The data token format is:
-			// XXX0AAA1
-			int i = 0;
-			uint8_t dataToken;
-			do
-			{
-				dataToken = writeResponseBuffer[i]; // Response
-				++i;
-			} while (((dataToken & 0x0101) != 1) && (i < sizeof(writeResponseBuffer)));
-
-			// At this point we should either have an accepted token, or we'll
-			// timeout and proceed into the error case below.
-			if (unlikely(((dataToken & 0x1F) >> 1) != 0x2)) // Accepted.
-			{
-				sdIOState = SD_IDLE;
-
-				sdWaitWriteBusy();
-				sdSpiByte(0xFD); // STOP TOKEN
-				sdWaitWriteBusy();
-
-				sdCmdState = CMD_STATE_IDLE;
-				scsiDiskReset();
-				sdClearStatus();
-
-				scsiDev.status = CHECK_CONDITION;
-				scsiDev.target->sense.code = HARDWARE_ERROR;
-				scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
-				scsiDev.phase = STATUS;
-			}
-			else
-			{
-				sdIOState = SD_ACCEPTED;
-			}
-		}
-
-		if (sdIOState == SD_ACCEPTED)
-		{
-			// Wait while the SD card is busy
-			if (sdSpiByte(0xFF) == 0xFF)
-			{
-				sdIOState = SD_IDLE;
-			}
-		}
-
-		return sdIOState == SD_IDLE;
-	}
-	else
-	{
-		return 0;
-	}
-}
-
-static void sdCompleteWrite()
-{
-	if (unlikely(sdIOState != SD_IDLE))
-	{
-		// Not much choice but to wait until we've completed the transfer.
-		// Cancelling the transfer can't be done as we have no way to reset
-		// the SD card.
-		trace(trace_spinSDCompleteWrite);
-		while (!sdWriteSectorDMAPoll()) { /* spin */ }
-	}
-
-	if (sdCmdState == CMD_STATE_WRITE)
-	{
-		sdWaitWriteBusy();
-
-		sdSpiByte(0xFD); // STOP TOKEN
-
-		sdWaitWriteBusy();
-	}
-
-
-	if (likely(scsiDev.phase == DATA_OUT))
-	{
-		uint16_t r2 = sdDoCommand(SD_SEND_STATUS, 0, 0, 1);
-		if (unlikely(r2))
-		{
-			sdClearStatus();
-			scsiDev.status = CHECK_CONDITION;
-			scsiDev.target->sense.code = HARDWARE_ERROR;
-			scsiDev.target->sense.asc = WRITE_ERROR_AUTO_REALLOCATION_FAILED;
-			scsiDev.phase = STATUS;
-		}
-	}
-	sdCmdState = CMD_STATE_IDLE;
-}
-
-#endif
 static void sdInitDMA()
 {
 	// One-time init only.
@@ -300,8 +151,13 @@ static int sdDoInit()
 		result = 1;
 
 		// SD Benchmark code
-		// Currently 8MB/s
+		// Currently 10MB/s in high-speed mode.
 		#ifdef SD_BENCHMARK
+		if (HAL_SD_HighSpeed(&hsd) == SD_OK) // normally done in mainLoop()
+		{
+			s2s_setFastClock();
+		}
+
 		while(1)
 		{
 			s2s_ledOn();
@@ -333,64 +189,6 @@ out:
 	return result;
 }
 
-#if 0
-void sdWriteMultiSectorPrep(uint32_t sdLBA, uint32_t sdSectors)
-{
-	uint32_t tmpNextLBA = sdLBA + sdSectors;
-
-	if (!sdDev.ccs)
-	{
-		sdLBA = sdLBA * SD_SECTOR_SIZE;
-		tmpNextLBA = tmpNextLBA * SD_SECTOR_SIZE;
-	}
-
-	if (sdCmdState == CMD_STATE_WRITE && sdCmdNextLBA == sdLBA)
-	{
-		// Well, that was lucky. We're already writing this data
-		sdCmdNextLBA = tmpNextLBA;
-		sdCmdTime = getTime_ms();
-	}
-	else
-	{
-		sdPreCmdState(CMD_STATE_WRITE);
-
-		// Set the number of blocks to pre-erase by the multiple block write
-		// command. We don't care about the response - if the command is not
-		// accepted, writes will just be a bit slower. Max 22bit parameter.
-		uint32 blocks = sdSectors > 0x7FFFFF ? 0x7FFFFF : sdSectors;
-		sdCommandAndResponse(SD_APP_CMD, 0);
-		sdCommandAndResponse(SD_APP_SET_WR_BLK_ERASE_COUNT, blocks);
-
-		uint8_t v = sdCommandAndResponse(SD_WRITE_MULTIPLE_BLOCK, sdLBA);
-		if (unlikely(v))
-		{
-			scsiDiskReset();
-			sdClearStatus();
-			scsiDev.status = CHECK_CONDITION;
-			scsiDev.target->sense.code = HARDWARE_ERROR;
-			scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
-			scsiDev.phase = STATUS;
-		}
-		else
-		{
-			sdCmdTime = getTime_ms();
-			sdCmdNextLBA = tmpNextLBA;
-			sdCmdState = CMD_STATE_WRITE;
-		}
-	}
-}
-
-void sdPoll()
-{
-	if ((scsiDev.phase == BUS_FREE) &&
-		(sdCmdState != CMD_STATE_IDLE) &&
-		(elapsedTime_ms(sdCmdTime) >= 50))
-	{
-		sdPreCmdState(CMD_STATE_IDLE);
-	}
-}
-
-#endif
 int sdInit()
 {
 	// Check if there's an SD card present.

+ 1 - 1
lib/SCSI2SD/src/scsi2sd-util6/scsi2sd-util.cc

@@ -543,7 +543,7 @@ private:
 			ss << "dfu-util ";
 		} else {
 			wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
-			ss << exePath.GetPathWithSep() << "dfu-util ";
+			ss << '"' << exePath.GetPathWithSep() << "dfu-util\" ";
 		}
 		ss << "--download \"" << filename.c_str() << "\" --alt 0 --reset";
 #endif

+ 3 - 2
lib/SCSI2SD/src/scsi2sd-util6/wxWidgets/src/stc/scintilla/src/Editor.cxx

@@ -11,6 +11,7 @@
 #include <ctype.h>
 #include <assert.h>
 
+#include <cmath>
 #include <string>
 #include <vector>
 #include <map>
@@ -5841,9 +5842,9 @@ void Editor::GoToLine(int lineNo) {
 }
 
 static bool Close(Point pt1, Point pt2) {
-	if (abs(pt1.x - pt2.x) > 3)
+	if (std::abs(pt1.x - pt2.x) > 3)
 		return false;
-	if (abs(pt1.y - pt2.y) > 3)
+	if (std::abs(pt1.y - pt2.y) > 3)
 		return false;
 	return true;
 }