diff --git a/Core/Inc/main.h b/Core/Inc/main.h index afe90eb..2596a38 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -62,6 +62,7 @@ void Error_Handler(void); #define LED1_GPIO_Port GPIOA #define SPI2_BUSY_Pin GPIO_PIN_0 #define SPI2_BUSY_GPIO_Port GPIOB +#define SPI2_BUSY_EXTI_IRQn EXTI0_IRQn #define SPI2_RES_Pin GPIO_PIN_1 #define SPI2_RES_GPIO_Port GPIOB #define SPI2_DC_Pin GPIO_PIN_14 diff --git a/Core/Inc/stm32h7xx_it.h b/Core/Inc/stm32h7xx_it.h index 112311d..faa8c15 100644 --- a/Core/Inc/stm32h7xx_it.h +++ b/Core/Inc/stm32h7xx_it.h @@ -56,6 +56,7 @@ void DebugMon_Handler(void); void PVD_AVD_IRQHandler(void); void FLASH_IRQHandler(void); void RCC_IRQHandler(void); +void EXTI0_IRQHandler(void); void SPI2_IRQHandler(void); void TIM7_IRQHandler(void); void FPU_IRQHandler(void); diff --git a/Core/Src/main.c b/Core/Src/main.c index 136e5e8..a503844 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -402,7 +402,7 @@ static void MX_GPIO_Init(void) /*Configure GPIO pin : SPI2_BUSY_Pin */ GPIO_InitStruct.Pin = SPI2_BUSY_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(SPI2_BUSY_GPIO_Port, &GPIO_InitStruct); @@ -420,6 +420,10 @@ static void MX_GPIO_Init(void) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(SPI2_DC_GPIO_Port, &GPIO_InitStruct); + /* EXTI interrupt init*/ + HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(EXTI0_IRQn); + } /* USER CODE BEGIN 4 */ diff --git a/Core/Src/stm32h7xx_it.c b/Core/Src/stm32h7xx_it.c index 34e397b..a4c2578 100644 --- a/Core/Src/stm32h7xx_it.c +++ b/Core/Src/stm32h7xx_it.c @@ -204,6 +204,20 @@ void RCC_IRQHandler(void) /* USER CODE END RCC_IRQn 1 */ } +/** + * @brief This function handles EXTI line0 interrupt. + */ +void EXTI0_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI0_IRQn 0 */ + + /* USER CODE END EXTI0_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); + /* USER CODE BEGIN EXTI0_IRQn 1 */ + + /* USER CODE END EXTI0_IRQn 1 */ +} + /** * @brief This function handles SPI2 global interrupt. */ diff --git a/Core/Src/user_epd_impl.c b/Core/Src/user_epd_impl.c index a0f147b..3eb5739 100644 --- a/Core/Src/user_epd_impl.c +++ b/Core/Src/user_epd_impl.c @@ -4,59 +4,68 @@ #include "user_epd_impl.h" +#define BUSY_MAX_POLLING_TIME 30000 // 30s + +uint8_t g_epd_busy_irq_flag = 0; + +extern osSemaphoreId_t g_epd_busy_semphr; depg0213_ret_t _epd_reset_cb(void *handle) { - SPI_HandleTypeDef *hspi = handle; - if(hspi->Instance == SPI2) { - HAL_GPIO_WritePin(SPI2_RES_GPIO_Port, SPI2_RES_Pin, GPIO_PIN_SET); - HAL_Delay(10); - HAL_GPIO_WritePin(SPI2_RES_GPIO_Port, SPI2_RES_Pin, GPIO_PIN_RESET); - HAL_Delay(5); - HAL_GPIO_WritePin(SPI2_RES_GPIO_Port, SPI2_RES_Pin, GPIO_PIN_SET); - HAL_Delay(10); - } - return DEPG0213_OK; + SPI_HandleTypeDef *hspi = handle; + if (hspi->Instance == SPI2) { + HAL_GPIO_WritePin(SPI2_RES_GPIO_Port, SPI2_RES_Pin, GPIO_PIN_RESET); + HAL_Delay(5); + HAL_GPIO_WritePin(SPI2_RES_GPIO_Port, SPI2_RES_Pin, GPIO_PIN_SET); + } + return DEPG0213_OK; } depg0213_ret_t _epd_poll_busy(void *handle) { - SPI_HandleTypeDef *hspi = handle; - if(hspi->Instance == SPI2) { - uint32_t tick_start = HAL_GetTick(); - while (HAL_GPIO_ReadPin(SPI2_BUSY_GPIO_Port, SPI2_BUSY_Pin) == GPIO_PIN_SET) { - if(HAL_GetTick() - tick_start > 10000) { - return DEPG0213_ERROR; - } + SPI_HandleTypeDef *hspi = handle; + if (hspi->Instance == SPI2) { + if (osKernelGetState() != osKernelRunning) { // Kernel has not started, use flag polling instead. + uint32_t tick_start = HAL_GetTick(); + while (!g_epd_busy_irq_flag) { + if (HAL_GetTick() - tick_start > BUSY_MAX_POLLING_TIME) { + return DEPG0213_ERROR; + } + } + g_epd_busy_irq_flag = 0; + } else { // Kernel has started, use semaphore. + if(osSemaphoreAcquire(g_epd_busy_semphr, BUSY_MAX_POLLING_TIME) != osOK) { + return DEPG0213_ERROR; + } + } } - } - return DEPG0213_OK; + return DEPG0213_OK; } depg0213_ret_t _epd_write_cmd_cb(void *handle, uint8_t *cmd, uint8_t len) { - SPI_HandleTypeDef *hspi = handle; + SPI_HandleTypeDef *hspi = handle; - HAL_StatusTypeDef ret = HAL_OK; + HAL_StatusTypeDef ret = HAL_OK; - if(hspi->Instance == SPI2) { - HAL_GPIO_WritePin(SPI2_DC_GPIO_Port, SPI2_DC_Pin, GPIO_PIN_RESET); - ret = HAL_SPI_Transmit(hspi, cmd, 0x01, 1000); - if(len > 1) { - HAL_GPIO_WritePin(SPI2_DC_GPIO_Port, SPI2_DC_Pin, GPIO_PIN_SET); - ret = HAL_SPI_Transmit(hspi, &cmd[1], len - 1, 1000); + if (hspi->Instance == SPI2) { + HAL_GPIO_WritePin(SPI2_DC_GPIO_Port, SPI2_DC_Pin, GPIO_PIN_RESET); + ret = HAL_SPI_Transmit(hspi, cmd, 0x01, 1000); + if (len > 1) { + HAL_GPIO_WritePin(SPI2_DC_GPIO_Port, SPI2_DC_Pin, GPIO_PIN_SET); + ret = HAL_SPI_Transmit(hspi, &cmd[1], len - 1, 1000); + } } - } - if(ret != HAL_OK) return DEPG0213_ERROR; - return DEPG0213_OK; + if (ret != HAL_OK) return DEPG0213_ERROR; + return DEPG0213_OK; } depg0213_ret_t _epd_write_data_cb(void *handle, uint8_t *data, uint16_t len) { - SPI_HandleTypeDef *hspi = handle; + SPI_HandleTypeDef *hspi = handle; - HAL_StatusTypeDef ret = HAL_OK; + HAL_StatusTypeDef ret = HAL_OK; - if(hspi->Instance == SPI2) { - HAL_GPIO_WritePin(SPI2_DC_GPIO_Port, SPI2_DC_Pin, GPIO_PIN_SET); - ret = HAL_SPI_Transmit(hspi, data, len, 1000); - } - if(ret != HAL_OK) return DEPG0213_ERROR; - return DEPG0213_OK; + if (hspi->Instance == SPI2) { + HAL_GPIO_WritePin(SPI2_DC_GPIO_Port, SPI2_DC_Pin, GPIO_PIN_SET); + ret = HAL_SPI_Transmit(hspi, data, len, 1000); + } + if (ret != HAL_OK) return DEPG0213_ERROR; + return DEPG0213_OK; } \ No newline at end of file diff --git a/Core/Src/user_irq_handlers.c b/Core/Src/user_irq_handlers.c new file mode 100644 index 0000000..13ba7c4 --- /dev/null +++ b/Core/Src/user_irq_handlers.c @@ -0,0 +1,21 @@ +#include "cmsis_os2.h" + +#include "main.h" + +#include "user_epd_impl.h" + +extern uint8_t g_epd_busy_irq_flag; +extern osSemaphoreId_t g_epd_busy_semphr; + +void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { + // FIXME + if(GPIO_Pin == SPI2_BUSY_Pin) { + if(osKernelGetState() != osKernelRunning) { // Kernel has not started, write poll variable + g_epd_busy_irq_flag = 1; + } + else { // Kernel has started, release semaphore. + osSemaphoreRelease(g_epd_busy_semphr); + // CMSIS-OS2 wraps FreeRTOS call, no need to use __xxFromISR functions here. + } + } +} \ No newline at end of file diff --git a/Core/Src/user_tasks.c b/Core/Src/user_tasks.c index e001b64..51c9458 100644 --- a/Core/Src/user_tasks.c +++ b/Core/Src/user_tasks.c @@ -1,3 +1,5 @@ +#include "cmsis_os2.h" + #include "lvgl.h" #include "user_epd_impl.h" @@ -5,33 +7,49 @@ // Defined in main.c extern SPI_HandleTypeDef hspi2; -// Globals -depg0213_epd_t g_epd; - -// Private defines -void _user_tasks_init_epd(void); +// Private function prototypes +uint8_t _user_tasks_init_epd(void); void _user_tasks_init_lvgl(void); +// Globals +depg0213_epd_t g_epd = { + .user_data = &hspi2, + .cb = { + .reset_cb = _epd_reset_cb, + .poll_busy_cb = _epd_poll_busy, + .write_cmd_cb = _epd_write_cmd_cb, + .write_data_cb = _epd_write_data_cb + } +}; +osSemaphoreId_t g_epd_busy_semphr; + void user_tasks_initialize(void) { - _user_tasks_init_epd(); + if(_user_tasks_init_epd()) return; _user_tasks_init_lvgl(); } -void _user_tasks_init_epd(void) { - depg0213_epd_t epd = { - .user_data = &hspi2, - .cb = { - .reset_cb = _epd_reset_cb, - .poll_busy_cb = _epd_poll_busy, - .write_cmd_cb = _epd_write_cmd_cb, - .write_data_cb = _epd_write_data_cb +void user_task_flush_epd(void *arguments) { + for(;;) { + // } - }; +} - depg0213_epd_init(&epd); +uint8_t _user_tasks_init_epd(void) { + depg0213_ret_t ret; - depg0213_epd_direction(&epd, DEPG0213_HORIZONTAL_INVERSE); - depg0213_epd_deepsleep(&epd); + g_epd_busy_semphr = osSemaphoreNew(1U, 0U, NULL); // Max: 1, initial 1, attr NULL + if(g_epd_busy_semphr == NULL) return -1; + + ret = depg0213_epd_init(&g_epd); + if(ret != DEPG0213_OK) return -2; + + ret = depg0213_epd_direction(&g_epd, DEPG0213_HORIZONTAL_INVERSE); + if(ret != DEPG0213_OK) return -3; + + ret = depg0213_epd_deepsleep(&g_epd); + if(ret != DEPG0213_OK) return -4; + + return 0; } void _user_tasks_init_lvgl(void) { diff --git a/Makefile b/Makefile index d059c2e..7c439af 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ ########################################################################################################################## -# File automatically-generated by tool: [projectgenerator] version: [3.11.2] date: [Mon Jan 11 00:59:29 CST 2021] +# File automatically-generated by tool: [projectgenerator] version: [3.11.2] date: [Wed Jan 13 02:55:23 CST 2021] ########################################################################################################################## # ------------------------------------------------ @@ -41,6 +41,7 @@ Core/Src/stm32h7xx_it.c \ Core/Src/stm32h7xx_hal_msp.c \ Core/Src/user_epd_impl.c \ Core/Src/user_tasks.c \ +Core/Src/user_irq_handlers.c \ Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c \ Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c \ Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c \ diff --git a/STM32H750_EPD.ioc b/STM32H750_EPD.ioc index dd3b162..a380e5a 100644 --- a/STM32H750_EPD.ioc +++ b/STM32H750_EPD.ioc @@ -82,10 +82,11 @@ CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_SIZE_12 NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true RCC.DIVM1=4 RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE +PB0.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.8.0 MxDb.Version=DB.6.0.10 CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_ACCESS_CACHEABLE -PB0.GPIOParameters=GPIO_Label +PB0.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI RCC.DIVP1Freq_Value=240000000 PA1.GPIOParameters=GPIO_Label CORTEX_M7.TypeExtField-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_TEX_LEVEL1 @@ -98,7 +99,7 @@ File.Version=6 SPI2.CalculateBaudRate=15.0 MBits/s PE2.Signal=QUADSPI_BK1_IO2 PA14\ (JTCK/SWCLK).Mode=Serial_Wire -NVIC.SPI2_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true +NVIC.SPI2_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true PB6.Locked=true NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false RCC.DIVR2Freq_Value=16125000 @@ -120,6 +121,7 @@ CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region1_Settings=0x90000000 RCC.EnbaleCSS=true PD12.Signal=QUADSPI_BK1_IO1 ProjectManager.ToolChainLocation= +SH.GPXTI0.0=GPIO_EXTI0 NVIC.TimeBaseIP=TIM7 RCC.DFSDMFreq_Value=120000000 RCC.DIVR1Freq_Value=240000000 @@ -146,7 +148,7 @@ PB15.Locked=true RCC.VCO3OutputFreq_Value=32250000 VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE -NVIC.QUADSPI_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true +NVIC.QUADSPI_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true ProjectManager.ProjectFileName=STM32H750_EPD.ioc CORTEX_M7.CPU_ICache=Enabled RCC.DIVQ1=8 @@ -161,6 +163,7 @@ RCC.SWPMI1Freq_Value=120000000 CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_ACCESS_NOT_CACHEABLE RCC.SAI4BFreq_Value=60000000 SPI2.NSSPMode=SPI_NSS_PULSE_ENABLE +SH.GPXTI0.ConfNb=1 ProjectManager.DefaultFWLocation=true ProjectManager.DeletePrevious=true PB14.Locked=true @@ -189,7 +192,7 @@ PA1.Signal=GPIO_Output RCC.CKPERFreq_Value=64000000 PB1.Locked=true PB14.Signal=GPIO_Output -NVIC.PVD_AVD_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true +NVIC.PVD_AVD_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_ENABLE board=custom ProjectManager.LastFirmware=true @@ -207,7 +210,7 @@ RCC.ADCFreq_Value=16125000 PA1.GPIO_Label=LED1 CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_FULL_ACCESS NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true -NVIC.HSEM1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true +NVIC.HSEM1_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true ProjectManager.FreePins=false RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVN1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,EnbaleCSS,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,HSE_VALUE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LSE_Drive_Capability,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLLSourceVirtual,QSPICLockSelection,QSPIFreq_Value,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value ProjectManager.AskForMigrate=true @@ -224,6 +227,7 @@ VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2 Mcu.IP6=RTC Mcu.IP7=SPI2 ProjectManager.CoupleFile=false +NVIC.EXTI0_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true RCC.SYSCLKFreq_VALUE=240000000 RCC.I2C123Freq_Value=120000000 PA1.Locked=true @@ -258,7 +262,7 @@ Mcu.Pin11=PB14 Mcu.Pin12=PB15 Mcu.Pin10=PB13 RCC.DIVQ1Freq_Value=60000000 -NVIC.FPU_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:false +NVIC.FPU_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:false SPI2.DataSize=SPI_DATASIZE_8BIT CORTEX_M7.CPU_DCache=Enabled PB1.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_OD @@ -266,7 +270,7 @@ RCC.HCLK3ClockFreq_Value=120000000 PB12.GPIO_PuPd=GPIO_PULLUP RCC.VCOInput2Freq_Value=250000 RCC.APB1Freq_Value=120000000 -PB0.Signal=GPIO_Input +PB0.Signal=GPXTI0 ProjectManager.DeviceId=STM32H750VBTx PB12.GPIOParameters=GPIO_PuPd PB12.Signal=SPI2_NSS