From 2640fd9cf810ea813b0ebba64c51120fcf55819e Mon Sep 17 00:00:00 2001 From: muzkr Date: Thu, 23 Oct 2025 14:23:28 +0800 Subject: [PATCH] Port K1 drivers - refactor gpio and related (keypad etc) - LCD driver - Part of board init --- App/CMakeLists.txt | 2 +- App/audio.h | 10 +- App/board.c | 465 +++++------------------------------------ App/board.h | 1 - App/driver/backlight.c | 11 +- App/driver/gpio.h | 105 +++++----- App/driver/keyboard.c | 48 ++--- App/driver/st7565.c | 162 ++++++++++---- App/main.c | 13 -- 9 files changed, 250 insertions(+), 567 deletions(-) diff --git a/App/CMakeLists.txt b/App/CMakeLists.txt index 5235e749..2b2d1e6d 100644 --- a/App/CMakeLists.txt +++ b/App/CMakeLists.txt @@ -106,7 +106,7 @@ enable_feature(ENABLE_AIRCOPY ui/aircopy.c ) enable_feature(ENABLE_NOAA) -enable_feature(ENABLE_VOICE) +# enable_feature(ENABLE_VOICE) enable_feature(ENABLE_VOX) enable_feature(ENABLE_ALARM) enable_feature(ENABLE_TX1750) diff --git a/App/audio.h b/App/audio.h index 26ed0b60..4bee066f 100644 --- a/App/audio.h +++ b/App/audio.h @@ -47,14 +47,10 @@ typedef enum BEEP_Type_t BEEP_Type_t; extern BEEP_Type_t gBeepToPlay; void AUDIO_PlayBeep(BEEP_Type_t Beep); - -static inline void AUDIO_AudioPathOn(void) { - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); -} -static inline void AUDIO_AudioPathOff(void) { - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); -} +#define AUDIO_AudioPathOn() GPIO_EnableAudioPath() + +#define AUDIO_AudioPathOff() GPIO_DisableAudioPath() #ifdef ENABLE_VOICE typedef enum VOICE_ID_t VOICE_ID_t; diff --git a/App/board.c b/App/board.c index e3db3ca3..dd28e152 100644 --- a/App/board.c +++ b/App/board.c @@ -1,4 +1,5 @@ -/* Copyright 2023 Dual Tachyon +/* Copyright 2025 muzkr https://github.com/muzkr + * Copyright 2023 Dual Tachyon * https://github.com/DualTachyon * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,8 +21,8 @@ #include "app/fm.h" #endif #include "board.h" -#include "bsp/dp32g030/gpio.h" -#include "bsp/dp32g030/portcon.h" +#include "py32f071_ll_bus.h" +#include "py32f071_ll_gpio.h" #include "bsp/dp32g030/saradc.h" #include "bsp/dp32g030/syscon.h" #include "driver/adc.h" @@ -60,436 +61,86 @@ void BOARD_GPIO_Init(void) { - GPIOA->DIR |= 0 - // A7 = UART1 TX default as OUTPUT from bootloader! - // A8 = UART1 RX default as INPUT from bootloader! - // Key pad + I2C - | GPIO_DIR_10_BITS_OUTPUT - // Key pad + I2C - | GPIO_DIR_11_BITS_OUTPUT - // Key pad + Voice chip - | GPIO_DIR_12_BITS_OUTPUT - // Key pad + Voice chip - | GPIO_DIR_13_BITS_OUTPUT - ; - GPIOA->DIR &= ~(0 - // Key pad - | GPIO_DIR_3_MASK // INPUT - // Key pad - | GPIO_DIR_4_MASK // INPUT - // Key pad - | GPIO_DIR_5_MASK // INPUT - // Key pad - | GPIO_DIR_6_MASK // INPUT - ); - GPIOB->DIR |= 0 - // ST7565 - | GPIO_DIR_9_BITS_OUTPUT - // ST7565 + SWD IO - | GPIO_DIR_11_BITS_OUTPUT - // B14 = SWD_CLK assumed INPUT by default - // BK1080 - | GPIO_DIR_15_BITS_OUTPUT - ; - GPIOC->DIR |= 0 - // BK4819 SCN - | GPIO_DIR_0_BITS_OUTPUT - // BK4819 SCL - | GPIO_DIR_1_BITS_OUTPUT - // BK4819 SDA - | GPIO_DIR_2_BITS_OUTPUT - // Flash light - | GPIO_DIR_3_BITS_OUTPUT - // Speaker - | GPIO_DIR_4_BITS_OUTPUT - ; - GPIOC->DIR &= ~(0 - // PTT button - | GPIO_DIR_5_MASK // INPUT - ); + LL_IOP_GRP1_EnableClock( + LL_IOP_GRP1_PERIPH_GPIOA // + | LL_IOP_GRP1_PERIPH_GPIOB // + | LL_IOP_GRP1_PERIPH_GPIOC // + | LL_IOP_GRP1_PERIPH_GPIOF // + ); - #if defined(ENABLE_FMRADIO) - GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BK1080); - #endif -} + LL_GPIO_InitTypeDef InitStruct; + LL_GPIO_StructInit(&InitStruct); + InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + InitStruct.Pull = LL_GPIO_PULL_UP; + InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; -void BOARD_PORTCON_Init(void) -{ - // PORT A pin selection + // --------------------- + // Input pins - PORTCON_PORTA_SEL0 &= ~(0 - // Key pad - | PORTCON_PORTA_SEL0_A3_MASK - // Key pad - | PORTCON_PORTA_SEL0_A4_MASK - // Key pad - | PORTCON_PORTA_SEL0_A5_MASK - // Key pad - | PORTCON_PORTA_SEL0_A6_MASK - ); - PORTCON_PORTA_SEL0 |= 0 - // Key pad - | PORTCON_PORTA_SEL0_A3_BITS_GPIOA3 - // Key pad - | PORTCON_PORTA_SEL0_A4_BITS_GPIOA4 - // Key pad - | PORTCON_PORTA_SEL0_A5_BITS_GPIOA5 - // Key pad - | PORTCON_PORTA_SEL0_A6_BITS_GPIOA6 - // UART1 TX, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTA_SEL0_A7_BITS_UART1_TX - ; + InitStruct.Mode = LL_GPIO_MODE_INPUT; - PORTCON_PORTA_SEL1 &= ~(0 - // Key pad + I2C - | PORTCON_PORTA_SEL1_A10_MASK - // Key pad + I2C - | PORTCON_PORTA_SEL1_A11_MASK - // Key pad + Voice chip - | PORTCON_PORTA_SEL1_A12_MASK - // Key pad + Voice chip - | PORTCON_PORTA_SEL1_A13_MASK - ); - PORTCON_PORTA_SEL1 |= 0 - // UART1 RX, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTA_SEL1_A8_BITS_UART1_RX - // Battery voltage, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTA_SEL1_A9_BITS_SARADC_CH4 - // Key pad + I2C - | PORTCON_PORTA_SEL1_A10_BITS_GPIOA10 - // Key pad + I2C - | PORTCON_PORTA_SEL1_A11_BITS_GPIOA11 - // Key pad + Voice chip - | PORTCON_PORTA_SEL1_A12_BITS_GPIOA12 - // Key pad + Voice chip - | PORTCON_PORTA_SEL1_A13_BITS_GPIOA13 - // Battery Current, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTA_SEL1_A14_BITS_SARADC_CH9 - ; + // Keypad rows: PB15:12 + InitStruct.Pin = LL_GPIO_PIN_15 | LL_GPIO_PIN_14 | LL_GPIO_PIN_13 | LL_GPIO_PIN_12; + LL_GPIO_Init(GPIOB, &InitStruct); - // PORT B pin selection + // PTT: PB10 + InitStruct.Pin = LL_GPIO_PIN_10; + LL_GPIO_Init(GPIOB, &InitStruct); - PORTCON_PORTB_SEL0 &= ~(0 - // SPI0 SSN - | PORTCON_PORTB_SEL0_B7_MASK - ); - PORTCON_PORTB_SEL0 |= 0 - // SPI0 SSN - | PORTCON_PORTB_SEL0_B7_BITS_SPI0_SSN - ; + // ----------------------- + // Output pins - PORTCON_PORTB_SEL1 &= ~(0 - // ST7565 - | PORTCON_PORTB_SEL1_B9_MASK - // ST7565 + SWD IO - | PORTCON_PORTB_SEL1_B11_MASK - // SWD CLK - | PORTCON_PORTB_SEL1_B14_MASK - // BK1080 - | PORTCON_PORTB_SEL1_B15_MASK - ); - PORTCON_PORTB_SEL1 |= 0 - // SPI0 CLK, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTB_SEL1_B8_BITS_SPI0_CLK - // ST7565 - | PORTCON_PORTB_SEL1_B9_BITS_GPIOB9 - // SPI0 MOSI, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTB_SEL1_B10_BITS_SPI0_MOSI -#if defined(ENABLE_SWD) - // SWD IO - | PORTCON_PORTB_SEL1_B11_BITS_SWDIO - // SWD CLK - | PORTCON_PORTB_SEL1_B14_BITS_SWCLK -#else - // ST7565 - | PORTCON_PORTB_SEL1_B11_BITS_GPIOB11 -#endif - ; + LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_6); // LCD A0 + LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_2); // LCD CS - // PORT C pin selection + InitStruct.Mode = LL_GPIO_MODE_OUTPUT; - PORTCON_PORTC_SEL0 &= ~(0 - // BK4819 SCN - | PORTCON_PORTC_SEL0_C0_MASK - // BK4819 SCL - | PORTCON_PORTC_SEL0_C1_MASK - // BK4819 SDA - | PORTCON_PORTC_SEL0_C2_MASK - // Flash light - | PORTCON_PORTC_SEL0_C3_MASK - // Speaker - | PORTCON_PORTC_SEL0_C4_MASK - // PTT button - | PORTCON_PORTC_SEL0_C5_MASK - ); + // Keypad cols: PB6:3 + InitStruct.Pin = LL_GPIO_PIN_6 | LL_GPIO_PIN_5 | LL_GPIO_PIN_4 | LL_GPIO_PIN_3; + LL_GPIO_Init(GPIOB, &InitStruct); - // PORT A pin configuration + // Audio PA: PA8 + // LCD A0: PA6 + // SPI flash CS: PA3 + InitStruct.Pin = LL_GPIO_PIN_8 | LL_GPIO_PIN_6 | LL_GPIO_PIN_3; + LL_GPIO_Init(GPIOA, &InitStruct); - PORTCON_PORTA_IE |= 0 - // Keypad - | PORTCON_PORTA_IE_A3_BITS_ENABLE - // Keypad - | PORTCON_PORTA_IE_A4_BITS_ENABLE - // Keypad - | PORTCON_PORTA_IE_A5_BITS_ENABLE - // Keypad - | PORTCON_PORTA_IE_A6_BITS_ENABLE - // A7 = UART1 TX disabled by default - // UART1 RX - | PORTCON_PORTA_IE_A8_BITS_ENABLE - ; - PORTCON_PORTA_IE &= ~(0 - // Keypad + I2C - | PORTCON_PORTA_IE_A10_MASK - // Keypad + I2C - | PORTCON_PORTA_IE_A11_MASK - // Keypad + Voice chip - | PORTCON_PORTA_IE_A12_MASK - // Keypad + Voice chip - | PORTCON_PORTA_IE_A13_MASK - ); + // BK4819 SCK: B8 + // BK4819 SDA: B9 + // LCD CS: PB2 + InitStruct.Pin = LL_GPIO_PIN_9 | LL_GPIO_PIN_8 | LL_GPIO_PIN_2; + LL_GPIO_Init(GPIOB, &InitStruct); - PORTCON_PORTA_PU |= 0 - // Keypad - | PORTCON_PORTA_PU_A3_BITS_ENABLE - // Keypad - | PORTCON_PORTA_PU_A4_BITS_ENABLE - // Keypad - | PORTCON_PORTA_PU_A5_BITS_ENABLE - // Keypad - | PORTCON_PORTA_PU_A6_BITS_ENABLE - ; - PORTCON_PORTA_PU &= ~(0 - // Keypad + I2C - | PORTCON_PORTA_PU_A10_MASK - // Keypad + I2C - | PORTCON_PORTA_PU_A11_MASK - // Keypad + Voice chip - | PORTCON_PORTA_PU_A12_MASK - // Keypad + Voice chip - | PORTCON_PORTA_PU_A13_MASK - ); + // Flashlight: PC13 + InitStruct.Pin = LL_GPIO_PIN_13; + LL_GPIO_Init(GPIOC, &InitStruct); - PORTCON_PORTA_PD &= ~(0 - // Keypad - | PORTCON_PORTA_PD_A3_MASK - // Keypad - | PORTCON_PORTA_PD_A4_MASK - // Keypad - | PORTCON_PORTA_PD_A5_MASK - // Keypad - | PORTCON_PORTA_PD_A6_MASK - // Keypad + I2C - | PORTCON_PORTA_PD_A10_MASK - // Keypad + I2C - | PORTCON_PORTA_PD_A11_MASK - // Keypad + Voice chip - | PORTCON_PORTA_PD_A12_MASK - // Keypad + Voice chip - | PORTCON_PORTA_PD_A13_MASK - ); + // BK1080 SCK: PF5 + // BK1080 SDA: PF6 + // Backlight: PF8 + // BK4819 CS: PF9 + InitStruct.Pin = LL_GPIO_PIN_9 | LL_GPIO_PIN_8 | LL_GPIO_PIN_6 | LL_GPIO_PIN_5; + LL_GPIO_Init(GPIOF, &InitStruct); - PORTCON_PORTA_OD |= 0 - // Keypad - | PORTCON_PORTA_OD_A3_BITS_ENABLE - // Keypad - | PORTCON_PORTA_OD_A4_BITS_ENABLE - // Keypad - | PORTCON_PORTA_OD_A5_BITS_ENABLE - // Keypad - | PORTCON_PORTA_OD_A6_BITS_ENABLE - ; - PORTCON_PORTA_OD &= ~(0 - // Keypad + I2C - | PORTCON_PORTA_OD_A10_MASK - // Keypad + I2C - | PORTCON_PORTA_OD_A11_MASK - // Keypad + Voice chip - | PORTCON_PORTA_OD_A12_MASK - // Keypad + Voice chip - | PORTCON_PORTA_OD_A13_MASK - ); - - // PORT B pin configuration - - PORTCON_PORTB_IE |= 0 - | PORTCON_PORTB_IE_B14_BITS_ENABLE - ; - PORTCON_PORTB_IE &= ~(0 - // Back light - | PORTCON_PORTB_IE_B6_MASK - // UART1 - | PORTCON_PORTB_IE_B7_MASK - | PORTCON_PORTB_IE_B8_MASK - // ST7565 - | PORTCON_PORTB_IE_B9_MASK - // SPI0 MOSI - | PORTCON_PORTB_IE_B10_MASK -#if !defined(ENABLE_SWD) - // ST7565 - | PORTCON_PORTB_IE_B11_MASK -#endif - // BK1080 - | PORTCON_PORTB_IE_B15_MASK - ); - - PORTCON_PORTB_PU &= ~(0 - // Back light - | PORTCON_PORTB_PU_B6_MASK - // ST7565 - | PORTCON_PORTB_PU_B9_MASK - // ST7565 + SWD IO - | PORTCON_PORTB_PU_B11_MASK - // SWD CLK - | PORTCON_PORTB_PU_B14_MASK - // BK1080 - | PORTCON_PORTB_PU_B15_MASK - ); - - PORTCON_PORTB_PD &= ~(0 - // Back light - | PORTCON_PORTB_PD_B6_MASK - // ST7565 - | PORTCON_PORTB_PD_B9_MASK - // ST7565 + SWD IO - | PORTCON_PORTB_PD_B11_MASK - // SWD CLK - | PORTCON_PORTB_PD_B14_MASK - // BK1080 - | PORTCON_PORTB_PD_B15_MASK - ); - - PORTCON_PORTB_OD &= ~(0 - // Back light - | PORTCON_PORTB_OD_B6_MASK - // ST7565 - | PORTCON_PORTB_OD_B9_MASK - // ST7565 + SWD IO - | PORTCON_PORTB_OD_B11_MASK - // BK1080 - | PORTCON_PORTB_OD_B15_MASK - ); - - PORTCON_PORTB_OD |= 0 - // SWD CLK - | PORTCON_PORTB_OD_B14_BITS_ENABLE - ; - - // PORT C pin configuration - - PORTCON_PORTC_IE |= 0 - // PTT button - | PORTCON_PORTC_IE_C5_BITS_ENABLE - ; - PORTCON_PORTC_IE &= ~(0 - // BK4819 SCN - | PORTCON_PORTC_IE_C0_MASK - // BK4819 SCL - | PORTCON_PORTC_IE_C1_MASK - // BK4819 SDA - | PORTCON_PORTC_IE_C2_MASK - // Flash Light - | PORTCON_PORTC_IE_C3_MASK - // Speaker - | PORTCON_PORTC_IE_C4_MASK - ); - - PORTCON_PORTC_PU |= 0 - // PTT button - | PORTCON_PORTC_PU_C5_BITS_ENABLE - ; - PORTCON_PORTC_PU &= ~(0 - // BK4819 SCN - | PORTCON_PORTC_PU_C0_MASK - // BK4819 SCL - | PORTCON_PORTC_PU_C1_MASK - // BK4819 SDA - | PORTCON_PORTC_PU_C2_MASK - // Flash Light - | PORTCON_PORTC_PU_C3_MASK - // Speaker - | PORTCON_PORTC_PU_C4_MASK - ); - - PORTCON_PORTC_PD &= ~(0 - // BK4819 SCN - | PORTCON_PORTC_PD_C0_MASK - // BK4819 SCL - | PORTCON_PORTC_PD_C1_MASK - // BK4819 SDA - | PORTCON_PORTC_PD_C2_MASK - // Flash Light - | PORTCON_PORTC_PD_C3_MASK - // Speaker - | PORTCON_PORTC_PD_C4_MASK - // PTT Button - | PORTCON_PORTC_PD_C5_MASK - ); - - PORTCON_PORTC_OD &= ~(0 - // BK4819 SCN - | PORTCON_PORTC_OD_C0_MASK - // BK4819 SCL - | PORTCON_PORTC_OD_C1_MASK - // BK4819 SDA - | PORTCON_PORTC_OD_C2_MASK - // Flash Light - | PORTCON_PORTC_OD_C3_MASK - // Speaker - | PORTCON_PORTC_OD_C4_MASK - ); - PORTCON_PORTC_OD |= 0 - // BK4819 SCN - | PORTCON_PORTC_OD_C0_BITS_DISABLE - // BK4819 SCL - | PORTCON_PORTC_OD_C1_BITS_DISABLE - // BK4819 SDA - | PORTCON_PORTC_OD_C2_BITS_DISABLE - // Flash Light - | PORTCON_PORTC_OD_C3_BITS_DISABLE - // Speaker - | PORTCON_PORTC_OD_C4_BITS_DISABLE - // PTT button - | PORTCON_PORTC_OD_C5_BITS_ENABLE - ; +#ifndef ENABLE_SWD + // A14:13 + InitStruct.Pin = LL_GPIO_PIN_14 | LL_GPIO_PIN_13; + LL_GPIO_Init(GPIOA, &InitStruct); +#endif // ENABLE_SWD } void BOARD_ADC_Init(void) { - ADC_Config_t Config; - - Config.CLK_SEL = SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV2; - Config.CH_SEL = ADC_CH4 | ADC_CH9; - Config.AVG = SARADC_CFG_AVG_VALUE_8_SAMPLE; - Config.CONT = SARADC_CFG_CONT_VALUE_SINGLE; - Config.MEM_MODE = SARADC_CFG_MEM_MODE_VALUE_CHANNEL; - Config.SMPL_CLK = SARADC_CFG_SMPL_CLK_VALUE_INTERNAL; - Config.SMPL_WIN = SARADC_CFG_SMPL_WIN_VALUE_15_CYCLE; - Config.SMPL_SETUP = SARADC_CFG_SMPL_SETUP_VALUE_1_CYCLE; - Config.ADC_TRIG = SARADC_CFG_ADC_TRIG_VALUE_CPU; - Config.CALIB_KD_VALID = SARADC_CALIB_KD_VALID_VALUE_YES; - Config.CALIB_OFFSET_VALID = SARADC_CALIB_OFFSET_VALID_VALUE_YES; - Config.DMA_EN = SARADC_CFG_DMA_EN_VALUE_DISABLE; - Config.IE_CHx_EOC = SARADC_IE_CHx_EOC_VALUE_NONE; - Config.IE_FIFO_FULL = SARADC_IE_FIFO_FULL_VALUE_DISABLE; - Config.IE_FIFO_HFULL = SARADC_IE_FIFO_HFULL_VALUE_DISABLE; - - ADC_Configure(&Config); - ADC_Enable(); - ADC_SoftReset(); + } void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent) { - ADC_Start(); - while (!ADC_CheckEndOfConversion(ADC_CH9)) {} - *pVoltage = ADC_GetValue(ADC_CH4); - *pCurrent = ADC_GetValue(ADC_CH9); + } void BOARD_Init(void) { - BOARD_PORTCON_Init(); BOARD_GPIO_Init(); BACKLIGHT_InitHardware(); BOARD_ADC_Init(); diff --git a/App/board.h b/App/board.h index 48b24747..4bfedfa9 100644 --- a/App/board.h +++ b/App/board.h @@ -22,7 +22,6 @@ void BOARD_FLASH_Init(void); void BOARD_GPIO_Init(void); -void BOARD_PORTCON_Init(void); void BOARD_ADC_Init(void); void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent); void BOARD_Init(void); diff --git a/App/driver/backlight.c b/App/driver/backlight.c index 4830ea6c..7a65493f 100644 --- a/App/driver/backlight.c +++ b/App/driver/backlight.c @@ -15,9 +15,9 @@ */ #include "backlight.h" -#include "bsp/dp32g030/gpio.h" -#include "bsp/dp32g030/pwmplus.h" -#include "bsp/dp32g030/portcon.h" +// #include "bsp/dp32g030/gpio.h" +// #include "bsp/dp32g030/pwmplus.h" +// #include "bsp/dp32g030/portcon.h" #include "driver/gpio.h" #include "settings.h" @@ -40,7 +40,7 @@ bool backlightOn; #endif void BACKLIGHT_InitHardware() -{ +{/* // 48MHz / 94 / 1024 ~ 500Hz const uint32_t PWM_FREQUENCY_HZ = 25000; PWM_PLUS0_CLKSRC |= ((48000000 / 1024 / PWM_FREQUENCY_HZ) << 16); @@ -64,6 +64,7 @@ void BACKLIGHT_InitHardware() PWMPLUS_CFG_CNT_REP_BITS_ENABLE | PWMPLUS_CFG_COUNTER_EN_BITS_ENABLE | 0; + */ } static void BACKLIGHT_Sound(void) @@ -162,7 +163,9 @@ static uint8_t currentBrightness; void BACKLIGHT_SetBrightness(uint8_t brigtness) { currentBrightness = brigtness; + /* PWM_PLUS0_CH0_COMP = value[brigtness] * 4; + */ //PWM_PLUS0_CH0_COMP = (1 << brigtness) - 1; //PWM_PLUS0_SWLOAD = 1; } diff --git a/App/driver/gpio.h b/App/driver/gpio.h index b19bf1c7..be6a539c 100644 --- a/App/driver/gpio.h +++ b/App/driver/gpio.h @@ -1,4 +1,5 @@ -/* Copyright 2023 Dual Tachyon +/* Copyright 2025 muzkr https://github.com/muzkr + * Copyright 2023 Dual Tachyon * https://github.com/DualTachyon * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,72 +19,64 @@ #define DRIVER_GPIO_H #include +#include #include "py32f071_ll_gpio.h" +#define GPIO_MAKE_PIN(Port, PinMask) ((uint32_t)((((uint32_t)(Port)) << 16) | (0xffff & (PinMask)))) +#define GPIO_PORT(Pin) ((GPIO_TypeDef *)((Pin) >> 16)) +#define GPIO_PIN_MASK(Pin) (0xffff & (Pin)) -enum GPIOA_PINS { - GPIOA_PIN_SPI2_SCK = 0, - GPIOA_PIN_SPI2_MOSI = 1, - GPIOA_PIN_SPI2_MISO = 2, - GPIOA_PIN_SPI2_CS = 3, - - GPIOA_PIN_ST7565_A0 = 6, - - GPIOA_PIN_AUDIO_PATH = 8, - - GPIOA_PIN_SWD_IO = 13, - GPIOA_PIN_SWD_CLK = 14, +enum GPIO_PINS +{ + GPIO_PIN_PTT = GPIO_MAKE_PIN(GPIOB, LL_GPIO_PIN_10), + GPIO_PIN_BACKLIGHT = GPIO_MAKE_PIN(GPIOF, LL_GPIO_PIN_8), + GPIO_PIN_FLASHLIGHT = GPIO_MAKE_PIN(GPIOC, LL_GPIO_PIN_13), + GPIO_PIN_AUDIO_PATH = GPIO_MAKE_PIN(GPIOA, LL_GPIO_PIN_8), }; -enum GPIOB_PINS { - GPIOB_PIN_KEYBOARD_0 = 15, - GPIOB_PIN_KEYBOARD_1 = 14, - GPIOB_PIN_KEYBOARD_2 = 13, - GPIOB_PIN_KEYBOARD_3 = 12, - GPIOB_PIN_KEYBOARD_4 = 6, - GPIOB_PIN_KEYBOARD_5 = 5, - GPIOB_PIN_KEYBOARD_6 = 4, - GPIOB_PIN_KEYBOARD_7 = 3, - - GPIOB_PIN_PTT = 10, - - GPIOB_PIN_BK1080 = 15, - - GPIOB_PIN_BK4819_SCL = 8, - GPIOB_PIN_BK4819_SDA = 9, -}; - -enum GPIOC_PINS { - GPIOC_PIN_FLASHLIGHT = 13, -}; - -enum GPIOF_PINS { - GPIOF_PIN_I2C_SCL = 5, - GPIOF_PIN_I2C_SDA = 6, - - GPIOF_PIN_BACKLIGHT = 8, - - GPIOF_PIN_BK4819_SCN = 9, -}; - -// Convert pin ID to pin mask -#define GPIO_PIN_MASK(id) (1u << (id)) - -static inline void GPIO_SetAudioPath() { - LL_GPIO_SetOutputPin(GPIOA, GPIO_PIN_MASK(GPIOA_PIN_AUDIO_PATH)); +static inline void GPIO_SetOutputPin(uint32_t Pin) +{ + LL_GPIO_SetOutputPin(GPIO_PORT(Pin), GPIO_PIN_MASK(Pin)); } -static inline void GPIO_ResetAudioPath() { - LL_GPIO_ResetOutputPin(GPIOA, GPIO_PIN_MASK(GPIOA_PIN_AUDIO_PATH)); +static inline void GPIO_ResetOutputPin(uint32_t Pin) +{ + LL_GPIO_ResetOutputPin(GPIO_PORT(Pin), GPIO_PIN_MASK(Pin)); } -static inline void GPIO_SetBacklight() { - LL_GPIO_SetOutputPin(GPIOF, GPIO_PIN_MASK(GPIOF_PIN_BACKLIGHT)); +static inline void GPIO_TogglePin(uint32_t Pin) +{ + LL_GPIO_TogglePin(GPIO_PORT(Pin), GPIO_PIN_MASK(Pin)); } -static inline void GPIO_ResetBacklight() { - LL_GPIO_ResetOutputPin(GPIOF, GPIO_PIN_MASK(GPIOF_PIN_BACKLIGHT)); +static inline bool GPIO_IsInputPinSet(uint32_t Pin) +{ + return !!LL_GPIO_IsInputPinSet(GPIO_PORT(Pin), GPIO_PIN_MASK(Pin)); +} + +static inline void GPIO_EnableAudioPath() +{ + GPIO_SetOutputPin(GPIO_PIN_AUDIO_PATH); +} + +static inline void GPIO_DisableAudioPath() +{ + GPIO_ResetOutputPin(GPIO_PIN_AUDIO_PATH); +} + +static inline void GPIO_TurnOnBacklight() +{ + GPIO_SetOutputPin(GPIO_PIN_BACKLIGHT); +} + +static inline void GPIO_TurnOffBacklight() +{ + GPIO_ResetOutputPin(GPIO_PIN_BACKLIGHT); +} + +static inline bool GPIO_IsPttPressed() +{ + return !GPIO_IsInputPinSet(GPIO_PIN_PTT); } #endif - diff --git a/App/driver/keyboard.c b/App/driver/keyboard.c index f166f739..c1a34b24 100644 --- a/App/driver/keyboard.c +++ b/App/driver/keyboard.c @@ -27,18 +27,18 @@ KEY_Code_t gKeyReading1 = KEY_INVALID; uint16_t gDebounceCounter = 0; bool gWasFKeyPressed = false; -#define PIN_MASK(n) GPIO_PIN_MASK(GPIOB_PIN_KEYBOARD_##n) +#define GPIOx GPIOB +#define PIN_MASK_COLS (LL_GPIO_PIN_6 | LL_GPIO_PIN_5 | LL_GPIO_PIN_4 | LL_GPIO_PIN_3) +#define PIN_COLS GPIO_MAKE_PIN(GPIOx, PIN_MASK_COLS) +#define PIN_COL(n) GPIO_MAKE_PIN(GPIOx, 1u << (6 - (n))) -static const uint16_t pin_masks[] = { - PIN_MASK(0), - PIN_MASK(1), - PIN_MASK(2), - PIN_MASK(3), - PIN_MASK(4), - PIN_MASK(5), - PIN_MASK(6), - PIN_MASK(7), -}; +#define PIN_MASK_ROWS (LL_GPIO_PIN_15 | LL_GPIO_PIN_14 | LL_GPIO_PIN_13 | LL_GPIO_PIN_12) +#define PIN_MASK_ROW(n) (1u << (15 - (n))) + +static inline uint32_t read_rows() +{ + return PIN_MASK_ROWS & LL_GPIO_ReadInputPort(GPIOx); +} static const KEY_Code_t keyboard[5][4] = { { // Zero col @@ -76,21 +76,6 @@ static const KEY_Code_t keyboard[5][4] = { } }; -static inline void set_cols() -{ - LL_GPIO_SetOutputPin(GPIOB, pin_masks[4] | pin_masks[5] | pin_masks[6] | pin_masks[7]); -} - -static inline void reset_col(uint32_t index) -{ - LL_GPIO_ResetOutputPin(GPIOB, pin_masks[index + 4]); -} - -static inline uint32_t read_rows() -{ - return LL_GPIO_ReadInputPort(GPIOB); -} - KEY_Code_t KEYBOARD_Poll(void) { KEY_Code_t Key = KEY_INVALID; @@ -102,22 +87,22 @@ KEY_Code_t KEYBOARD_Poll(void) for (unsigned int j = 0; j < 5; j++) { - uint16_t reg; + uint32_t reg; unsigned int i; unsigned int k; // Set all high - set_cols(); + GPIO_SetOutputPin(PIN_COLS); // Clear the pin we are selecting if (j > 0) - reset_col(j - 1); + GPIO_ResetOutputPin(PIN_COL(j - 1)); // Read all 4 GPIO pins at once .. with de-noise, max of 8 sample loops for (i = 0, k = 0, reg = 0; i < 3 && k < 8; i++, k++) { SYSTICK_DelayUs(1); - uint16_t reg2 = (uint16_t) read_rows(); + uint32_t reg2 = read_rows(); i *= reg == reg2; reg = reg2; } @@ -127,8 +112,7 @@ KEY_Code_t KEYBOARD_Poll(void) for (unsigned int i = 0; i < 4; i++) { - const uint16_t mask = pin_masks[i]; - if (!(reg & mask)) + if (!(reg & PIN_MASK_ROW(i))) { Key = keyboard[j][i]; break; diff --git a/App/driver/st7565.c b/App/driver/st7565.c index e6493803..22fca16c 100644 --- a/App/driver/st7565.c +++ b/App/driver/st7565.c @@ -17,33 +17,110 @@ #include #include // NULL -#include "bsp/dp32g030/gpio.h" -#include "bsp/dp32g030/spi.h" +#include "py32f071_ll_bus.h" +#include "py32f071_ll_spi.h" +#include "py32f071_ll_gpio.h" #include "driver/gpio.h" -#include "driver/spi.h" #include "driver/st7565.h" #include "driver/system.h" #include "misc.h" +#define SPIx SPI1 + +#define PIN_CS GPIO_MAKE_PIN(GPIOB, LL_GPIO_PIN_2) +#define PIN_A0 GPIO_MAKE_PIN(GPIOA, LL_GPIO_PIN_6) + uint8_t gStatusLine[LCD_WIDTH]; uint8_t gFrameBuffer[FRAME_LINES][LCD_WIDTH]; +static void SPI_Init() +{ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SPI1); + LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); + + do + { + LL_GPIO_InitTypeDef InitStruct; + LL_GPIO_StructInit(&InitStruct); + InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + InitStruct.Alternate = LL_GPIO_AF0_SPI1; + InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + + // SCK: PA5 + InitStruct.Pin = LL_GPIO_PIN_5; + InitStruct.Pull = LL_GPIO_PULL_UP; + LL_GPIO_Init(GPIOA, &InitStruct); + + // SDA: PA7 + InitStruct.Pin = LL_GPIO_PIN_7; + InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &InitStruct); + } while (0); + + LL_SPI_InitTypeDef InitStruct; + LL_SPI_StructInit(&InitStruct); + InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; + InitStruct.Mode = LL_SPI_MODE_MASTER; + InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT; + InitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH; + InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE; + InitStruct.NSS = LL_SPI_NSS_SOFT; + InitStruct.BitOrder = LL_SPI_MSB_FIRST; + InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; + InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV256; + LL_SPI_Init(SPIx, &InitStruct); + + LL_SPI_Enable(SPIx); +} + +static inline void AssertCS() +{ + GPIO_ResetOutputPin(PIN_CS); +} + +static inline void ReleaseCS() +{ + GPIO_SetOutputPin(PIN_CS); +} + +static inline void SetA0() +{ + GPIO_SetOutputPin(PIN_A0); +} + +static inline void ResetA0() +{ + GPIO_ResetOutputPin(PIN_A0); +} + +static uint8_t SPI_WriteByte(uint8_t Value) +{ + while (!LL_SPI_IsActiveFlag_TXE(SPIx)) + ; + + LL_SPI_TransmitData8(SPIx, Value); + + while (!LL_SPI_IsActiveFlag_RXNE(SPIx)) + ; + + return LL_SPI_ReceiveData8(SPIx); +} + static void DrawLine(uint8_t column, uint8_t line, const uint8_t * lineBuffer, unsigned size_defVal) { ST7565_SelectColumnAndLine(column + 4, line); - GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0); + SetA0(); for (unsigned i = 0; i < size_defVal; i++) { - while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} - SPI0->WDR = lineBuffer ? lineBuffer[i] : size_defVal; + SPI_WriteByte(lineBuffer ? lineBuffer[i] : size_defVal); } - SPI_WaitForUndocumentedTxFifoStatusBit(); } void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const uint8_t *pBitmap, const unsigned int Size) { - SPI_ToggleMasterMode(&SPI0->CR, false); + AssertCS(); DrawLine(Column, Line, pBitmap, Size); - SPI_ToggleMasterMode(&SPI0->CR, true); + ReleaseCS(); } @@ -57,7 +134,7 @@ void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const u static void ST7565_BlitScreen(uint8_t line) { - SPI_ToggleMasterMode(&SPI0->CR, false); + AssertCS(); ST7565_WriteByte(0x40); if(line == 0) @@ -75,7 +152,7 @@ void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const u } } - SPI_ToggleMasterMode(&SPI0->CR, true); + ReleaseCS(); } void ST7565_BlitFullScreen(void) @@ -95,38 +172,38 @@ void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const u #else void ST7565_BlitFullScreen(void) { - SPI_ToggleMasterMode(&SPI0->CR, false); + AssertCS(); ST7565_WriteByte(0x40); for (unsigned line = 0; line < FRAME_LINES; line++) { DrawLine(0, line+1, gFrameBuffer[line], LCD_WIDTH); } - SPI_ToggleMasterMode(&SPI0->CR, true); + ReleaseCS(); } void ST7565_BlitLine(unsigned line) { - SPI_ToggleMasterMode(&SPI0->CR, false); + AssertCS(); ST7565_WriteByte(0x40); // start line ? DrawLine(0, line+1, gFrameBuffer[line], LCD_WIDTH); - SPI_ToggleMasterMode(&SPI0->CR, true); + ReleaseCS(); } void ST7565_BlitStatusLine(void) { // the top small text line on the display - SPI_ToggleMasterMode(&SPI0->CR, false); + AssertCS(); ST7565_WriteByte(0x40); // start line ? DrawLine(0, 0, gStatusLine, LCD_WIDTH); - SPI_ToggleMasterMode(&SPI0->CR, true); + ReleaseCS(); } #endif void ST7565_FillScreen(uint8_t value) { - SPI_ToggleMasterMode(&SPI0->CR, false); + AssertCS(); for (unsigned i = 0; i < 8; i++) { DrawLine(0, i, NULL, value); } - SPI_ToggleMasterMode(&SPI0->CR, true); + ReleaseCS(); } // Software reset @@ -212,13 +289,15 @@ uint8_t cmds[] = { #if defined(ENABLE_FEAT_F4HWN_CTR) || defined(ENABLE_FEAT_F4HWN_INV) void ST7565_ContrastAndInv(void) { - SPI_ToggleMasterMode(&SPI0->CR, false); + AssertCS(); ST7565_WriteByte(ST7565_CMD_SOFTWARE_RESET); // software reset for(uint8_t i = 0; i < 8; i++) { ST7565_Cmd(i); } + + // TODO: Release CS?? } #endif @@ -246,9 +325,9 @@ uint8_t cmds[] = { void ST7565_Init(void) { - SPI0_Init(); + SPI_Init(); ST7565_HardwareReset(); - SPI_ToggleMasterMode(&SPI0->CR, false); + AssertCS(); ST7565_WriteByte(ST7565_CMD_SOFTWARE_RESET); // software reset SYSTEM_DelayMs(120); @@ -273,8 +352,8 @@ void ST7565_Init(void) ST7565_WriteByte(ST7565_CMD_SET_START_LINE | 0); // line 0 ST7565_WriteByte(ST7565_CMD_DISPLAY_ON_OFF | 1); // D=1 - SPI_WaitForUndocumentedTxFifoStatusBit(); - SPI_ToggleMasterMode(&SPI0->CR, true); + + ReleaseCS(); ST7565_FillScreen(0x00); } @@ -282,52 +361,43 @@ void ST7565_Init(void) #ifdef ENABLE_FEAT_F4HWN_SLEEP void ST7565_ShutDown(void) { - SPI_ToggleMasterMode(&SPI0->CR, false); + AssertCS(); ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b000); // VB=0 VR=1 VF=1 ST7565_WriteByte(ST7565_CMD_SET_START_LINE | 0); // line 0 ST7565_WriteByte(ST7565_CMD_DISPLAY_ON_OFF | 0); // D=1 - SPI_ToggleMasterMode(&SPI0->CR, true); + ReleaseCS(); } #endif void ST7565_FixInterfGlitch(void) { - SPI_ToggleMasterMode(&SPI0->CR, false); + AssertCS(); for(uint8_t i = 0; i < ARRAY_SIZE(cmds); i++) #ifdef ENABLE_FEAT_F4HWN ST7565_Cmd(i); #else ST7565_WriteByte(cmds[i]); #endif - SPI_WaitForUndocumentedTxFifoStatusBit(); - SPI_ToggleMasterMode(&SPI0->CR, true); + + ReleaseCS(); } void ST7565_HardwareReset(void) { - GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES); - SYSTEM_DelayMs(1); - GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES); - SYSTEM_DelayMs(20); - GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES); - SYSTEM_DelayMs(120); + // Not supported on K1 + // TODO: Delete this function } void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line) { - GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0); - while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} - SPI0->WDR = Line + 176; - while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} - SPI0->WDR = ((Column >> 4) & 0x0F) | 0x10; - while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} - SPI0->WDR = ((Column >> 0) & 0x0F); - SPI_WaitForUndocumentedTxFifoStatusBit(); + ResetA0(); + SPI_WriteByte(Line + 176); + SPI_WriteByte(((Column >> 4) & 0x0F) | 0x10); + SPI_WriteByte((Column >> 0) & 0x0F); } void ST7565_WriteByte(uint8_t Value) { - GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0); - while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} - SPI0->WDR = Value; + ResetA0(); + SPI_WriteByte(Value); } diff --git a/App/main.c b/App/main.c index 97863213..fd3ef8ac 100644 --- a/App/main.c +++ b/App/main.c @@ -72,19 +72,6 @@ void _putchar(__attribute__((unused)) char c) void Main(void) { - // Enable clock gating of blocks we need - SYSCON_DEV_CLK_GATE = 0 - | SYSCON_DEV_CLK_GATE_GPIOA_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_GPIOB_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_GPIOC_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_UART1_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_CRC_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_PWM_PLUS0_BITS_ENABLE; - - SYSTICK_Init(); BOARD_Init();