1.准备工作
下载RT-Thread源码和MM32F5375库文件:
2.移植步骤
进入到bsp目录,复制一份mm32f327x,重命名为mm32f537x:
进入mm32f537内文件Libraries下,将从官网下载的函数库对应的替换进去。
修改libraries的SConscript文件,这里直接贴在这里了:
from building import *
import rtconfig
cwd = GetCurrentDir()
src = ['MM32F537x/Source/system_mm32f537x.c']
CPPPATH = [cwd + '/CMSIS/KEIL_Core', cwd + '/MM32F537x/Include', cwd + '/MM32F537x/Source', cwd + '/MM32F537x/HAL_Lib/Inc']
src += Glob('MM32F537x/HAL_Lib/Src/*.c')
CPPDEFINES = ['USE_STDPERIPH_DRIVER']
if rtconfig.PLATFORM in ['armcc', 'armclang']:
src += ['MM32F537x/Source/KEIL_StartAsm/startup_mm32f537x_keil.s']
elif rtconfig.PLATFORM in ['iccarm']:
src += ['MM32F537x/Source/IAR_StartAsm/startup_mm32f537x_iar.s']
group = DefineGroup('Libraries', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
Return('group')
在mm32f537x下的rtconfig.py同样要改一下,CPU就配成Cortex-m33即可,是兼容的。mm32f3270是cortex-m3的,对应的都要改一下。这里添加是用于Keil,但用keil编译的时候各种报错,最后还是用scons.
接下来就是对接驱动,主要是GPIO和Usart的对接。改动不少,直接贴了
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-14 RiceChen first version
*/
#include "drv_usart.h"
enum
{
#ifdef BSP_USING_UART1
UART1_INDEX,
#endif
#ifdef BSP_USING_UART2
UART2_INDEX,
#endif
#ifdef BSP_USING_UART3
UART3_INDEX,
#endif
#ifdef BSP_USING_UART4
UART4_INDEX,
#endif
#ifdef BSP_USING_UART5
UART5_INDEX,
#endif
#ifdef BSP_USING_UART6
UART6_INDEX,
#endif
#ifdef BSP_USING_UART7
UART7_INDEX,
#endif
#ifdef BSP_USING_LPUART1
LPUART1_INDEX,
#endif
UART_INDEX_MAX,
};
static struct mm32_uart_config uart_config[] =
{
#ifdef BSP_USING_UART1
UART1_CONFIG,
#endif
#ifdef BSP_USING_UART2
// UART2_CONFIG,
#endif
#ifdef BSP_USING_UART3
UART3_CONFIG,
#endif
#ifdef BSP_USING_UART4
UART4_CONFIG,
#endif
#ifdef BSP_USING_UART5
UART5_CONFIG,
#endif
#ifdef BSP_USING_UART6
UART6_CONFIG,
#endif
#ifdef BSP_USING_UART7
UART7_CONFIG,
#endif
#ifdef BSP_USING_LPUART1
LPUART1_CONFIG,
#endif
};
#define UART_OBJ_SIZE sizeof(uart_config) / sizeof(uart_config[0])
static struct mm32_uart uart_obj[UART_OBJ_SIZE] = {0};
static rt_err_t mm32_configure(struct rt_serial_device *serial,
struct serial_configure *cfg)
{
struct mm32_uart *uart;
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
uart = rt_container_of(serial, struct mm32_uart, serial);
//uart->handle.Instance = uart->config->Instance;
uart->handle.USART_BaudRate = cfg->baud_rate;
uart->handle.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
switch (cfg->flowcontrol)
{
case RT_SERIAL_FLOWCONTROL_NONE:
uart->handle.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
break;
case RT_SERIAL_FLOWCONTROL_CTSRTS:
uart->handle.USART_HardwareFlowControl = USART_HardwareFlowControl_AutoFlowEn;
break;
default:
uart->handle.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
break;
}
switch (cfg->data_bits)
{
case DATA_BITS_8:
if (cfg->parity == PARITY_ODD || cfg->parity == PARITY_EVEN)
uart->handle.USART_WordLength = USART_WordLength_9b;
else
uart->handle.USART_WordLength = USART_WordLength_8b;
break;
case DATA_BITS_9:
uart->handle.USART_WordLength = USART_WordLength_9b;
break;
default:
uart->handle.USART_WordLength = USART_WordLength_8b;
break;
}
switch (cfg->stop_bits)
{
case STOP_BITS_1:
uart->handle.USART_StopBits = USART_StopBits_1;
break;
case STOP_BITS_2:
uart->handle.USART_StopBits = USART_StopBits_2;
break;
default:
uart->handle.USART_StopBits = USART_StopBits_1;
break;
}
switch (cfg->parity)
{
case PARITY_NONE:
uart->handle.USART_Parity = USART_Parity_No;
break;
case PARITY_ODD:
uart->handle.USART_Parity = USART_Parity_Odd;
break;
case PARITY_EVEN:
uart->handle.USART_Parity = USART_Parity_Even;
break;
default:
uart->handle.USART_Parity = USART_Parity_No;
break;
}
USART_Init(uart->config->uartx,&uart->handle) ;
return RT_EOK;
}
static rt_err_t mm32_control(struct rt_serial_device *serial,
int cmd,
void *arg)
{
struct mm32_uart *uart;
rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
RT_ASSERT(serial != RT_NULL);
uart = rt_container_of(serial, struct mm32_uart, serial);
switch (cmd)
{
case RT_DEVICE_CTRL_SET_INT:
{
USART_ITConfig(uart->config->uartx, USART_IT_RXNE, ENABLE);
NVIC_EnableIRQ(uart->config->irq_type);
break;
}
case RT_DEVICE_CTRL_CLR_INT:
{
USART_ITConfig(uart->config->uartx, USART_IT_RXNE, DISABLE);
NVIC_DisableIRQ(uart->config->irq_type);
break;
}
}
return 0;
}
static int mm32_putc(struct rt_serial_device *serial, char c)
{
struct mm32_uart *uart;
RT_ASSERT(serial != RT_NULL);
uart = rt_container_of(serial, struct mm32_uart, serial);
while (0u == (USART_FLAG_TXE & USART_GetFlagStatus(uart->config->uartx,USART_FLAG_TXE)));
USART_SendData(uart->config->uartx, (uint8_t)(c));
return 1;
}
static int mm32_getc(struct rt_serial_device *serial)
{
struct mm32_uart *uart;
int ch = -1;
RT_ASSERT(serial != RT_NULL);
uart = rt_container_of(serial, struct mm32_uart, serial);
if(USART_FLAG_RXNE & USART_GetFlagStatus(uart->config->uartx,USART_FLAG_RXNE))
{
ch = USART_ReceiveData(uart->config->uartx);
return ch;
}
return -1;
}
static rt_size_t mm32_dma_transmit(struct rt_serial_device *serial,
rt_uint8_t *buf,
rt_size_t size,
int direction)
{
return 0;
}
struct rt_uart_ops mm32_uart_ops =
{
.configure = mm32_configure,
.control = mm32_control,
.putc = mm32_putc,
.getc = mm32_getc,
// .dma_transmit = mm32_dma_transmit
};
static void uart_isr(struct rt_serial_device *serial)
{
struct mm32_uart *uart;
RT_ASSERT(serial != RT_NULL);
uart = rt_container_of(serial, struct mm32_uart, serial);
if((0u != (USART_IT_RXNE & USART_GetITStatus(uart->config->uartx,USART_IT_RXNE)))
&& (0u != (USART_IT_TXE & USART_GetITStatus(uart->config->uartx,USART_IT_TXE))))
{
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
}
}
void USART1_IRQHandler(void)
{
rt_interrupt_enter();
uart_isr(&(uart_obj[UART1_INDEX].serial));
rt_interrupt_leave();
}
static int rt_hw_uart_gpio_init(struct mm32_uart_config *cfg)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHBPeriphClockCmd(cfg->uart_rcc_clock, ENABLE);
/*
RCC_EnableAPB2Periphs(cfg->uart_rcc_clock, true);
RCC_ResetAPB2Periphs(cfg->uart_rcc_clock);
RCC_EnableAHB1Periphs(cfg->rx_rcc_clock, true);
RCC_ResetAHB1Periphs(cfg->rx_rcc_clock);
RCC_EnableAHB1Periphs(cfg->tx_rcc_clock, true);
RCC_ResetAHB1Periphs(cfg->tx_rcc_clock);
*/
GPIO_InitStruct.GPIO_Pin = cfg->rx_pin;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_FLOATING;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_Init(cfg->rx_gpiox, &GPIO_InitStruct);
GPIO_PinAFConfig(cfg->rx_gpiox, cfg->rx_pin, cfg->rx_gpio_af);
GPIO_InitStruct.GPIO_Pin = cfg->tx_pin;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_Init(cfg->tx_gpiox, &GPIO_InitStruct);
GPIO_PinAFConfig(cfg->tx_gpiox, cfg->tx_pin, cfg->tx_gpio_af);
return RT_EOK;
}
int rt_hw_uart_init(void)
{
rt_err_t result = 0;
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
for(int index = 0; index < UART_OBJ_SIZE; index++)
{
rt_hw_uart_gpio_init(&uart_config[index]);
uart_obj[index].config = &uart_config[index];
uart_obj[index].serial.ops = &mm32_uart_ops;
uart_obj[index].serial.config = config;
result = rt_hw_serial_register(&uart_obj[index].serial,
uart_obj[index].config->name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
NULL);
}
return result;
}
修改SRAM大小:
串口头文件配置:
主函数修改:
当然在移植的过程问题老多了,看移植好的就行。这里不说明。
3.编译
使用scons编译,如下所示,编译通过,完成,但是有一点就是完成怎么下载进去,官方的ISP不支持当前这个型号,我固件贴在这里,有兴趣的和有办法的可以试一下。