Skip to content

Commit

Permalink
[nanokit] Pulls nRESET and GPIO_B_01 with DTR and RTS of CDC ACM
Browse files Browse the repository at this point in the history
  • Loading branch information
xychen committed Aug 30, 2024
1 parent 0e4d130 commit eca8189
Showing 1 changed file with 193 additions and 4 deletions.
197 changes: 193 additions & 4 deletions source/hic_hal/stm32/stm32f103xb/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "util.h"
#include "circ_buf.h"
#include "IO_Config.h"
#include "cmsis_os2.h"

// For usart
#define CDC_UART USART2
Expand All @@ -38,6 +39,16 @@
#define UART_PINS_PORT_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define UART_PINS_PORT_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()

// For CSK update
#define CDC_UART2 USART3
#define CDC_UART2_ENABLE() __HAL_RCC_USART3_CLK_ENABLE()
#define CDC_UART2_DISABLE() __HAL_RCC_USART3_CLK_DISABLE()
#define CDC_UART2_IRQn USART3_IRQn
#define CDC_UART2_IRQn_Handler USART3_IRQHandler

#define UART2_PINS_PORT_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define UART2_PINS_PORT_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()

#define UART_TX_PORT GPIOA
#define UART_TX_PIN GPIO_PIN_2

Expand All @@ -47,14 +58,36 @@
#define UART_CTS_PORT GPIOA
#define UART_CTS_PIN GPIO_PIN_0

#define UART_RTS_PORT GPIOA
#define UART_RTS_PIN GPIO_PIN_1
#define UART_RTS_PORT GPIOB
#define UART_RTS_PIN GPIO_PIN_3

#define UART_DTR_PORT GPIOB
#define UART_DTR_PIN GPIO_PIN_4

// For CSK update
#define CSK_BOOT_PORT GPIOA
#define CSK_BOOT_PIN GPIO_PIN_6

#define CSK_RESET_PORT GPIOB
#define CSK_RESET_PIN GPIO_PIN_0

#define UART2_TX_PORT GPIOB
#define UART2_TX_PIN GPIO_PIN_10

#define UART2_RX_PORT GPIOB
#define UART2_RX_PIN GPIO_PIN_11


#define RX_OVRF_MSG "<DAPLink:Overflow>\n"
#define RX_OVRF_MSG_SIZE (sizeof(RX_OVRF_MSG) - 1)
#define BUFFER_SIZE (512)

#define CTRL_DTR_BIT (1 << 0)
#define CTRL_RTS_BIT (1 << 1)

uint8_t update_mode = 0;
uint8_t last_dtr = 0;

circ_buf_t write_buffer;
uint8_t write_buffer_data[BUFFER_SIZE];
circ_buf_t read_buffer;
Expand All @@ -78,15 +111,88 @@ static void clear_buffers(void)
circ_buf_init(&read_buffer, read_buffer_data, sizeof(read_buffer_data));
}

void uart2_set_configuration(uint32_t baud_rate)
{
UART_HandleTypeDef uart_handle;

memset(&uart_handle, 0, sizeof(uart_handle));
uart_handle.Instance = CDC_UART2;
uart_handle.Init.Parity = HAL_UART_PARITY_NONE;
uart_handle.Init.StopBits = UART_STOPBITS_1;
uart_handle.Init.WordLength = UART_WORDLENGTH_8B;
uart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
uart_handle.Init.BaudRate = baud_rate;
uart_handle.Init.Mode = UART_MODE_TX_RX;

// Disable uart and tx/rx interrupt
CDC_UART2->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE);

HAL_UART_DeInit(&uart_handle);
HAL_UART_Init(&uart_handle);

CDC_UART2->CR1 |= USART_IT_RXNE;
}

void uart2_enable(void)
{
CDC_UART->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE);
NVIC_DisableIRQ(CDC_UART_IRQn);

CDC_UART2->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE);

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = UART2_TX_PIN;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(UART2_TX_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pin = UART2_RX_PIN;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_PULLUP;
HAL_GPIO_Init(UART2_RX_PORT, &GPIO_InitStructure);

NVIC_EnableIRQ(CDC_UART2_IRQn);

uart2_set_configuration(115200);
}

void uart2_disable(void)
{
CDC_UART2->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE);
NVIC_DisableIRQ(CDC_UART2_IRQn);

UART_HandleTypeDef uart_handle;
memset(&uart_handle, 0, sizeof(uart_handle));
uart_handle.Instance = CDC_UART2;
HAL_UART_DeInit(&uart_handle);

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = UART2_TX_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(UART2_TX_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pin = UART2_RX_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(UART2_RX_PORT, &GPIO_InitStructure);

CDC_UART->CR1 &= ~USART_IT_TXE;
NVIC_EnableIRQ(CDC_UART_IRQn);
}

int32_t uart_initialize(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

CDC_UART->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE);
CDC_UART2->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE);
clear_buffers();

CDC_UART_ENABLE();
UART_PINS_PORT_ENABLE();
CDC_UART2_ENABLE();
UART2_PINS_PORT_ENABLE();

//TX pin
GPIO_InitStructure.Pin = UART_TX_PIN;
Expand All @@ -106,11 +212,30 @@ int32_t uart_initialize(void)
GPIO_InitStructure.Pull = GPIO_PULLUP;
HAL_GPIO_Init(UART_CTS_PORT, &GPIO_InitStructure);
//RTS pin, output low
HAL_GPIO_WritePin(UART_RTS_PORT, UART_RTS_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(UART_RTS_PORT, UART_RTS_PIN, GPIO_PIN_SET);
GPIO_InitStructure.Pin = UART_RTS_PIN;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(UART_RTS_PORT, &GPIO_InitStructure);
//DTR pin, output low
HAL_GPIO_WritePin(UART_DTR_PORT, UART_DTR_PIN, GPIO_PIN_SET);
GPIO_InitStructure.Pin = UART_DTR_PIN;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(UART_DTR_PORT, &GPIO_InitStructure);

// CSK BOOT pin, open-drain low
HAL_GPIO_WritePin(CSK_BOOT_PORT, CSK_BOOT_PIN, GPIO_PIN_SET);
GPIO_InitStructure.Pin = CSK_BOOT_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(CSK_BOOT_PORT, &GPIO_InitStructure);
// CSK RESET pin, open-drain low
HAL_GPIO_WritePin(CSK_RESET_PORT, CSK_RESET_PIN, GPIO_PIN_SET);
GPIO_InitStructure.Pin = CSK_RESET_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(CSK_RESET_PORT, &GPIO_InitStructure);

NVIC_EnableIRQ(CDC_UART_IRQn);

Expand All @@ -120,16 +245,20 @@ int32_t uart_initialize(void)
int32_t uart_uninitialize(void)
{
CDC_UART->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE);
CDC_UART2->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE);
clear_buffers();
return 1;
}

int32_t uart_reset(void)
{
const uint32_t cr1 = CDC_UART->CR1;
const uint32_t cr21 = CDC_UART2->CR1;
CDC_UART->CR1 = cr1 & ~(USART_IT_TXE | USART_IT_RXNE);
CDC_UART2->CR1 = cr21 & ~(USART_IT_TXE | USART_IT_RXNE);
clear_buffers();
CDC_UART->CR1 = cr1 & ~USART_IT_TXE;
CDC_UART2->CR1 = cr21 & ~USART_IT_TXE;
return 1;
}

Expand All @@ -138,6 +267,11 @@ int32_t uart_set_configuration(UART_Configuration *config)
UART_HandleTypeDef uart_handle;
HAL_StatusTypeDef status;

if (update_mode) {
uart2_set_configuration(config->Baudrate);
return 1;
}

memset(&uart_handle, 0, sizeof(uart_handle));
uart_handle.Instance = CDC_UART;

Expand Down Expand Up @@ -216,6 +350,32 @@ int32_t uart_get_configuration(UART_Configuration *config)

void uart_set_control_line_state(uint16_t ctrl_bmp)
{
uint8_t rts = ctrl_bmp & CTRL_RTS_BIT;
uint8_t dtr = ctrl_bmp & CTRL_DTR_BIT;
HAL_GPIO_WritePin(UART_RTS_PORT, UART_RTS_PIN, rts ? GPIO_PIN_RESET : GPIO_PIN_SET);
HAL_GPIO_WritePin(UART_DTR_PORT, UART_DTR_PIN, dtr ? GPIO_PIN_RESET : GPIO_PIN_SET);

// Boot pin and USART3 (for update_mode) are controlled by RTS
// Some host may pull both RTS and DTR down by default. Thus only trust the
// level when RTS and DTR are different.
uint8_t boot = rts && !dtr;
HAL_GPIO_WritePin(CSK_BOOT_PORT, CSK_BOOT_PIN, boot ? GPIO_PIN_RESET : GPIO_PIN_SET);
if (update_mode && !boot) {
uart2_disable();
} else if (!update_mode && boot) {
uart2_enable();
}
update_mode = boot;

// Reset pin is controlled by DTR
// Some host may pull DTR down by default, so we need to perform the reset
// only when a rising edge is detected.
if (last_dtr && !dtr) {
HAL_GPIO_WritePin(CSK_RESET_PORT, CSK_RESET_PIN, GPIO_PIN_RESET);
osDelay(2);
HAL_GPIO_WritePin(CSK_RESET_PORT, CSK_RESET_PIN, GPIO_PIN_SET);
}
last_dtr = dtr;
}

int32_t uart_write_free(void)
Expand All @@ -226,7 +386,11 @@ int32_t uart_write_free(void)
int32_t uart_write_data(uint8_t *data, uint16_t size)
{
uint32_t cnt = circ_buf_write(&write_buffer, data, size);
CDC_UART->CR1 |= USART_IT_TXE;
if (update_mode) {
CDC_UART2->CR1 |= USART_IT_TXE;
} else {
CDC_UART->CR1 |= USART_IT_TXE;
}

return cnt;
}
Expand Down Expand Up @@ -260,3 +424,28 @@ void CDC_UART_IRQn_Handler(void)
}
}
}

void CDC_UART2_IRQn_Handler(void)
{
const uint32_t sr = CDC_UART2->SR;

if (sr & USART_SR_RXNE) {
uint8_t dat = CDC_UART2->DR;
uint32_t free = circ_buf_count_free(&read_buffer);
if (free > RX_OVRF_MSG_SIZE) {
circ_buf_push(&read_buffer, dat);
} else if (RX_OVRF_MSG_SIZE == free) {
circ_buf_write(&read_buffer, (uint8_t*)RX_OVRF_MSG, RX_OVRF_MSG_SIZE);
} else {
// Drop character
}
}

if (sr & USART_SR_TXE) {
if (circ_buf_count_used(&write_buffer) > 0) {
CDC_UART2->DR = circ_buf_pop(&write_buffer);
} else {
CDC_UART2->CR1 &= ~USART_IT_TXE;
}
}
}

0 comments on commit eca8189

Please sign in to comment.