Port K1 drivers

Port drivers:  gpio, keyboad, system, systick, uart, flashlight
This commit is contained in:
muzkr committed 2025-10-22 18:39:11 +08:00
1 parent 60ba4cbea6
commit ebac7e87f3
11 files changed
+242 -222

No files matched your search

+10 -6
View File
@@ -1,7 +1,7 @@
add_library(App INTERFACE)
target_include_directories(App INTERFACE .)
target_link_libraries(App INTERFACE PY32F071_Driver printf)
target_link_libraries(App INTERFACE PY32F071_Driver)
target_compile_definitions(App INTERFACE PRINTF_INCLUDE_CONFIG_H)
target_sources(App INTERFACE
@@ -10,13 +10,13 @@ target_sources(App INTERFACE
# driver/backlight.c
# driver/bk4819.c
# driver/eeprom.c
# driver/gpio.c
driver/gpio.c
# driver/i2c.c
# driver/keyboard.c
driver/keyboard.c
# driver/spi.c
# driver/st7565.c
# driver/system.c
# driver/systick.c
driver/system.c
driver/systick.c
# Main
app/action.c
app/app.c
@@ -85,6 +85,10 @@ if(NOT SQL_TONE)
endif()
target_compile_definitions(App INTERFACE SQL_TONE=${SQL_TONE})
if(ENABLE_AIRCOPY AND ENABLE_UART)
target_sources(App INTERFACE driver/crc.c)
endif()
# ---- STOCK QUANSHENG FEATURES ----
enable_feature(ENABLE_FMRADIO
@@ -95,7 +99,7 @@ enable_feature(ENABLE_FMRADIO
enable_feature(ENABLE_UART
driver/uart.c
app/uart.c
driver/aes.c
# driver/aes.c
)
enable_feature(ENABLE_AIRCOPY
app/aircopy.c
+13 -9
View File
@@ -1,9 +1,13 @@
#ifdef ENABLE_FLASHLIGHT
#include "driver/gpio.h"
#include "bsp/dp32g030/gpio.h"
#include "app/flashlight.h"
#include <stdbool.h>
#include "flashlight.h"
#define FLASHLIGHT_PIN GPIO_PIN_MASK(GPIOC_PIN_FLASHLIGHT)
static inline void Flashlight_TurnOn(){ LL_GPIO_SetOutputPin(GPIOC, FLASHLIGHT_PIN); }
static inline void Flashlight_TurnOff(){ LL_GPIO_ResetOutputPin(GPIOC, FLASHLIGHT_PIN); }
static inline void Flashlight_Toggle(){ LL_GPIO_TogglePin(GPIOC, FLASHLIGHT_PIN); }
#if !defined(ENABLE_FEAT_F4HWN) || defined(ENABLE_FEAT_F4HWN_RESCUE_OPS)
enum FlashlightMode_t gFlashLightState;
@@ -11,7 +15,7 @@
void FlashlightTimeSlice()
{
if (gFlashLightState == FLASHLIGHT_BLINK && (gFlashLightBlinkCounter & 15u) == 0) {
GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
Flashlight_Toggle();
return;
}
@@ -28,9 +32,9 @@
if (gFlashLightBlinkCounter == next) {
if (c==0) {
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
Flashlight_TurnOff();
} else {
GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
Flashlight_Toggle();
}
if (c >= 18) {
@@ -51,7 +55,7 @@
switch (gFlashLightState) {
case FLASHLIGHT_OFF:
gFlashLightState++;
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
Flashlight_TurnOn();
break;
case FLASHLIGHT_ON:
case FLASHLIGHT_BLINK:
@@ -60,7 +64,7 @@
case FLASHLIGHT_SOS:
default:
gFlashLightState = 0;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
Flashlight_TurnOff();
}
}
#else
@@ -70,11 +74,11 @@
if(gFlashLightState)
{
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
Flashlight_TurnOff();
}
else
{
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
Flashlight_TurnOn();
}
gFlashLightState = (gFlashLightState) ? false : true;
+10 -8
View File
@@ -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");
@@ -24,9 +25,7 @@
#endif
#include "app/uart.h"
#include "board.h"
#include "bsp/dp32g030/dma.h"
#include "bsp/dp32g030/gpio.h"
#include "driver/aes.h"
#include "py32f071_ll_dma.h"
#include "driver/backlight.h"
#include "driver/bk4819.h"
#include "driver/crc.h"
@@ -218,6 +217,8 @@ static void SendVersion(void)
#ifndef ENABLE_FEAT_F4HWN
static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint32_t *pResponse)
{
// PY32 has no AES hardware
/*
unsigned int i;
uint32_t IV[4];
@@ -231,6 +232,7 @@ static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint
for (i = 0; i < 4; i++)
if (IV[i] != pResponse[i])
return true;
*/
return false;
}
@@ -489,9 +491,9 @@ bool UART_IsCommandAvailable(void)
uint16_t Index;
uint16_t TailIndex;
uint16_t Size;
uint16_t CRC;
uint16_t Crc;
uint16_t CommandLength;
uint16_t DmaLength = DMA_CH0->ST & 0xFFFU;
uint16_t DmaLength = sizeof(UART_DMA_Buffer) - LL_DMA_GetDataLength(DMA1, LL_DMA_CHANNEL_2);
while (1)
{
@@ -572,9 +574,9 @@ bool UART_IsCommandAvailable(void)
UART_Command.Buffer[i] ^= Obfuscation[i % 16];
}
CRC = UART_Command.Buffer[Size] | (UART_Command.Buffer[Size + 1] << 8);
Crc = UART_Command.Buffer[Size] | (UART_Command.Buffer[Size + 1] << 8);
return (CRC_Calculate(UART_Command.Buffer, Size) != CRC) ? false : true;
return (CRC_Calculate(UART_Command.Buffer, Size) != Crc) ? false : true;
}
void UART_HandleCommand(void)
+18 -18
View File
@@ -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");
@@ -14,21 +15,10 @@
* limitations under the License.
*/
#include "../bsp/dp32g030/crc.h"
#include "crc.h"
void CRC_Init(void)
{
CRC_CR = 0
| CRC_CR_CRC_EN_BITS_DISABLE
| CRC_CR_INPUT_REV_BITS_NORMAL
| CRC_CR_INPUT_INV_BITS_NORMAL
| CRC_CR_OUTPUT_REV_BITS_NORMAL
| CRC_CR_OUTPUT_INV_BITS_NORMAL
| CRC_CR_DATA_WIDTH_BITS_8
| CRC_CR_CRC_SEL_BITS_CRC_16_CCITT
;
CRC_IV = 0;
}
uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size)
@@ -36,14 +26,24 @@ uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size)
const uint8_t *pData = (const uint8_t *)pBuffer;
uint16_t i, Crc;
CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_ENABLE;
Crc = 0;
for (i = 0; i < Size; i++)
{
Crc ^= (pData[i] << 8);
for (i = 0; i < Size; i++) {
CRC_DATAIN = pData[i];
for (int j = 0; j < 8; j++)
{
// Check bit [15]
if (Crc >> 15)
{
Crc = (Crc << 1) ^ 0x1021;
}
else
{
Crc = Crc << 1;
}
}
}
Crc = (uint16_t)CRC_DATAOUT;
CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_DISABLE;
return Crc;
}
+44 -33
View File
@@ -18,60 +18,71 @@
#define DRIVER_GPIO_H
#include <stdint.h>
#include "py32f071_ll_gpio.h"
enum GPIOA_PINS {
GPIOA_PIN_KEYBOARD_0 = 3,
GPIOA_PIN_KEYBOARD_1 = 4,
GPIOA_PIN_KEYBOARD_2 = 5,
GPIOA_PIN_KEYBOARD_3 = 6,
GPIOA_PIN_KEYBOARD_4 = 10, // Shared with I2C!
GPIOA_PIN_KEYBOARD_5 = 11, // Shared with I2C!
GPIOA_PIN_KEYBOARD_6 = 12, // Shared with voice chip!
GPIOA_PIN_KEYBOARD_7 = 13, // Shared with voice chip!
GPIOA_PIN_SPI2_SCK = 0,
GPIOA_PIN_SPI2_MOSI = 1,
GPIOA_PIN_SPI2_MISO = 2,
GPIOA_PIN_SPI2_CS = 3,
GPIOA_PIN_I2C_SCL = 10, // Shared with keyboard!
GPIOA_PIN_I2C_SDA = 11, // Shared with keyboard!
GPIOA_PIN_ST7565_A0 = 6,
GPIOA_PIN_VOICE_0 = 12, // Shared with keyboard!
GPIOA_PIN_VOICE_1 = 13 // Shared with keyboard!
GPIOA_PIN_AUDIO_PATH = 8,
GPIOA_PIN_SWD_IO = 13,
GPIOA_PIN_SWD_CLK = 14,
};
enum GPIOB_PINS {
GPIOB_PIN_BACKLIGHT = 6,
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_ST7565_A0 = 9,
GPIOB_PIN_ST7565_RES = 11, // Shared with SWD!
GPIOB_PIN_PTT = 10,
GPIOB_PIN_SWD_IO = 11, // Shared with ST7565!
GPIOB_PIN_SWD_CLK = 14,
GPIOB_PIN_BK1080 = 15,
GPIOB_PIN_BK1080 = 15
GPIOB_PIN_BK4819_SCL = 8,
GPIOB_PIN_BK4819_SDA = 9,
};
enum GPIOC_PINS {
GPIOC_PIN_BK4819_SCN = 0,
GPIOC_PIN_BK4819_SCL = 1,
GPIOC_PIN_BK4819_SDA = 2,
GPIOC_PIN_FLASHLIGHT = 3,
GPIOC_PIN_AUDIO_PATH = 4,
GPIOC_PIN_PTT = 5
GPIOC_PIN_FLASHLIGHT = 13,
};
static inline void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit) {
*pReg &= ~(1U << Bit);
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 uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit) {
return (*pReg >> Bit) & 1U;
static inline void GPIO_ResetAudioPath() {
LL_GPIO_ResetOutputPin(GPIOA, GPIO_PIN_MASK(GPIOA_PIN_AUDIO_PATH));
}
static inline void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit) {
*pReg ^= 1U << Bit;
static inline void GPIO_SetBacklight() {
LL_GPIO_SetOutputPin(GPIOF, GPIO_PIN_MASK(GPIOF_PIN_BACKLIGHT));
}
static inline void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit) {
*pReg |= 1U << Bit;
static inline void GPIO_ResetBacklight() {
LL_GPIO_ResetOutputPin(GPIOF, GPIO_PIN_MASK(GPIOF_PIN_BACKLIGHT));
}
#endif
+64 -74
View File
@@ -1,4 +1,5 @@
/* Copyright 2023 Manuel Jinger
/* Copyright 2025 muzkr https://github.com/muzkr
* Copyright 2023 Manuel Jinger
* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
@@ -15,7 +16,6 @@
* limitations under the License.
*/
#include "bsp/dp32g030/gpio.h"
#include "driver/gpio.h"
#include "driver/keyboard.h"
#include "driver/systick.h"
@@ -27,71 +27,70 @@ KEY_Code_t gKeyReading1 = KEY_INVALID;
uint16_t gDebounceCounter = 0;
bool gWasFKeyPressed = false;
static const struct {
#define PIN_MASK(n) GPIO_PIN_MASK(GPIOB_PIN_KEYBOARD_##n)
// Using a 16 bit pre-calculated shift and invert is cheaper
// than using 8 bit and doing shift and invert in code.
uint16_t set_to_zero_mask;
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),
};
// We are very fortunate.
// The key and pin defines fit together in a single u8, making this very efficient
struct {
KEY_Code_t key : 5;
uint8_t pin : 3; // Pin 6 is highest
} pins[4];
} keyboard[] = {
{ // Zero row
static const KEY_Code_t keyboard[5][4] = {
{ // Zero col
// Set to zero to handle special case of nothing pulled down
.set_to_zero_mask = 0xffff,
.pins = {
{ .key = KEY_SIDE1, .pin = GPIOA_PIN_KEYBOARD_0},
{ .key = KEY_SIDE2, .pin = GPIOA_PIN_KEYBOARD_1},
KEY_SIDE1,
KEY_SIDE2,
// Duplicate to fill the array with valid values
{ .key = KEY_INVALID, .pin = GPIOA_PIN_KEYBOARD_1},
{ .key = KEY_INVALID, .pin = GPIOA_PIN_KEYBOARD_1}
}
KEY_INVALID,
KEY_INVALID,
},
{ // First row
.set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_4) & 0xffff,
.pins = {
{ .key = KEY_MENU, .pin = GPIOA_PIN_KEYBOARD_0},
{ .key = KEY_1, .pin = GPIOA_PIN_KEYBOARD_1},
{ .key = KEY_4, .pin = GPIOA_PIN_KEYBOARD_2},
{ .key = KEY_7, .pin = GPIOA_PIN_KEYBOARD_3}
}
{ // First col
KEY_MENU,
KEY_1,
KEY_4,
KEY_7,
},
{ // Second row
.set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_5) & 0xffff,
.pins = {
{ .key = KEY_UP, .pin = GPIOA_PIN_KEYBOARD_0},
{ .key = KEY_2 , .pin = GPIOA_PIN_KEYBOARD_1},
{ .key = KEY_5 , .pin = GPIOA_PIN_KEYBOARD_2},
{ .key = KEY_8 , .pin = GPIOA_PIN_KEYBOARD_3}
}
{ // Second col
KEY_UP,
KEY_2 ,
KEY_5 ,
KEY_8 ,
},
{ // Third row
.set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_6) & 0xffff,
.pins = {
{ .key = KEY_DOWN, .pin = GPIOA_PIN_KEYBOARD_0},
{ .key = KEY_3 , .pin = GPIOA_PIN_KEYBOARD_1},
{ .key = KEY_6 , .pin = GPIOA_PIN_KEYBOARD_2},
{ .key = KEY_9 , .pin = GPIOA_PIN_KEYBOARD_3}
}
{ // Third col
KEY_DOWN,
KEY_3 ,
KEY_6 ,
KEY_9 ,
},
{ // Fourth row
.set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_7) & 0xffff,
.pins = {
{ .key = KEY_EXIT, .pin = GPIOA_PIN_KEYBOARD_0},
{ .key = KEY_STAR, .pin = GPIOA_PIN_KEYBOARD_1},
{ .key = KEY_0 , .pin = GPIOA_PIN_KEYBOARD_2},
{ .key = KEY_F , .pin = GPIOA_PIN_KEYBOARD_3}
}
{ // Fourth col
KEY_EXIT,
KEY_STAR,
KEY_0 ,
KEY_F ,
}
};
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;
@@ -101,25 +100,24 @@ KEY_Code_t KEYBOARD_Poll(void)
// *****************
for (unsigned int j = 0; j < ARRAY_SIZE(keyboard); j++)
for (unsigned int j = 0; j < 5; j++)
{
uint16_t reg;
unsigned int i;
unsigned int k;
// Set all high
GPIOA->DATA |= 1u << GPIOA_PIN_KEYBOARD_4 |
1u << GPIOA_PIN_KEYBOARD_5 |
1u << GPIOA_PIN_KEYBOARD_6 |
1u << GPIOA_PIN_KEYBOARD_7;
set_cols();
// Clear the pin we are selecting
GPIOA->DATA &= keyboard[j].set_to_zero_mask;
if (j > 0)
reset_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++) {
for (i = 0, k = 0, reg = 0; i < 3 && k < 8; i++, k++)
{
SYSTICK_DelayUs(1);
uint16_t reg2 = GPIOA->DATA;
uint16_t reg2 = (uint16_t) read_rows();
i *= reg == reg2;
reg = reg2;
}
@@ -127,12 +125,12 @@ KEY_Code_t KEYBOARD_Poll(void)
if (i < 3)
break; // noise is too bad
for (unsigned int i = 0; i < ARRAY_SIZE(keyboard[j].pins); i++)
for (unsigned int i = 0; i < 4; i++)
{
const uint16_t mask = 1u << keyboard[j].pins[i].pin;
const uint16_t mask = pin_masks[i];
if (!(reg & mask))
{
Key = keyboard[j].pins[i].key;
Key = keyboard[j][i];
break;
}
}
@@ -141,13 +139,5 @@ KEY_Code_t KEYBOARD_Poll(void)
break;
}
// Create I2C stop condition since we might have toggled I2C pins
// This leaves GPIOA_PIN_KEYBOARD_4 and GPIOA_PIN_KEYBOARD_5 high
I2C_Stop();
// Reset VOICE pins
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6);
GPIO_SetBit( &GPIOA->DATA, GPIOA_PIN_KEYBOARD_7);
return Key;
}
+2 -12
View File
@@ -14,10 +14,8 @@
* limitations under the License.
*/
#include "../bsp/dp32g030/pmu.h"
#include "../bsp/dp32g030/syscon.h"
#include "system.h"
#include "systick.h"
#include "driver/system.h"
#include "driver/systick.h"
void SYSTEM_DelayMs(uint32_t Delay)
{
@@ -26,12 +24,4 @@ void SYSTEM_DelayMs(uint32_t Delay)
void SYSTEM_ConfigureClocks(void)
{
// Set source clock from external crystal
PMU_SRC_CFG = (PMU_SRC_CFG & ~(PMU_SRC_CFG_RCHF_SEL_MASK | PMU_SRC_CFG_RCHF_EN_MASK)) | PMU_SRC_CFG_RCHF_SEL_BITS_48MHZ | PMU_SRC_CFG_RCHF_EN_BITS_ENABLE;
// Divide by 2
SYSCON_CLK_SEL = SYSCON_CLK_SEL_DIV_BITS_2;
// Disable division clock gate
SYSCON_DIV_CLK_GATE = (SYSCON_DIV_CLK_GATE & ~SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_MASK) | SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_BITS_DISABLE;
}
+2 -2
View File
@@ -14,9 +14,9 @@
* limitations under the License.
*/
#include "ARMCM0.h"
#include "py32f0xx.h"
#include "systick.h"
#include "../misc.h"
#include "misc.h"
// 0x20000324
static uint32_t gTickMultiplier;
+78 -59
View File
@@ -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");
@@ -16,73 +17,90 @@
#include <stdbool.h>
#include <string.h>
#include "bsp/dp32g030/dma.h"
#include "bsp/dp32g030/syscon.h"
#include "bsp/dp32g030/uart.h"
#include "py32f071_ll_bus.h"
#include "py32f071_ll_system.h"
#include "py32f071_ll_dma.h"
#include "py32f071_ll_gpio.h"
#include "py32f071_ll_usart.h"
#include "driver/uart.h"
#define _DMA_CHANNEL LL_DMA_CHANNEL_2
static bool UART_IsLogEnabled;
uint8_t UART_DMA_Buffer[256];
void UART_Init(void)
{
uint32_t Delta;
uint32_t Positive;
uint32_t Frequency;
// PA9 TX
// PA10 RX
UART1->CTRL = (UART1->CTRL & ~UART_CTRL_UARTEN_MASK) | UART_CTRL_UARTEN_BITS_DISABLE;
Delta = SYSCON_RC_FREQ_DELTA;
Positive = (Delta & SYSCON_RC_FREQ_DELTA_RCHF_SIG_MASK) >> SYSCON_RC_FREQ_DELTA_RCHF_SIG_SHIFT;
Frequency = (Delta & SYSCON_RC_FREQ_DELTA_RCHF_DELTA_MASK) >> SYSCON_RC_FREQ_DELTA_RCHF_DELTA_SHIFT;
if (Positive) {
Frequency += 48000000U;
} else {
Frequency = 48000000U - Frequency;
}
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SYSCFG);
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_USART1);
UART1->BAUD = Frequency / 39053U;
UART1->CTRL = UART_CTRL_RXEN_BITS_ENABLE | UART_CTRL_TXEN_BITS_ENABLE | UART_CTRL_RXDMAEN_BITS_ENABLE;
UART1->RXTO = 4;
UART1->FC = 0;
UART1->FIFO = UART_FIFO_RF_LEVEL_BITS_8_BYTE | UART_FIFO_RF_CLR_BITS_ENABLE | UART_FIFO_TF_CLR_BITS_ENABLE;
UART1->IE = 0;
// Pins
do
{
LL_GPIO_InitTypeDef GPIO_InitStruct;
LL_GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_9 | LL_GPIO_PIN_10;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Alternate = LL_GPIO_AF1_USART1;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_DISABLE;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
} while (0);
DMA_CH0->MSADDR = (uint32_t)(uintptr_t)&UART1->RDR;
DMA_CH0->MDADDR = (uint32_t)(uintptr_t)UART_DMA_Buffer;
DMA_CH0->MOD = 0
// Source
| DMA_CH_MOD_MS_ADDMOD_BITS_NONE
| DMA_CH_MOD_MS_SIZE_BITS_8BIT
| DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS1
// Destination
| DMA_CH_MOD_MD_ADDMOD_BITS_INCREMENT
| DMA_CH_MOD_MD_SIZE_BITS_8BIT
| DMA_CH_MOD_MD_SEL_BITS_SRAM
;
DMA_INTEN = 0;
DMA_INTST = 0
| DMA_INTST_CH0_TC_INTST_BITS_SET
| DMA_INTST_CH1_TC_INTST_BITS_SET
| DMA_INTST_CH2_TC_INTST_BITS_SET
| DMA_INTST_CH3_TC_INTST_BITS_SET
| DMA_INTST_CH0_THC_INTST_BITS_SET
| DMA_INTST_CH1_THC_INTST_BITS_SET
| DMA_INTST_CH2_THC_INTST_BITS_SET
| DMA_INTST_CH3_THC_INTST_BITS_SET
;
DMA_CH0->CTR = 0
| DMA_CH_CTR_CH_EN_BITS_ENABLE
| ((0xFF << DMA_CH_CTR_LENGTH_SHIFT) & DMA_CH_CTR_LENGTH_MASK)
| DMA_CH_CTR_LOOP_BITS_ENABLE
| DMA_CH_CTR_PRI_BITS_MEDIUM
;
UART1->IF = UART_IF_RXTO_BITS_SET;
// DMA
do
{
LL_DMA_DisableChannel(DMA1, _DMA_CHANNEL);
DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_ENABLE;
LL_DMA_InitTypeDef DMA_InitStruct;
LL_DMA_StructInit(&DMA_InitStruct);
UART1->CTRL |= UART_CTRL_UARTEN_BITS_ENABLE;
DMA_InitStruct.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
DMA_InitStruct.Mode = LL_DMA_MODE_CIRCULAR;
DMA_InitStruct.PeriphOrM2MSrcAddress = LL_USART_DMA_GetRegAddr(USART1);
DMA_InitStruct.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
DMA_InitStruct.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
DMA_InitStruct.MemoryOrM2MDstAddress = (uint32_t)UART_DMA_Buffer;
DMA_InitStruct.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
DMA_InitStruct.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
DMA_InitStruct.NbData = sizeof(UART_DMA_Buffer);
DMA_InitStruct.Priority = LL_DMA_PRIORITY_HIGH;
LL_DMA_Init(DMA1, _DMA_CHANNEL, &DMA_InitStruct);
LL_SYSCFG_SetDMARemap(DMA1, _DMA_CHANNEL, LL_SYSCFG_DMA_MAP_USART1_RD);
} while (0);
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_USART1);
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_USART1);
// USART
do
{
LL_USART_Disable(USART1);
LL_USART_InitTypeDef USART_InitStruct;
LL_USART_StructInit(&USART_InitStruct);
USART_InitStruct.BaudRate = 38400;
USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
LL_USART_Init(USART1, &USART_InitStruct);
LL_USART_EnableDMAReq_RX(USART1);
} while (0);
LL_DMA_EnableChannel(DMA1, _DMA_CHANNEL);
LL_USART_Enable(USART1);
LL_USART_TransmitData8(USART1, 0);
}
void UART_Send(const void *pBuffer, uint32_t Size)
@@ -90,10 +108,11 @@ void UART_Send(const void *pBuffer, uint32_t Size)
const uint8_t *pData = (const uint8_t *)pBuffer;
uint32_t i;
for (i = 0; i < Size; i++) {
UART1->TDR = pData[i];
while ((UART1->IF & UART_IF_TXFIFO_FULL_MASK) != UART_IF_TXFIFO_FULL_BITS_NOT_SET) {
}
for (i = 0; i < Size; i++)
{
while (!LL_USART_IsActiveFlag_TXE(USART1))
;
LL_USART_TransmitData8(USART1, pData[i]);
}
}
+1
View File
@@ -19,6 +19,7 @@
#define DRIVER_UART_H
#include <stdint.h>
#include <stdbool.h>
extern uint8_t UART_DMA_Buffer[256];
-1
View File
@@ -59,7 +59,6 @@ endif()
add_executable(${EXE_NAME})
add_subdirectory(Drivers)
add_subdirectory(external)
add_subdirectory(Core)
add_subdirectory(App)