diff --git a/Core/Inc/disp7seg.h b/Core/Inc/disp7seg.h new file mode 100644 index 0000000..7d31b82 --- /dev/null +++ b/Core/Inc/disp7seg.h @@ -0,0 +1,10 @@ +#ifndef DISP7SEG_H_INCLUDED +#define DISP7SEG_H_INCLUDED + +#include + +extern void DispPutDigit(uint8_t pos, char chr, uint8_t dp); +extern void ShiftReg_Update(void); + + +#endif diff --git a/Core/Inc/main.h b/Core/Inc/main.h index 85d6c50..78eaca7 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -71,8 +71,14 @@ void Error_Handler(void); /* USER CODE END EFP */ /* Private defines -----------------------------------------------------------*/ +#define SHR_CLK_Pin LL_GPIO_PIN_14 +#define SHR_CLK_GPIO_Port GPIOC +#define SHR_STR_Pin LL_GPIO_PIN_15 +#define SHR_STR_GPIO_Port GPIOC #define LD2_Pin LL_GPIO_PIN_11 #define LD2_GPIO_Port GPIOC +#define SHR_DOUT_DISP_Pin LL_GPIO_PIN_8 +#define SHR_DOUT_DISP_GPIO_Port GPIOB #ifndef NVIC_PRIORITYGROUP_0 #define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority, 4 bits for subpriority */ @@ -87,6 +93,17 @@ void Error_Handler(void); #endif /* USER CODE BEGIN Private defines */ +static inline void Delay_us() { LL_mDelay(1); } // TODO: implement real microsecond delay + +// Shift register control macros +#define SHR_COUNT 4 +static inline void SHRCLK_HI() { LL_GPIO_SetOutputPin( SHR_CLK_GPIO_Port, SHR_CLK_Pin); } +static inline void SHRCLK_LO() { LL_GPIO_ResetOutputPin( SHR_CLK_GPIO_Port, SHR_CLK_Pin); } +static inline void SHRSTR_HI() { LL_GPIO_SetOutputPin( SHR_STR_GPIO_Port, SHR_STR_Pin); } +static inline void SHRSTR_LO() { LL_GPIO_ResetOutputPin( SHR_STR_GPIO_Port, SHR_STR_Pin); } +static inline void SHRDIN_HI() { LL_GPIO_SetOutputPin( SHR_DOUT_DISP_GPIO_Port, SHR_DOUT_DISP_Pin); } +static inline void SHRDIN_LO() { LL_GPIO_ResetOutputPin( SHR_DOUT_DISP_GPIO_Port, SHR_DOUT_DISP_Pin); } + /* USER CODE END Private defines */ diff --git a/Core/Src/disp7seg.c b/Core/Src/disp7seg.c new file mode 100644 index 0000000..c8a913e --- /dev/null +++ b/Core/Src/disp7seg.c @@ -0,0 +1,94 @@ +/***************************************************************************//** +* @file disp7seg.c +* @brief 7-segment display handling +*******************************************************************************/ + +#include "disp7seg.h" +#include "main.h" + + +static uint8_t ShrBuf[SHR_COUNT] = {0}; // buffer for ext. shift register +static uint8_t ShrDirty = 1; // update request + +/***************************************************************************//** +* @brief Write data to external shift register on changes +*******************************************************************************/ +void ShiftReg_Update() { + if (ShrDirty == 0) return; // register is up to date + ShrDirty = 0; + + uint_fast8_t shrsel = SHR_COUNT; + while (shrsel--) { + uint8_t reg = ShrBuf[shrsel]; + uint_fast8_t clkcnt; + for (clkcnt = 0; clkcnt < 8; clkcnt++) { + SHRCLK_LO(); + if (reg & 0x80) { SHRDIN_HI(); } + else { SHRDIN_LO(); } + reg <<= 1; // shift left + Delay_us(1); + SHRCLK_HI(); // clock pulse + Delay_us(1); + } + } + SHRSTR_HI(); // strobe pulse + SHRCLK_LO(); + SHRDIN_LO(); + Delay_us(1); + SHRSTR_LO(); +} + +/***************************************************************************//** +/brief Segment table for 7 segment display + +For ASCII characters range 0x20...0x60 + +Segment <--> bit allocation +/code + + 0000 + 5 1 + 5 1 + 6666 + 4 2 + 4 2 + 3333 77 +*******************************************************************************/ +static const uint8_t LcdAscii7segTable[] = { + 0x00, 0x82, 0xA2, 0x5C, 0x6D, 0x00, 0x7F, 0x02, // space ... apostrof + 0x39, 0x0F, 0x00, 0x00, 0x04, 0x40, 0x00, 0x52, // ( ... slash + 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, // 0 ... 9 + 0x48, 0x48, 0x58, 0x48, 0x4C, 0x53, 0x7B, // : ... @ + + 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x3D, 0x76, // ABCDEFGH + 0x06, 0x1E, 0x7A, 0x38, 0x37, 0x54, 0x3F, 0x73, // IJKLMNOP + 0x67, 0x50, 0x6D, 0x78, 0x3E, 0x3E, 0x3E, 0x76, // QRSTUVWX + 0x6E, 0x5B, 0x39, 0x64, 0x0F, 0x23, 0x08, 0x60, // YZ[\]^_` + + 0x5F, 0x7C, 0x58, 0x5E, 0x79, 0x71, 0x6F, 0x74, // abcdefgh + 0x04, 0x1E, 0x7A, 0x06, 0x37, 0x54, 0x5C, 0x73, // ijklmnop + 0x67, 0x50, 0x6D, 0x78, 0x1C, 0x1C, 0x1C, 0x76, // qrstuvwx + 0x6E, 0x5B, 0x39, 0x30, 0x0F, 0x62 // yz{|}~ +}; + +/***************************************************************************//** +* \brief Print characters to 7 segment display +*******************************************************************************/ +void DispPutDigit(uint8_t pos, char chr, uint8_t dp) { + if (pos >= SHR_COUNT) return; + + uint8_t* disp_buf = ShrBuf; + uint8_t segments; + + uint8_t c = chr; + if (c >= ' ' && c < 127) segments = LcdAscii7segTable[c-' ']; + //else if (c == '°') segments = 0x63; + else segments = 0; + if (dp) segments |= 0x80; // decimal point + uint8_t prevseg = disp_buf[pos]; + disp_buf[pos] = ~segments; // write new digit + + if (prevseg != disp_buf[pos]) { // buffer changed + ShrDirty = 1; // update request + } +} diff --git a/Core/Src/main.c b/Core/Src/main.c index 8535f18..10577e4 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -21,6 +21,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ +#include "disp7seg.h" /* USER CODE END Includes */ @@ -101,6 +102,12 @@ int main(void) LL_Init1msTick(SystemCoreClock); + DispPutDigit(0, ' ', 0); + DispPutDigit(1, ' ', 0); + DispPutDigit(2, ' ', 0); + DispPutDigit(3, ' ', 0); + ShiftReg_Update(); + /* USER CODE END 2 */ /* Infinite loop */ @@ -109,6 +116,13 @@ int main(void) { LD2_Toggle(); LL_mDelay(250); + static uint8_t cnt = 0; + DispPutDigit(0, '0'+cnt, 0); + DispPutDigit(1, 'a'+cnt, 1); + DispPutDigit(2, 'A'+cnt, 0); + DispPutDigit(3, 'Z'-cnt, 1); + if (++cnt > 9) cnt = 0; + ShiftReg_Update(); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ @@ -209,20 +223,35 @@ static void MX_GPIO_Init(void) /* USER CODE END MX_GPIO_Init_1 */ /* GPIO Ports Clock Enable */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + + /**/ + LL_GPIO_ResetOutputPin(GPIOC, SHR_CLK_Pin|SHR_STR_Pin); + + /**/ + LL_GPIO_ResetOutputPin(SHR_DOUT_DISP_GPIO_Port, SHR_DOUT_DISP_Pin); /**/ LL_GPIO_SetOutputPin(LD2_GPIO_Port, LD2_Pin); /**/ - GPIO_InitStruct.Pin = LD2_Pin; + GPIO_InitStruct.Pin = SHR_CLK_Pin|SHR_STR_Pin|LD2_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = SHR_DOUT_DISP_Pin; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - LL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct); + LL_GPIO_Init(SHR_DOUT_DISP_GPIO_Port, &GPIO_InitStruct); /* USER CODE BEGIN MX_GPIO_Init_2 */ diff --git a/DigitalAudioH533.ioc b/DigitalAudioH533.ioc index e272326..f08dcce 100644 --- a/DigitalAudioH533.ioc +++ b/DigitalAudioH533.ioc @@ -56,19 +56,22 @@ Mcu.IP8=SYS Mcu.IPNb=9 Mcu.Name=STM32H533RETx Mcu.Package=LQFP64 -Mcu.Pin0=PH0-OSC_IN(PH0) -Mcu.Pin1=PH1-OSC_OUT(PH1) -Mcu.Pin10=VP_BOOTPATH_VS_BOOTPATH -Mcu.Pin11=VP_MEMORYMAP_VS_MEMORYMAP -Mcu.Pin2=PA13(JTMS/SWDIO) -Mcu.Pin3=PA14(JTCK/SWCLK) -Mcu.Pin4=PC11 -Mcu.Pin5=VP_CORTEX_M33_NS_VS_Hclk -Mcu.Pin6=VP_ICACHE_VS_ICACHE -Mcu.Pin7=VP_PWR_VS_SECSignals -Mcu.Pin8=VP_PWR_VS_LPOM -Mcu.Pin9=VP_SYS_VS_Systick -Mcu.PinsNb=12 +Mcu.Pin0=PC14-OSC32_IN(OSC32_IN) +Mcu.Pin1=PC15-OSC32_OUT(OSC32_OUT) +Mcu.Pin10=VP_PWR_VS_SECSignals +Mcu.Pin11=VP_PWR_VS_LPOM +Mcu.Pin12=VP_SYS_VS_Systick +Mcu.Pin13=VP_BOOTPATH_VS_BOOTPATH +Mcu.Pin14=VP_MEMORYMAP_VS_MEMORYMAP +Mcu.Pin2=PH0-OSC_IN(PH0) +Mcu.Pin3=PH1-OSC_OUT(PH1) +Mcu.Pin4=PA13(JTMS/SWDIO) +Mcu.Pin5=PA14(JTCK/SWCLK) +Mcu.Pin6=PC11 +Mcu.Pin7=PB8 +Mcu.Pin8=VP_CORTEX_M33_NS_VS_Hclk +Mcu.Pin9=VP_ICACHE_VS_ICACHE +Mcu.PinsNb=15 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32H533RETx @@ -89,11 +92,23 @@ PA13(JTMS/SWDIO).Mode=Serial_Wire PA13(JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO PA14(JTCK/SWCLK).Mode=Serial_Wire PA14(JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK +PB8.GPIOParameters=GPIO_Label +PB8.GPIO_Label=SHR_DOUT_DISP +PB8.Locked=true +PB8.Signal=GPIO_Output PC11.GPIOParameters=PinState,GPIO_Label PC11.GPIO_Label=LD2 PC11.Locked=true PC11.PinState=GPIO_PIN_SET PC11.Signal=GPIO_Output +PC14-OSC32_IN(OSC32_IN).GPIOParameters=GPIO_Label +PC14-OSC32_IN(OSC32_IN).GPIO_Label=SHR_CLK +PC14-OSC32_IN(OSC32_IN).Locked=true +PC14-OSC32_IN(OSC32_IN).Signal=GPIO_Output +PC15-OSC32_OUT(OSC32_OUT).GPIOParameters=GPIO_Label +PC15-OSC32_OUT(OSC32_OUT).GPIO_Label=SHR_STR +PC15-OSC32_OUT(OSC32_OUT).Locked=true +PC15-OSC32_OUT(OSC32_OUT).Signal=GPIO_Output PCC.Checker=false PCC.Line=STM32H5x3 PCC.MCU=STM32H533RETx