+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.
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
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
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 \
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 \
SRC = \
src/firmware/bootloader.c \
+ src/firmware/bsp.c \
src/firmware/cdrom.c \
src/firmware/config.c \
src/firmware/disk.c \
__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;
+++ /dev/null
-/**
- ******************************************************************************
- * 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****/
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
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
/*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 */
/*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 */
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;
#include "stm32f2xx_hal.h"
#include "sdio.h"
#include "spi.h"
-#include "tim.h"
#include "usart.h"
#include "usb_device.h"
#include "usb_host.h"
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();
while (1)
{
/* USER CODE END WHILE */
- // TODO re-enable MX_USB_HOST_Process();
+ //MX_USB_HOST_Process();
/* USER CODE BEGIN 3 */
mainLoop();
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
+++ /dev/null
-/**
- ******************************************************************************
- * 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****/
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);
// The maximum burst is 16 bytes.
#define S2S_DMA_ALIGN __attribute__((aligned(1024)))
+void s2s_setNormalClock();
+void s2s_setFastClock();
#endif
\r
#include <string.h>\r
\r
-static const uint16_t FIRMWARE_VERSION = 0x060D;\r
+static const uint16_t FIRMWARE_VERSION = 0x060E;\r
\r
// 1 flash row\r
static const uint8_t DEFAULT_CONFIG[128] =\r
response[14] = scsiDev.lastStatus;\r
response[15] = scsiDev.lastSense;\r
response[16] = scsiDev.phase;\r
- response[17] = scsiStatusBSY();\r
- response[18] = scsiStatusSEL();\r
- response[19] = scsiStatusATN();\r
- response[20] = scsiStatusRST();\r
+ response[17] = *SCSI_STS_SCSI;\r
+ response[18] = scsiDev.target != NULL ? scsiDev.target->syncOffset : 0;\r
+ response[19] = scsiDev.target != NULL ? scsiDev.target->syncPeriod : 0;\r
+ response[20] = scsiDev.minSyncPeriod;\r
response[21] = scsiDev.rstCount;\r
response[22] = scsiDev.selCount;\r
response[23] = scsiDev.msgCount;\r
response[28] = scsiDev.lastSenseASC;\r
response[29] = *SCSI_STS_DBX;\r
response[30] = LastTrace;\r
- response[31] = scsiStatusACK();\r
+ response[31] = 0; // Unused\r
hidPacket_send(response, sizeof(response));\r
}\r
\r
{\r
prep += completedDmaSectors;\r
sdActive -= completedDmaSectors;\r
- } else if (sdActive > 1) {\r
- if (scsiDev.data[SD_SECTOR_SIZE * (prep % buffers) + 511] != 0x33) {\r
+ } else if (sdActive > 1)\r
+ {\r
+ if ((scsiDev.data[SD_SECTOR_SIZE * (prep % buffers) + 510] != 0xAA) ||\r
+ (scsiDev.data[SD_SECTOR_SIZE * (prep % buffers) + 511] != 0x33))\r
+ {\r
prep += 1;\r
sdActive -= 1;\r
}\r
\r
for (int dodgy = 0; dodgy < sectors; dodgy++)\r
{\r
+ scsiDev.data[SD_SECTOR_SIZE * (startBuffer + dodgy) + 510] = 0xAA;\r
scsiDev.data[SD_SECTOR_SIZE * (startBuffer + dodgy) + 511] = 0x33;\r
}\r
\r
}\r
\r
uint16_t* scsiDmaData = (uint16_t*) &(scsiDev.data[SD_SECTOR_SIZE * (i % buffers)]);\r
- for (int k = 0; k < (dmaBytes + 1) / 2; ++k)\r
+ // Manually unrolled loop for performance.\r
+ // -Os won't unroll this for us automatically,\r
+ // especially since scsiPhyTx does volatile stuff.\r
+ // Reduces bus utilisation by making the fsmc split\r
+ // 32bits into 2 16 bit writes.\r
+ int k = 0;\r
+ for (; k + 4 < (dmaBytes + 1) / 2; k += 4)\r
+ {\r
+ scsiPhyTx32(scsiDmaData[k], scsiDmaData[k+1]);\r
+ scsiPhyTx32(scsiDmaData[k+2], scsiDmaData[k+3]);\r
+ }\r
+ for (; k < (dmaBytes + 1) / 2; ++k)\r
{\r
scsiPhyTx(scsiDmaData[k]);\r
}\r
i++;\r
- while (!scsiPhyComplete() && !scsiDev.resetFlag) {}\r
+ while (!scsiPhyComplete() && !scsiDev.resetFlag)\r
+ {\r
+ __WFE(); // Wait for event\r
+ }\r
scsiPhyFifoFlip();\r
scsiSetDataCount(dmaBytes);\r
}\r
likely(scsiDev.phase == DATA_IN) &&\r
likely(!scsiDev.resetFlag))\r
{\r
+ __WFE(); // Wait for event\r
}\r
\r
\r
#include "stm32f2xx.h"\r
\r
#include "config.h"\r
+#include "bsp.h"\r
#include "disk.h"\r
#include "fpga.h"\r
#include "led.h"\r
#include "scsiPhy.h"\r
#include "time.h"\r
#include "trace.h"\r
+#include "sdio.h"\r
#include "usb_device/usb_device.h"\r
#include "usb_device/usbd_composite.h"\r
#include "usb_device/usbd_msc_storage_sd.h"\r
const char* Notice = "Copyright (C) 2016 Michael McMaster <michael@codesrc.com>";\r
uint32_t lastSDPoll;\r
\r
+static int isUsbStarted;\r
+\r
void mainEarlyInit()\r
{\r
// USB device is initialised before mainInit is called\r
scsiInit();\r
\r
MX_USB_DEVICE_Init(); // USB lun config now available.\r
+ isUsbStarted = 1;\r
\r
// Optional bootup delay\r
int delaySeconds = 0;\r
scsiPhyConfig();\r
scsiInit();\r
\r
+ // Is a USB host connected ?\r
+ if (isUsbStarted)\r
+ {\r
+ USBD_Stop(&hUsbDeviceFS);\r
+ s2s_delay_ms(128);\r
+ USBD_Start(&hUsbDeviceFS);\r
+ }\r
+ }\r
+\r
+ // Can we speed up the SD card ?\r
+ // Don't combine with the above block because that won't\r
+ // run if the SD card is present at startup.\r
+ // Don't use VBUS monitoring because that just tells us about\r
+ // power, which could be from a charger\r
+ if ((blockDev.state & DISK_PRESENT) &&\r
+ isUsbStarted &&\r
+ (scsiDev.cmdCount > 0) && // no need for speed without scsi\r
+ !USBD_Composite_IsConfigured(&hUsbDeviceFS))\r
+ {\r
+ if (HAL_SD_HighSpeed(&hsd) == SD_OK)\r
+ {\r
+ USBD_Stop(&hUsbDeviceFS);\r
+ s2s_setFastClock();\r
+ isUsbStarted = 0;\r
+ }\r
+ }\r
\r
- USBD_Stop(&hUsbDeviceFS);\r
- s2s_delay_ms(128);\r
+ else if (!(blockDev.state & DISK_PRESENT) && !isUsbStarted)\r
+ {\r
+ // Good time to restart USB.\r
+ s2s_setNormalClock();\r
USBD_Start(&hUsbDeviceFS);\r
+ isUsbStarted = 1;\r
}\r
}\r
else\r
\r
s2s_ledOff();\r
scsiDev.phase = BUS_FREE;\r
+ scsiDev.selFlag = 0;\r
}\r
\r
static void enter_MessageIn(uint8_t message)\r
scsiDev.phase = BUS_FREE;\r
scsiDev.atnFlag = 0;\r
scsiDev.resetFlag = 0;\r
+ scsiDev.selFlag = 0;\r
scsiDev.lun = -1;\r
scsiDev.compatMode = COMPAT_UNKNOWN;\r
\r
scsiDev.target[i].syncOffset = 0;\r
scsiDev.target[i].syncPeriod = 0;\r
}\r
+ scsiDev.minSyncPeriod = 0;\r
\r
scsiDiskReset();\r
\r
}\r
\r
uint8_t selStatus = *SCSI_STS_SELECTED;\r
+ if ((selStatus == 0) && (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_SEL_LATCH))\r
+ {\r
+ selStatus = scsiDev.selFlag;\r
+ }\r
\r
int tgtIndex;\r
TargetState* target = NULL;\r
{\r
scsiDev.phase = BUS_BUSY;\r
}\r
+ scsiDev.selFlag = 0;\r
}\r
\r
static void process_MessageOut()\r
int transferPeriod = extmsg[1];\r
int offset = extmsg[2];\r
\r
- if ((scsiDev.compatMode < COMPAT_SCSI2) ||\r
- (transferPeriod > 50)) // 200ns, 5MB/s\r
+ if ((transferPeriod < scsiDev.minSyncPeriod) ||\r
+ (scsiDev.minSyncPeriod == 0))\r
+ {\r
+ scsiDev.minSyncPeriod = transferPeriod;\r
+ }\r
+\r
+ if ((transferPeriod > 80) || // 320ns, 3.125MB/s\r
+ // Amiga A590 (WD33C93 chip) only does 3.5MB/s sync\r
+ // After 80 we start to run out of bits in the fpga timing\r
+ // register.\r
+ (transferPeriod == 0))\r
{\r
scsiDev.target->syncOffset = 0;\r
scsiDev.target->syncPeriod = 0;\r
} else {\r
- scsiDev.target->syncOffset = offset < 15 ? offset : 15;\r
+ scsiDev.target->syncOffset = offset < 63 ? offset : 63;\r
// FAST20 / 50ns / 20MHz is disabled for now due to\r
// data corruption while reading data. We can count the\r
// ACK's correctly, but can't save the data to a register\r
{\r
scsiDev.target->syncPeriod = 25; // 100ns, 10MB/s\r
} else {\r
- scsiDev.target->syncPeriod = 50; // 200ns, 5MB/s\r
+ scsiDev.target->syncPeriod = transferPeriod;\r
}\r
}\r
\r
// one initiator in the chain. Support this by moving\r
// straight to selection if SEL is asserted.\r
// ie. the initiator won't assert BSY and it's own ID before moving to selection.\r
- else if (*SCSI_STS_SELECTED)\r
+ else if (scsiDev.selFlag || *SCSI_STS_SELECTED)\r
{\r
enter_SelectionPhase();\r
}\r
case BUS_BUSY:\r
// Someone is using the bus. Perhaps they are trying to\r
// select us.\r
- if (*SCSI_STS_SELECTED)\r
+ if (scsiDev.selFlag || *SCSI_STS_SELECTED)\r
{\r
enter_SelectionPhase();\r
}\r
\r
scsiDev.atnFlag = 0;\r
scsiDev.resetFlag = 1;\r
+ scsiDev.selFlag = 0;\r
scsiDev.phase = BUS_FREE;\r
scsiDev.target = NULL;\r
scsiDev.compatMode = COMPAT_UNKNOWN;\r
// 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;
uint8_t lastStatus;
uint8_t lastSense;
uint16_t lastSenseASC;
+ uint8_t minSyncPeriod; // Debug use only.
int needSyncNegotiationAck;
} ScsiDevice;
\r
#include <string.h>\r
\r
-// 5MB/s sync and async.\r
-// Assumes a 96MHz fpga clock.\r
+// Time until we consider ourselves selected\r
+// 400ns at 108MHz\r
+#define SCSI_DEFAULT_SELECTION 43\r
+#define SCSI_FAST_SELECTION 5\r
+\r
+// async.\r
+// Assumes a 108MHz fpga clock.\r
// 2:0 Deskew count, 55ns\r
// 6:4 Hold count, 53ns\r
// 3:0 Assertion count, 80ns\r
#define SCSI_DEFAULT_DESKEW 0x6\r
-#define SCSI_DEFAULT_TIMING ((0x5 << 4) | 0x8)\r
+#define SCSI_DEFAULT_TIMING ((0x6 << 4) | 0x9)\r
+\r
+// 3.125MB/s (80 period) to < 10MB/s sync\r
+// Assumes a 108MHz fpga clock. (9 ns)\r
+// (((period * 4) / 2) * 0.8) / 9\r
+// Done using 3 fixed point math.\r
+// 2:0 Deskew count, 55ns normal, or 25ns if faster than 5.5MB/s\r
+// 6:4 Hold count, 53ns normal, or 33ns if faster than 5.5MB/s\r
+// 3:0 Assertion count, variable\r
+#define SCSI_SYNC_DESKEW(period) (period < 45 ? SCSI_FAST10_DESKEW : SCSI_DEFAULT_DESKEW)\r
+#define SCSI_SYNC_TIMING(period) (((period < 45 ? 0x4 : 0x6) << 4) | ((((((int)period) * 177) + 750)/1000) & 0xF))\r
\r
// 10MB/s\r
// 2:0 Deskew count, 25ns\r
// 6:4 Hold count, 33ns\r
// 3:0 Assertion count, 30ns\r
-#define SCSI_FAST10_DESKEW 3\r
+// We want deskew + hold + assert + 3 to add up to 11 clocks\r
+// the fpga code has 1 clock of overhead when transitioning from deskew to\r
+// assert to hold\r
+#define SCSI_FAST10_DESKEW 2\r
#define SCSI_FAST10_TIMING ((0x3 << 4) | 0x3)\r
\r
// 20MB/s\r
// 2:0 Deskew count, 12ns\r
// 6:4 Hold count, 17ns\r
// 3:0 Assertion count, 15ns\r
-#define SCSI_FAST20_DESKEW 2\r
+#define SCSI_FAST20_DESKEW 1\r
#define SCSI_FAST20_TIMING ((0x2 << 4) | 0x2)\r
\r
// Private DMA variables.\r
volatile uint8_t scsiRxDMAComplete;\r
volatile uint8_t scsiTxDMAComplete;\r
\r
-#if 0\r
-CY_ISR_PROTO(scsiRxCompleteISR);\r
-CY_ISR(scsiRxCompleteISR)\r
-{\r
- traceIrq(trace_scsiRxCompleteISR);\r
- scsiRxDMAComplete = 1;\r
-}\r
-\r
-CY_ISR_PROTO(scsiTxCompleteISR);\r
-CY_ISR(scsiTxCompleteISR)\r
-{\r
- traceIrq(trace_scsiTxCompleteISR);\r
- scsiTxDMAComplete = 1;\r
-}\r
-#endif\r
-\r
uint8_t scsiPhyFifoSel = 0; // global\r
\r
// scsi IRQ handler is initialised by the STM32 HAL. Connected to\r
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_4);\r
\r
scsiDev.resetFlag = scsiDev.resetFlag || scsiStatusRST();\r
- // TODO grab SEL status as well\r
\r
+ // selFlag is required for Philips P2000C which releases it after 600ns\r
+ // without waiting for BSY.\r
+ // Also required for some early Mac Plus roms\r
+ scsiDev.selFlag = *SCSI_STS_SELECTED;\r
}\r
+\r
+ __SEV(); // Set event. See corresponding __WFE() calls.\r
}\r
\r
static void assertFail()\r
scsiSetDataCount(1);\r
\r
trace(trace_spinPhyRxFifo);\r
- while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}\r
+ while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
+ {\r
+ __WFE(); // Wait for event\r
+ }\r
scsiPhyFifoFlip();\r
uint8_t val = scsiPhyRx();\r
// TODO scsiDev.parityError = scsiDev.parityError || SCSI_Parity_Error_Read();\r
scsiReadPIO(uint8_t* data, uint32_t count)\r
{\r
uint16_t* fifoData = (uint16_t*)data;\r
+\r
for (int i = 0; i < (count + 1) / 2; ++i)\r
{\r
fifoData[i] = scsiPhyRx(); // TODO ASSUMES LITTLE ENDIAN\r
\r
while (i < count && likely(!scsiDev.resetFlag))\r
{\r
- while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}\r
+ while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
+ {\r
+ __WFE(); // Wait for event\r
+ }\r
*parityError |= scsiParityError();\r
scsiPhyFifoFlip();\r
\r
scsiSetDataCount(1);\r
\r
trace(trace_spinTxComplete);\r
- while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}\r
+ while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
+ {\r
+ __WFE(); // Wait for event\r
+ }\r
\r
#if FIFODEBUG\r
if (!scsiPhyFifoAltEmpty()) {\r
\r
while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
{\r
+ __WFE(); // Wait for event\r
}\r
\r
#if FIFODEBUG\r
}\r
while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
{\r
+ __WFE(); // Wait for event\r
}\r
\r
#if FIFODEBUG\r
// SCSI2 FAST Timing. 10MB/s.\r
*SCSI_CTRL_DESKEW = SCSI_FAST10_DESKEW;\r
*SCSI_CTRL_TIMING = SCSI_FAST10_TIMING;\r
- } else {\r
- // 5MB/s Timing\r
- *SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW;\r
- *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+ }\r
+ else\r
+ {\r
+ *SCSI_CTRL_DESKEW = SCSI_SYNC_DESKEW(scsiDev.target->syncPeriod);\r
+ *SCSI_CTRL_TIMING = SCSI_SYNC_TIMING(scsiDev.target->syncPeriod);\r
}\r
\r
*SCSI_CTRL_SYNC_OFFSET = scsiDev.target->syncOffset;\r
*SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW;\r
*SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
\r
+ *SCSI_CTRL_SEL_TIMING = SCSI_DEFAULT_SELECTION;\r
+\r
}\r
\r
void scsiPhyConfig()\r
((scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY) ?\r
SCSI_CTRL_FLAGS_ENABLE_PARITY : 0);\r
\r
+ *SCSI_CTRL_SEL_TIMING =\r
+ (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_SEL_LATCH) ?\r
+ SCSI_FAST_SELECTION : SCSI_DEFAULT_SELECTION;\r
}\r
\r
\r
#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)
}
#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)
}\r
\r
\r
-#if 0\r
-void\r
-sdWriteMultiSectorDMA(uint8_t* outputBuffer)\r
-{\r
- static uint8_t dmaRxTd[2] = { CY_DMA_INVALID_TD, CY_DMA_INVALID_TD};\r
- static uint8_t dmaTxTd[3] = { CY_DMA_INVALID_TD, CY_DMA_INVALID_TD, CY_DMA_INVALID_TD};\r
- if (unlikely(dmaRxTd[0] == CY_DMA_INVALID_TD))\r
- {\r
- dmaRxTd[0] = CyDmaTdAllocate();\r
- dmaRxTd[1] = CyDmaTdAllocate();\r
- dmaTxTd[0] = CyDmaTdAllocate();\r
- dmaTxTd[1] = CyDmaTdAllocate();\r
- dmaTxTd[2] = CyDmaTdAllocate();\r
-\r
- // Transmit 512 bytes of data and then 2 bytes CRC, and then get the response byte\r
- // We need to do this without stopping the clock\r
- CyDmaTdSetConfiguration(dmaTxTd[0], 2, dmaTxTd[1], TD_INC_SRC_ADR);\r
- CyDmaTdSetAddress(dmaTxTd[0], LO16((uint32)&writeStartToken), LO16((uint32)SDCard_TXDATA_PTR));\r
-\r
- CyDmaTdSetConfiguration(dmaTxTd[1], SD_SECTOR_SIZE, dmaTxTd[2], TD_INC_SRC_ADR);\r
-\r
- CyDmaTdSetConfiguration(dmaTxTd[2], 2 + sizeof(writeResponseBuffer), CY_DMA_DISABLE_TD, SD_TX_DMA__TD_TERMOUT_EN);\r
- CyDmaTdSetAddress(dmaTxTd[2], LO16((uint32)&dummyBuffer), LO16((uint32)SDCard_TXDATA_PTR));\r
-\r
- CyDmaTdSetConfiguration(dmaRxTd[0], SD_SECTOR_SIZE + 4, dmaRxTd[1], 0);\r
- CyDmaTdSetAddress(dmaRxTd[0], LO16((uint32)SDCard_RXDATA_PTR), LO16((uint32)&discardBuffer));\r
- CyDmaTdSetConfiguration(dmaRxTd[1], sizeof(writeResponseBuffer), CY_DMA_DISABLE_TD, SD_RX_DMA__TD_TERMOUT_EN|TD_INC_DST_ADR);\r
- CyDmaTdSetAddress(dmaRxTd[1], LO16((uint32)SDCard_RXDATA_PTR), LO16((uint32)&writeResponseBuffer));\r
- }\r
- CyDmaTdSetAddress(dmaTxTd[1], LO16((uint32)outputBuffer), LO16((uint32)SDCard_TXDATA_PTR));\r
-\r
-\r
- // The DMA controller is a bit trigger-happy. It will retain\r
- // a drq request that was triggered while the channel was\r
- // disabled.\r
- CyDmaChSetRequest(sdDMATxChan, CY_DMA_CPU_REQ);\r
- CyDmaClearPendingDrq(sdDMARxChan);\r
-\r
- sdTxDMAComplete = 0;\r
- sdRxDMAComplete = 0;\r
-\r
- // Re-loading the initial TD's here is very important, or else\r
- // we'll be re-using the last-used TD, which would be the last\r
- // in the chain (ie. CRC TD)\r
- CyDmaChSetInitialTd(sdDMARxChan, dmaRxTd[0]);\r
- CyDmaChSetInitialTd(sdDMATxChan, dmaTxTd[0]);\r
-\r
- // There is no flow control, so we must ensure we can read the bytes\r
- // before we start transmitting\r
- CyDmaChEnable(sdDMARxChan, 1);\r
- CyDmaChEnable(sdDMATxChan, 1);\r
-}\r
-\r
-int\r
-sdWriteSectorDMAPoll()\r
-{\r
- if (sdRxDMAComplete && sdTxDMAComplete)\r
- {\r
- if (sdIOState == SD_DMA)\r
- {\r
- // Retry a few times. The data token format is:\r
- // XXX0AAA1\r
- int i = 0;\r
- uint8_t dataToken;\r
- do\r
- {\r
- dataToken = writeResponseBuffer[i]; // Response\r
- ++i;\r
- } while (((dataToken & 0x0101) != 1) && (i < sizeof(writeResponseBuffer)));\r
-\r
- // At this point we should either have an accepted token, or we'll\r
- // timeout and proceed into the error case below.\r
- if (unlikely(((dataToken & 0x1F) >> 1) != 0x2)) // Accepted.\r
- {\r
- sdIOState = SD_IDLE;\r
-\r
- sdWaitWriteBusy();\r
- sdSpiByte(0xFD); // STOP TOKEN\r
- sdWaitWriteBusy();\r
-\r
- sdCmdState = CMD_STATE_IDLE;\r
- scsiDiskReset();\r
- sdClearStatus();\r
-\r
- scsiDev.status = CHECK_CONDITION;\r
- scsiDev.target->sense.code = HARDWARE_ERROR;\r
- scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;\r
- scsiDev.phase = STATUS;\r
- }\r
- else\r
- {\r
- sdIOState = SD_ACCEPTED;\r
- }\r
- }\r
-\r
- if (sdIOState == SD_ACCEPTED)\r
- {\r
- // Wait while the SD card is busy\r
- if (sdSpiByte(0xFF) == 0xFF)\r
- {\r
- sdIOState = SD_IDLE;\r
- }\r
- }\r
-\r
- return sdIOState == SD_IDLE;\r
- }\r
- else\r
- {\r
- return 0;\r
- }\r
-}\r
-\r
-static void sdCompleteWrite()\r
-{\r
- if (unlikely(sdIOState != SD_IDLE))\r
- {\r
- // Not much choice but to wait until we've completed the transfer.\r
- // Cancelling the transfer can't be done as we have no way to reset\r
- // the SD card.\r
- trace(trace_spinSDCompleteWrite);\r
- while (!sdWriteSectorDMAPoll()) { /* spin */ }\r
- }\r
-\r
- if (sdCmdState == CMD_STATE_WRITE)\r
- {\r
- sdWaitWriteBusy();\r
-\r
- sdSpiByte(0xFD); // STOP TOKEN\r
-\r
- sdWaitWriteBusy();\r
- }\r
-\r
-\r
- if (likely(scsiDev.phase == DATA_OUT))\r
- {\r
- uint16_t r2 = sdDoCommand(SD_SEND_STATUS, 0, 0, 1);\r
- if (unlikely(r2))\r
- {\r
- sdClearStatus();\r
- scsiDev.status = CHECK_CONDITION;\r
- scsiDev.target->sense.code = HARDWARE_ERROR;\r
- scsiDev.target->sense.asc = WRITE_ERROR_AUTO_REALLOCATION_FAILED;\r
- scsiDev.phase = STATUS;\r
- }\r
- }\r
- sdCmdState = CMD_STATE_IDLE;\r
-}\r
-\r
-#endif\r
static void sdInitDMA()\r
{\r
// One-time init only.\r
result = 1;\r
\r
// SD Benchmark code\r
- // Currently 8MB/s\r
+ // Currently 10MB/s in high-speed mode.\r
#ifdef SD_BENCHMARK\r
+ if (HAL_SD_HighSpeed(&hsd) == SD_OK) // normally done in mainLoop()\r
+ {\r
+ s2s_setFastClock();\r
+ }\r
+\r
while(1)\r
{\r
s2s_ledOn();\r
return result;\r
}\r
\r
-#if 0\r
-void sdWriteMultiSectorPrep(uint32_t sdLBA, uint32_t sdSectors)\r
-{\r
- uint32_t tmpNextLBA = sdLBA + sdSectors;\r
-\r
- if (!sdDev.ccs)\r
- {\r
- sdLBA = sdLBA * SD_SECTOR_SIZE;\r
- tmpNextLBA = tmpNextLBA * SD_SECTOR_SIZE;\r
- }\r
-\r
- if (sdCmdState == CMD_STATE_WRITE && sdCmdNextLBA == sdLBA)\r
- {\r
- // Well, that was lucky. We're already writing this data\r
- sdCmdNextLBA = tmpNextLBA;\r
- sdCmdTime = getTime_ms();\r
- }\r
- else\r
- {\r
- sdPreCmdState(CMD_STATE_WRITE);\r
-\r
- // Set the number of blocks to pre-erase by the multiple block write\r
- // command. We don't care about the response - if the command is not\r
- // accepted, writes will just be a bit slower. Max 22bit parameter.\r
- uint32 blocks = sdSectors > 0x7FFFFF ? 0x7FFFFF : sdSectors;\r
- sdCommandAndResponse(SD_APP_CMD, 0);\r
- sdCommandAndResponse(SD_APP_SET_WR_BLK_ERASE_COUNT, blocks);\r
-\r
- uint8_t v = sdCommandAndResponse(SD_WRITE_MULTIPLE_BLOCK, sdLBA);\r
- if (unlikely(v))\r
- {\r
- scsiDiskReset();\r
- sdClearStatus();\r
- scsiDev.status = CHECK_CONDITION;\r
- scsiDev.target->sense.code = HARDWARE_ERROR;\r
- scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;\r
- scsiDev.phase = STATUS;\r
- }\r
- else\r
- {\r
- sdCmdTime = getTime_ms();\r
- sdCmdNextLBA = tmpNextLBA;\r
- sdCmdState = CMD_STATE_WRITE;\r
- }\r
- }\r
-}\r
-\r
-void sdPoll()\r
-{\r
- if ((scsiDev.phase == BUS_FREE) &&\r
- (sdCmdState != CMD_STATE_IDLE) &&\r
- (elapsedTime_ms(sdCmdTime) >= 50))\r
- {\r
- sdPreCmdState(CMD_STATE_IDLE);\r
- }\r
-}\r
-\r
-#endif\r
int sdInit()\r
{\r
// Check if there's an SD card present.\r
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
#include <ctype.h>
#include <assert.h>
+#include <cmath>
#include <string>
#include <vector>
#include <map>
}
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;
}