From d3137d41ac8a457846c003143a5005896ea5276d Mon Sep 17 00:00:00 2001 From: Michael McMaster Date: Sun, 19 Apr 2020 19:09:10 +1000 Subject: [PATCH] Fix hardware version checks for V6 revF and older boards --- STM32CubeMX/SCSI2SD-V6/Src/gpio.c | 10 ++- src/firmware/hwversion.c | 102 ++++++++++++++++++++++++++++++ src/firmware/hwversion.h | 23 +++++++ 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100755 src/firmware/hwversion.c create mode 100755 src/firmware/hwversion.h diff --git a/STM32CubeMX/SCSI2SD-V6/Src/gpio.c b/STM32CubeMX/SCSI2SD-V6/Src/gpio.c index 5682f257..78bc6069 100755 --- a/STM32CubeMX/SCSI2SD-V6/Src/gpio.c +++ b/STM32CubeMX/SCSI2SD-V6/Src/gpio.c @@ -90,12 +90,18 @@ void MX_GPIO_Init(void) PCPin PCPin PCPin PCPin PCPin */ GPIO_InitStruct.Pin = UNUSED_PC13_Pin|UNUSED_PC14_Pin|UNUSED_PC15_Pin|UNUSED_PC0_Pin - |UNUSED_PC1_Pin|UNUSED_PC2_Pin|UNUSED_PC3_Pin|UNUSED_PC4_Pin - |UNUSED_PC5_Pin; + |UNUSED_PC1_Pin|UNUSED_PC2_Pin|UNUSED_PC3_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); +// Pins are used to sense scsi2sd hardware version, must be pullup + GPIO_InitStruct.Pin = UNUSED_PC4_Pin|UNUSED_PC5_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /*Configure GPIO pins : PAPin PAPin PAPin PAPin */ GPIO_InitStruct.Pin = UNUSED_PA0_Pin|UNUSED_PA1_Pin|UNUSED_PA2_Pin|UNUSED_PA3_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; diff --git a/src/firmware/hwversion.c b/src/firmware/hwversion.c new file mode 100755 index 00000000..e5b6d579 --- /dev/null +++ b/src/firmware/hwversion.c @@ -0,0 +1,102 @@ +// Copyright (C) 2020 Michael McMaster +// +// This file is part of SCSI2SD. +// +// SCSI2SD is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SCSI2SD is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SCSI2SD. If not, see . + +#include "hwversion.h" +#include "stm32f2xx.h" +#include "config.h" +#include "time.h" + +// Store hardware version details to the "One Time Programmable" flash memory +// This is 512 bytes that can only be written to ONCE and once only. +// It can be read by dfu-util, so once we write the marker it can be +// detected even when the firmware isn't running. + +// Values for STM32F401RE +const size_t OTP_SIZE = 512; +const size_t OTP_BLOCKS = 16; +const size_t OTP_BLOCK_SIZE = OTP_SIZE / OTP_BLOCKS; + +const size_t OTP_BLOCK_NUM = 0; + +// Define some pointers for writing, but also to allow easy reading back values +#define FLASH_OTP_BASE 0x1FFF7800 +const uint8_t *otp = (uint8_t*)(FLASH_OTP_BASE + OTP_BLOCK_NUM * OTP_BLOCK_SIZE); +const uint32_t *otp32 = (uint32_t*)(FLASH_OTP_BASE + OTP_BLOCK_NUM * OTP_BLOCK_SIZE); +const uint8_t *lock = (uint8_t*)(FLASH_OTP_BASE + OTP_SIZE + OTP_BLOCK_NUM); + +const uint32_t marker = 0x06002019; + +static void +checkHwSensePins() +{ + // Check the board version is correct. + // Sense pins are configued as pullup, and connected to GND for 2020 hw, + // or N/C for v6 ref F or older + if ((HAL_GPIO_ReadPin(UNUSED_PC4_GPIO_Port, UNUSED_PC4_Pin) == 0) || + (HAL_GPIO_ReadPin(UNUSED_PC5_GPIO_Port, UNUSED_PC5_Pin) == 0)) + { + // Oh dear, wrong version. Do not pass go. + while (1) {} + } +} + +void +s2s_checkHwVersion() +{ + checkHwSensePins(); + + // Write a marker to flash that can be read by dfu-util now that we know + // the version is correct. + if (*otp32 != marker) + { + // Double-check the pins are good. + s2s_delay_ms(10); + checkHwSensePins(); + + // Well, pins are good. Make sure marker isn't set at all + if (*otp32 != 0xffffffff) + { + // Some other version was set. + while (1) {} + } + + // Write the marker to flash. + if (HAL_FLASH_Unlock() != HAL_OK) + { + return; + } + + // Write 4 bytes to the start of OTP. + if (HAL_FLASH_Program( + FLASH_TYPEPROGRAM_WORD, + (uint32_t)otp, + marker) != HAL_OK) + { + HAL_FLASH_Lock(); + return; + } + + // Lock OTP page + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, (uint32_t)lock, 0x00)) { + HAL_FLASH_Lock(); + return; + } + + HAL_FLASH_Lock(); + } +} + diff --git a/src/firmware/hwversion.h b/src/firmware/hwversion.h new file mode 100755 index 00000000..3ddfe4c2 --- /dev/null +++ b/src/firmware/hwversion.h @@ -0,0 +1,23 @@ +// Copyright (C) 2020 Michael McMaster +// +// This file is part of SCSI2SD. +// +// SCSI2SD is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SCSI2SD is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SCSI2SD. If not, see . + +#ifndef S2S_HWVERSION_H +#define S2S_HWVERSION_H + +void s2s_checkHwVersion(void); + +#endif -- 2.38.5