From 29f256a8d50cc4e185f7ccb9d4447841e06e8ebd Mon Sep 17 00:00:00 2001 From: Bs0Dd Date: Sun, 8 Feb 2026 02:14:55 +0100 Subject: [PATCH 1/3] Fixes from PIMP --- STMP/Src/main.c | 167 ++++++++++++++++++++++++++---------------------- STMP/fatfs/ff.c | 6 +- 2 files changed, 94 insertions(+), 79 deletions(-) diff --git a/STMP/Src/main.c b/STMP/Src/main.c index c1ceacb..aabeae1 100644 --- a/STMP/Src/main.c +++ b/STMP/Src/main.c @@ -31,12 +31,12 @@ static void MX_GPIO_Init(void); static void PVD_Config(); static FRESULT openFile(char *filename) { - DIR dj; - FILINFO fno; - FRESULT fr; + DIR dj; + FILINFO fno; + FRESULT fr; - fr = f_opendir(&dj, ""); - if(fr == FR_OK){ + fr = f_opendir(&dj, ""); + if(fr == FR_OK){ uint32_t i = 0; do { fr = f_readdir(&dj, &fno); @@ -45,37 +45,37 @@ static FRESULT openFile(char *filename) { } } while (fr == FR_OK && i<255 && fno.fname[0] != 0); f_closedir(&dj); - } + } - if(filename != NULL) { - fr = f_open(&appFile, filename, FA_READ); - } + if(filename != NULL) { + fr = f_open(&appFile, filename, FA_READ); + } - if (fr != FR_OK && fileList[0]) { - fr = f_open(&appFile, fileList[0], FA_READ); - } + if (fr != FR_OK && fileList[0]) { + fr = f_open(&appFile, fileList[0], FA_READ); + } - if (fr == FR_OK) { - uint32_t lktbl[256]; + if (fr == FR_OK) { + uint32_t lktbl[256]; lktbl[0] = 256; appFile.cltbl = lktbl; fr = f_lseek(&appFile, CREATE_LINKMAP); } - return fr; + return fr; } static void fastGpioInitOutputPP(GPIO_TypeDef *GPIOx, uint32_t pinNum) { #define GPIO_CR_CNF_GP_OUTPUT_PP 0x00000000U uint32_t position = ((pinNum - 8U) << 2); - MODIFY_REG(GPIOx->CRH, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << position), - ((GPIO_SPEED_FREQ_HIGH + GPIO_CR_CNF_GP_OUTPUT_PP) << position)); + MODIFY_REG(GPIOx->CRH, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << position), + ((GPIO_SPEED_FREQ_HIGH + GPIO_CR_CNF_GP_OUTPUT_PP) << position)); } static void fastGpioInitOutputPP_DATA(void) { #define GPIO_CR_CNF_GP_OUTPUT_OD 0x00000004U - MODIFY_REG(PORT_DATA->CRH, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << ((PIN_DATA_NUM - 8) << 2)), - ((GPIO_SPEED_FREQ_HIGH + GPIO_CR_CNF_GP_OUTPUT_PP) << ((PIN_DATA_NUM - 8) << 2))); + MODIFY_REG(PORT_DATA->CRH, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << ((PIN_DATA_NUM - 8) << 2)), + ((GPIO_SPEED_FREQ_HIGH + GPIO_CR_CNF_GP_OUTPUT_PP) << ((PIN_DATA_NUM - 8) << 2))); } static void fastGpioInitInputPU(GPIO_TypeDef *GPIOx, uint32_t pinNum) { @@ -84,12 +84,12 @@ static void fastGpioInitInputPU(GPIO_TypeDef *GPIOx, uint32_t pinNum) { uint32_t position = (pinNum < 8) ? (pinNum << 2U) : ((pinNum - 8U) << 2U); __IO uint32_t *configregister = (pinNum < 8) ? &GPIOx->CRL : &GPIOx->CRH; GPIOx->BSRR = 0x01U << pinNum; //pull-up - MODIFY_REG(*configregister, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << position), - ((GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD) << position)); + MODIFY_REG(*configregister, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << position), + ((GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD) << position)); } static void fastGpioInitEvtFal(GPIO_TypeDef *GPIOx, uint32_t pinNum) { - __HAL_RCC_AFIO_CLK_ENABLE(); + __HAL_RCC_AFIO_CLK_ENABLE(); MODIFY_REG(AFIO->EXTICR[pinNum >> 2], (0x0F << (4 * (pinNum & 0x03))), (GPIO_GET_INDEX(GPIOx)) << (4 * (pinNum & 0x03))); @@ -151,6 +151,9 @@ static void parseCommand(uint32_t command) { break; } + // read postdecrement + case 0x18: + case 0x10: // read postincrement case 0xD8: case 0xD0: { @@ -159,6 +162,7 @@ static void parseCommand(uint32_t command) { while ((PORT_SELECT->IDR & PIN_SELECT) == GPIO_PIN_RESET) { sendByte(readBuffer); + if ((command & 0xC0) == 0) f_lseek(&appFile, appFile.fptr - 2); // postdecrement f_read_byte(&appFile, &readBuffer); } @@ -170,23 +174,25 @@ static void parseCommand(uint32_t command) { break; } + // Genjitsu: get files list case 0xF0: { fastGpioInitOutputPP_DATA(); uint32_t i = 0; uint32_t j = 0; - do { - j = 0; - do { - sendByte(fileList[i][j]); - } while (fileList[i][j++]); - } while (fileList[i++][0]); + do { + j = 0; + do { + sendByte(fileList[i][j]); + } while (fileList[i][j++]); + } while (fileList[i++][0]); sendByte(0xFF); fastGpioInitInputPU(PORT_DATA, PIN_DATA_NUM); break; } + // Genjitsu: mount selected file case 0xF1: { char filename[12+1] = {0,}; uint32_t i = 0; @@ -201,9 +207,16 @@ static void parseCommand(uint32_t command) { break; } - // unknown command + // Genjitsu: unmount current file and go to the autorun + case 0xF2: { + if (openFile("AUTORUN.BIN") != FR_OK) { + Error_Handler(); + } + break; + } + + // unknown command - just ignore default: { - Error_Handler(); break; } } @@ -225,7 +238,7 @@ int main(void) { HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE); SystemClock_Config(); if(f_mount(&FATFS_Obj, "0", 1) == FR_OK) { - openFile("autorun.bin"); + openFile("AUTORUN.BIN"); } } else { HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFE); @@ -244,40 +257,40 @@ int main(void) { * @retval None */ static void SystemClock_Config(void) { - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + Error_Handler(); + } - /** Initializes the CPU, AHB and APB busses clocks - */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; - RCC_OscInitStruct.HSEState = RCC_HSE_ON; - RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - Error_Handler(); - } - - /** Initializes the CPU, AHB and APB busses clocks - */ - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK - |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { - Error_Handler(); - } - - PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; - PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { - Error_Handler(); - } + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { + Error_Handler(); + } + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { + Error_Handler(); + } } static void MX_GPIO_PullUp(void) { @@ -304,12 +317,12 @@ static void MX_GPIO_PullUp(void) { * @retval None */ static void MX_GPIO_Init(void) { - fastGpioInitInputPU(PORT_DATA, PIN_DATA_NUM); - fastGpioInitInputPU(PORT_SELECT, PIN_SELECT_NUM); - fastGpioInitEvtFal(PORT_SELECT, PIN_SELECT_NUM); - fastGpioInitInputPU(PORT_CLK, PIN_CLK_NUM); - fastGpioInitEvtFal(PORT_CLK, PIN_CLK_NUM); - fastGpioInitOutputPP(PORT_LED, PIN_LED_NUM); + fastGpioInitInputPU(PORT_DATA, PIN_DATA_NUM); + fastGpioInitInputPU(PORT_SELECT, PIN_SELECT_NUM); + fastGpioInitEvtFal(PORT_SELECT, PIN_SELECT_NUM); + fastGpioInitInputPU(PORT_CLK, PIN_CLK_NUM); + fastGpioInitEvtFal(PORT_CLK, PIN_CLK_NUM); + fastGpioInitOutputPP(PORT_LED, PIN_LED_NUM); } @@ -317,17 +330,17 @@ static void PVD_Config() { __HAL_RCC_PWR_CLK_ENABLE(); //Enable Power Clock HAL_NVIC_SetPriority(PVD_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(PVD_IRQn); + HAL_NVIC_EnableIRQ(PVD_IRQn); - PWR_PVDTypeDef sConfigPVD; - sConfigPVD.PVDLevel = PWR_CR_PLS_2V9; - sConfigPVD.Mode = PWR_PVD_MODE_IT_RISING; - HAL_PWR_ConfigPVD(&sConfigPVD); //event on supply voltage < 2.8V - HAL_PWR_EnablePVD(); + PWR_PVDTypeDef sConfigPVD; + sConfigPVD.PVDLevel = PWR_CR_PLS_2V9; + sConfigPVD.Mode = PWR_PVD_MODE_IT_RISING; + HAL_PWR_ConfigPVD(&sConfigPVD); //event on supply voltage < 2.8V + HAL_PWR_EnablePVD(); } void PVD_IRQHandler(void) { - HAL_PWR_PVD_IRQHandler(); + HAL_PWR_PVD_IRQHandler(); } /** diff --git a/STMP/fatfs/ff.c b/STMP/fatfs/ff.c index c15808b..ec3d127 100644 --- a/STMP/fatfs/ff.c +++ b/STMP/fatfs/ff.c @@ -3832,9 +3832,11 @@ FRESULT f_read_byte ( FATFS *fs = fp->obj.fs; if (fp->obj.objsize - fp->fptr<=0) { - LEAVE_FF(fs, FR_DISK_ERR); + *buff = 0xFF; // end of "cartridge", just return 0xFF :-) + fp->fptr++; + LEAVE_FF(fs, FR_OK); } - + if ((fp->fptr % SS(fs)) == 0) { uint32_t csect = (fp->fptr / SS(fs) & (fs->csize - 1)); if (csect == 0) { From b18d9385ffd598459c3893ae69070a18562c831b Mon Sep 17 00:00:00 2001 From: Bs0Dd Date: Sun, 8 Feb 2026 02:20:43 +0100 Subject: [PATCH 2/3] New README --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 731eb93..9636e1b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Модуль памяти для "Электроника МК 90" на основе микроконтроллера STM32. **Возможности:** -- Простое копирование образов картриджей - при подключении к ПК модуль работает как флешка; +- Простое копирование образов картриджей - при подключении к ПК модуль работает как флешка (~90КБ); - При подключении к МК90 модуль монтирует autorun.bin или первый попавшийся образ и работает как обычный МПО/СМП (только на чтение); - Поддержка (только на чтение) протокола [Genjitsu SMP](https://github.com/vladkorotnev/SMPEmu/tree/master/pdp) благодаря чему можно загрузить несколько образов и выбирать нужный из списка непосредственно на МК90. @@ -10,10 +10,12 @@ +Если необходим больший размер накопителя (90КБ не хватит на некоторое ПО для МК90) - для сборки доступен модуль на базе Raspberry Pi Pico (~1.8МБ) - [PIMP](https://github.com/azya52/PIMP). + **Что понадобится:** - Сама отладочная плата Blue Pill; - Программатор, в качестве которого можно использовать ST-Link или любой адаптер USB-UART (или Arduino); -- Пара резисторов. +- Пара-тройка резисторов. **Схема подключения** @@ -25,5 +27,5 @@ **Мультикартридж** -Для возможности выбора образа из нескольких непосредственно на МК90, достаточно скопировать [загрузчик](https://github.com/vladkorotnev/SMPEmu/blob/master/pdp/smp0.bin) на модуль, переименовав в autorun.bin и конечно скопировать нужные образы. +Для возможности выбора образа из нескольких непосредственно на МК90, достаточно скопировать [загрузчик](https://github.com/vladkorotnev/SMPEmu/blob/master/pdp/autorun.bin) на модуль и конечно скопировать нужные образы. From b6cc5e28336a001c8a18b47a131a4f239238d49d Mon Sep 17 00:00:00 2001 From: Bs0Dd Date: Sun, 8 Feb 2026 02:24:07 +0100 Subject: [PATCH 3/3] Extra tabulation --- STMP/fatfs/ff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/STMP/fatfs/ff.c b/STMP/fatfs/ff.c index ec3d127..e2fcaf1 100644 --- a/STMP/fatfs/ff.c +++ b/STMP/fatfs/ff.c @@ -3836,7 +3836,7 @@ FRESULT f_read_byte ( fp->fptr++; LEAVE_FF(fs, FR_OK); } - + if ((fp->fptr % SS(fs)) == 0) { uint32_t csect = (fp->fptr / SS(fs) & (fs->csize - 1)); if (csect == 0) {