feat : 基于AT32,将各驱动移植整改待验证

1. 部分驱动已经整改,但未验证
2. 根据AT32整改目录结构
This commit is contained in:
linyuanbo_breo_server 2021-08-19 08:19:02 +00:00
parent 7c5f552103
commit 3ef5278322
24 changed files with 2777 additions and 41 deletions

View File

@ -20,41 +20,41 @@ if GetDepend(['RT_USING_WDT']):
if GetDepend(['RT_USING_SERIAL']):
src += ['drv_usart.c']
if GetDepend(['RT_USING_PWM']):
if GetDepend(['BSP_USING_PWM']):
src += ['drv_pwm.c']
if GetDepend(['RT_USING_HWTIMER']):
if GetDepend(['BSP_USING_HWTIMER']):
src += ['drv_hwtimer.c']
if GetDepend(['RT_USING_SPI']):
if GetDepend(['BSP_USING_SPI']):
src += ['drv_spi.c']
if GetDepend(['RT_USING_ETH', 'RT_USING_LWIP']):
if GetDepend(['BSP_USING_ETH', 'BSP_USING_LWIP']):
src += ['drv_eth.c']
if GetDepend(['RT_USING_I2C', 'RT_USING_I2C_BITOPS']):
if GetDepend('RT_USING_I2C1') or GetDepend('RT_USING_I2C2') or GetDepend('RT_USING_I2C3') or GetDepend('RT_USING_I2C4'):
if GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2') or GetDepend('BSP_USING_I2C3') or GetDepend('BSP_USING_I2C4'):
src += ['drv_soft_i2c.c']
if GetDepend(['RT_USING_ADC']):
if GetDepend(['BSP_USING_ADC']):
src += Glob('drv_adc.c')
if GetDepend('RT_USING_SRAM'):
if GetDepend('BSP_USING_SRAM'):
src += ['drv_sram.c']
if GetDepend('RT_USING_RTC'):
if GetDepend('BSP_USING_RTC'):
src += ['drv_rtc.c']
if GetDepend('RT_USING_ON_CHIP_FLASH'):
if GetDepend('BSP_USING_ON_CHIP_FLASH'):
src += ['drv_flash.c']
if GetDepend(['RT_USING_WDT']):
if GetDepend(['BSP_USING_WDT']):
src += ['drv_wdt.c']
if GetDepend(['RT_USING_CAN']):
if GetDepend(['BSP_USING_CAN']):
src += ['drv_can.c']
if GetDepend(['RT_USING_SDIO']):
if GetDepend(['BSP_USING_SDIO']):
src += ['drv_sdio.c']
CPPPATH = [cwd]

View File

@ -0,0 +1,208 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-01-15 Leo first version
*/
#include <board.h>
#include "drv_adc.h"
#if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) || defined(BSP_USING_ADC3)
#define DRV_DEBUG
#define LOG_TAG "drv.adc"
#include <drv_log.h>
struct n32_adc
{
struct rt_adc_device n32_adc_device;
ADC_Module *ADC_Handler;
char *name;
};
static struct n32_adc n32_adc_obj[] =
{
#ifdef BSP_USING_ADC1
ADC1_CONFIG,
#endif
#ifdef BSP_USING_ADC2
ADC2_CONFIG,
#endif
#ifdef BSP_USING_ADC3
ADC3_CONFIG,
#endif
};
static rt_uint32_t n32_adc_get_channel(rt_uint32_t channel)
{
rt_uint32_t n32_channel = 0;
switch (channel)
{
case 0:
n32_channel = ADC_CH_0;
break;
case 1:
n32_channel = ADC_CH_1;
break;
case 2:
n32_channel = ADC_CH_2;
break;
case 3:
n32_channel = ADC_CH_3;
break;
case 4:
n32_channel = ADC_CH_4;
break;
case 5:
n32_channel = ADC_CH_5;
break;
case 6:
n32_channel = ADC_CH_6;
break;
case 7:
n32_channel = ADC_CH_7;
break;
case 8:
n32_channel = ADC_CH_8;
break;
case 9:
n32_channel = ADC_CH_9;
break;
case 10:
n32_channel = ADC_CH_10;
break;
case 11:
n32_channel = ADC_CH_11;
break;
case 12:
n32_channel = ADC_CH_12;
break;
case 13:
n32_channel = ADC_CH_13;
break;
case 14:
n32_channel = ADC_CH_14;
break;
case 15:
n32_channel = ADC_CH_15;
break;
case 16:
n32_channel = ADC_CH_16;
break;
case 17:
n32_channel = ADC_CH_17;
break;
}
return n32_channel;
}
static rt_err_t n32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
{
ADC_Module *n32_adc_handler;
ADC_InitType ADC_InitStructure;
RT_ASSERT(device != RT_NULL);
n32_adc_handler = device->parent.user_data;
n32_msp_adc_init(n32_adc_handler);
/* ADCx configuration ------------------------------------------------------*/
ADC_InitStruct(&ADC_InitStructure);
ADC_InitStructure.WorkMode = ADC_WORKMODE_INDEPENDENT;
ADC_InitStructure.MultiChEn = DISABLE;
ADC_InitStructure.ContinueConvEn = DISABLE;
ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_NONE;
ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R;
ADC_InitStructure.ChsNumber = 1;
ADC_Init(n32_adc_handler, &ADC_InitStructure);
/* ADCx regular channels configuration */
ADC_ConfigRegularChannel(n32_adc_handler, n32_adc_get_channel(channel), 1, ADC_SAMP_TIME_28CYCLES5);
/* Enable ADCx */
ADC_Enable(n32_adc_handler, ENABLE);
// /* Enable ADCx reset calibration register */
// ADC_RstCalibration(n32_adc_handler);
// /* Check the end of ADCx reset calibration register */
// while(ADC_GetResetCalibrationStatus(n32_adc_handler));
/* Start ADCx calibration */
ADC_StartCalibration(n32_adc_handler);
/* Check the end of ADCx calibration */
while(ADC_GetCalibrationStatus(n32_adc_handler));
if (enabled)
{
/* Enable ADC1 */
ADC_Enable(n32_adc_handler, ENABLE);
}
else
{
/* Enable ADCx */
ADC_Enable(n32_adc_handler, DISABLE);
}
return RT_EOK;
}
static rt_err_t n32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
{
ADC_Module *n32_adc_handler;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(value != RT_NULL);
n32_adc_handler = device->parent.user_data;
/* Start ADCx Software Conversion */
ADC_EnableSoftwareStartConv(n32_adc_handler, ENABLE);
/* Wait for the ADC to convert */
while(ADC_GetFlagStatus(n32_adc_handler, ADC_FLAG_ENDC) == RESET);
/* get ADC value */
*value = ADC_GetDat(n32_adc_handler);
return RT_EOK;
}
static const struct rt_adc_ops at_adc_ops =
{
.enabled = n32_adc_enabled,
.convert = n32_get_adc_value,
};
static int rt_hw_adc_init(void)
{
int result = RT_EOK;
int i = 0;
for (i = 0; i < sizeof(n32_adc_obj) / sizeof(n32_adc_obj[0]); i++)
{
/* register ADC device */
if (rt_hw_adc_register(&n32_adc_obj[i].n32_adc_device,
n32_adc_obj[i].name, &at_adc_ops,
n32_adc_obj[i].ADC_Handler) == RT_EOK)
{
LOG_D("%s register success", n32_adc_obj[i].name);
}
else
{
LOG_E("%s register failed", n32_adc_obj[i].name);
result = -RT_ERROR;
}
}
return result;
}
INIT_BOARD_EXPORT(rt_hw_adc_init);
#endif /* BSP_USING_ADC */

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-07 Leo first version
*/
#ifndef __ADC_CONFIG_H__
#define __ADC_CONFIG_H__
#include <rtthread.h>
#include <drivers/adc.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) || defined(BSP_USING_ADC3)
#ifndef ADC1_CONFIG
#define ADC1_CONFIG \
{ \
.ADC_Handler = ADC1, \
.name = "adc1", \
}
#endif /* ADC1_CONFIG */
#ifndef ADC2_CONFIG
#define ADC2_CONFIG \
{ \
.ADC_Handler = ADC2, \
.name = "adc2", \
}
#endif /* ADC2_CONFIG */
#ifndef ADC3_CONFIG
#define ADC3_CONFIG \
{ \
.ADC_Handler = ADC3, \
.name = "adc3", \
}
#endif /* ADC3_CONFIG */
#endif
#ifdef __cplusplus
}
#endif
#endif /* __ADC_CONFIG_H__ */

View File

@ -62,3 +62,4 @@ void rt_hw_us_delay(rt_uint32_t us)
}
}
}

View File

@ -0,0 +1,210 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-09 shelton the first version
*/
#include <board.h>
#include <rtthread.h>
#ifdef BSP_USING_ON_CHIP_FLASH
#include "drv_flash.h"
#if defined(PKG_USING_FAL)
#include "fal.h"
#endif
//#define DRV_DEBUG
#define LOG_TAG "drv.flash"
#include <drv_log.h>
/**
* @brief Gets the page of a given address
* @param addr: address of the flash memory
* @retval The page of a given address
*/
static rt_uint32_t get_page(uint32_t addr)
{
rt_uint32_t page = 0;
page = RT_ALIGN_DOWN(addr, FLASH_PAGE_SIZE);
return page;
}
/**
* Read data from flash.
* @note This operation's units is word.
*
* @param addr flash address
* @param buf buffer to store read data
* @param size read bytes size
*
* @return result
*/
int n32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
{
size_t i;
if ((addr + size) > N32_FLASH_END_ADDRESS)
{
LOG_E("read outrange flash size! addr is (0x%p)", (void *)(addr + size));
return -RT_EINVAL;
}
for (i = 0; i < size; i++, buf++, addr++)
{
*buf = *(rt_uint8_t *) addr;
}
return size;
}
/**
* Write data to flash.
* @note This operation's units is word.
* @note This operation must after erase. @see flash_erase.
*
* @param addr flash address
* @param buf the write data buffer
* @param size write bytes size
*
* @return result
*/
int n32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
{
rt_err_t result = RT_EOK;
rt_uint32_t end_addr = addr + size;
if (addr % 4 != 0)
{
LOG_E("write addr must be 4-byte alignment");
return -RT_EINVAL;
}
if ((end_addr) > N32_FLASH_END_ADDRESS)
{
LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size));
return -RT_EINVAL;
}
FLASH_Unlock();
while (addr < end_addr)
{
if (FLASH_ProgramWord(addr, *((rt_uint32_t *)buf)) == FLASH_COMPL)
{
if (*(rt_uint32_t *)addr != *(rt_uint32_t *)buf)
{
result = -RT_ERROR;
break;
}
addr += 4;
buf += 4;
}
else
{
result = -RT_ERROR;
break;
}
}
FLASH_Lock();
if (result != RT_EOK)
{
return result;
}
return size;
}
/**
* Erase data on flash .
* @note This operation is irreversible.
* @note This operation's units is different which on many chips.
*
* @param addr flash address
* @param size erase bytes size
*
* @return result
*/
int n32_flash_erase(rt_uint32_t addr, size_t size)
{
rt_err_t result = RT_EOK;
rt_uint32_t end_addr = addr + size;
rt_uint32_t page_addr = 0;
FLASH_Unlock();
if ((end_addr) > N32_FLASH_END_ADDRESS)
{
LOG_E("erase outrange flash size! addr is (0x%p)", (void *)(addr + size));
return -RT_EINVAL;
}
while(addr < end_addr)
{
page_addr = get_page(addr);
if(FLASH_EraseOnePage(page_addr) != FLASH_COMPL)
{
result = -RT_ERROR;
goto __exit;
}
addr += FLASH_PAGE_SIZE;
}
FLASH_Lock();
__exit:
if(result != RT_EOK)
{
return result;
}
return size;
}
#if defined(PKG_USING_FAL)
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size);
static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size);
static int fal_flash_erase(long offset, size_t size);
const struct fal_flash_dev n32_onchip_flash =
{
"onchip_flash",
N32_FLASH_START_ADRESS,
N32_FLASH_SIZE,
FLASH_PAGE_SIZE,
{
NULL,
fal_flash_read,
fal_flash_write,
fal_flash_erase
}
};
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size)
{
return n32_flash_read(n32_onchip_flash.addr + offset, buf, size);
}
static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size)
{
return n32_flash_write(n32_onchip_flash.addr + offset, buf, size);
}
static int fal_flash_erase(long offset, size_t size)
{
return n32_flash_erase(n32_onchip_flash.addr + offset, size);
}
#endif
#endif /* BSP_USING_ON_CHIP_FLASH */

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-09 shelton the first version
*/
#ifndef __DRV_FLASH_H__
#define __DRV_FLASH_H__
#include <rtthread.h>
#include "rtdevice.h"
#include <rthw.h>
#ifdef __cplusplus
extern "C" {
#endif
int n32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size);
int n32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size);
int n32_flash_erase(rt_uint32_t addr, size_t size);
#ifdef __cplusplus
}
#endif
#endif /* __DRV_FLASH_H__ */

View File

@ -0,0 +1,412 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-03-16 Leo first version
*/
#include <board.h>
#include "drv_hwtimer.h"
#define DRV_DEBUG
#define LOG_TAG "drv.hwtimer"
#include <drv_log.h>
#ifdef BSP_USING_HWTIMER
enum
{
#ifdef BSP_USING_HWTMR1
TMR1_INDEX,
#endif
#ifdef BSP_USING_HWTMR2
TMR2_INDEX,
#endif
#ifdef BSP_USING_HWTMR3
TMR3_INDEX,
#endif
#ifdef BSP_USING_HWTMR4
TMR4_INDEX,
#endif
#ifdef BSP_USING_HWTMR5
TMR5_INDEX,
#endif
#ifdef BSP_USING_HWTMR6
TMR6_INDEX,
#endif
#ifdef BSP_USING_HWTMR7
TMR7_INDEX,
#endif
#ifdef BSP_USING_HW_TMR8
TMR8_INDEX,
#endif
#ifdef BSP_USING_HWTMR9
TMR9_INDEX,
#endif
#ifdef BSP_USING_HWTMR10
TMR10_INDEX,
#endif
#ifdef BSP_USING_HWTMR11
TMR11_INDEX,
#endif
#ifdef BSP_USING_HWTMR12
TMR12_INDEX,
#endif
#ifdef BSP_USING_HWTMR13
TMR13_INDEX,
#endif
#ifdef BSP_USING_HWTMR14
TMR14_INDEX,
#endif
#ifdef BSP_USING_HWTMR15
TMR15_INDEX,
#endif
};
struct at32_hwtimer
{
rt_hwtimer_t time_device;
TMR_Type* tim_handle;
IRQn_Type tim_irqn;
char *name;
};
static struct at32_hwtimer at32_hwtimer_obj[] =
{
#ifdef BSP_USING_HWTMR1
TMR1_CONFIG,
#endif
#ifdef BSP_USING_HWTMR2
TMR2_CONFIG,
#endif
#ifdef BSP_USING_HWTMR3
TMR3_CONFIG,
#endif
#ifdef BSP_USING_HWTMR4
TMR4_CONFIG,
#endif
#ifdef BSP_USING_HWTMR5
TMR5_CONFIG,
#endif
#ifdef BSP_USING_HWTMR6
TMR6_CONFIG,
#endif
#ifdef BSP_USING_HWTMR7
TMR7_CONFIG,
#endif
#ifdef BSP_USING_HWTMR8
TMR8_CONFIG,
#endif
#ifdef BSP_USING_HWTMR9
TMR9_CONFIG,
#endif
#ifdef BSP_USING_HWTMR10
TMR10_CONFIG,
#endif
#ifdef BSP_USING_HWTMR11
TMR11_CONFIG,
#endif
#ifdef BSP_USING_HWTMR12
TMR12_CONFIG,
#endif
#ifdef BSP_USING_HWTMR13
TMR13_CONFIG,
#endif
#ifdef BSP_USING_HWTMR14
TMR14_CONFIG,
#endif
#ifdef BSP_USING_HWTMR15
TMR15_CONFIG,
#endif
};
static void at32_timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
{
RCC_ClockType RCC_ClockStruct;
TMR_TimerBaseInitType TMR_TMReBaseStructure;
NVIC_InitType NVIC_InitStructure;
uint32_t prescaler_value = 0;
TMR_Type *tim = RT_NULL;
struct at32_hwtimer *tim_device = RT_NULL;
RT_ASSERT(timer != RT_NULL);
if (state)
{
tim = (TMR_Type *)timer->parent.user_data;
tim_device = (struct at32_hwtimer *)timer;
/* timer clock enable */
at32_msp_hwtmr_init(tim);
/* timer init */
RCC_GetClocksFreq(&RCC_ClockStruct);
/* Set timer clock is 1Mhz */
prescaler_value = (uint32_t)(RCC_ClockStruct.SYSCLK_Freq / 10000) - 1;
TMR_TMReBaseStructure.TMR_Period = 10000 - 1;
TMR_TMReBaseStructure.TMR_DIV = prescaler_value;
TMR_TMReBaseStructure.TMR_ClockDivision = TMR_CKD_DIV1;
TMR_TMReBaseStructure.TMR_RepetitionCounter = 0;
if (timer->info->cntmode == HWTIMER_CNTMODE_UP)
{
TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_Up;
}
else
{
TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_Down;
}
TMR_TimeBaseInit(tim, &TMR_TMReBaseStructure);
/* Enable the TMRx global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = tim_device->tim_irqn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TMR_INTConfig(tim, TMR_INT_Overflow ,ENABLE);
TMR_ClearITPendingBit(tim, TMR_INT_Overflow);
LOG_D("%s init success", tim_device->name);
}
}
static rt_err_t at32_timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
{
rt_err_t result = RT_EOK;
TMR_Type *tim = RT_NULL;
RT_ASSERT(timer != RT_NULL);
tim = (TMR_Type *)timer->parent.user_data;
/* set tim cnt */
TMR_SetCounter(tim, 0);
/* set tim arr */
TMR_SetAutoreload(tim, t - 1);
if (opmode == HWTIMER_MODE_ONESHOT)
{
/* set timer to single mode */
TMR_SelectOnePulseMode(tim, TMR_OPMode_Once);
}
else
{
TMR_SelectOnePulseMode(tim, TMR_OPMode_Repetitive);
}
/* start timer */
TMR_Cmd(tim, ENABLE);
return result;
}
static void at32_timer_stop(rt_hwtimer_t *timer)
{
TMR_Type *tim = RT_NULL;
RT_ASSERT(timer != RT_NULL);
tim = (TMR_Type *)timer->parent.user_data;
/* stop timer */
TMR_Cmd(tim, ENABLE);
/* set tim cnt */
TMR_SetCounter(tim, 0);
}
static rt_uint32_t at32_timer_counter_get(rt_hwtimer_t *timer)
{
TMR_Type *tim = RT_NULL;
RT_ASSERT(timer != RT_NULL);
tim = (TMR_Type *)timer->parent.user_data;
return tim->CNT;
}
static rt_err_t at32_timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
{
RCC_ClockType RCC_ClockStruct;
TMR_Type *tim = RT_NULL;
rt_err_t result = RT_EOK;
RT_ASSERT(timer != RT_NULL);
RT_ASSERT(arg != RT_NULL);
tim = (TMR_Type *)timer->parent.user_data;
switch(cmd)
{
case HWTIMER_CTRL_FREQ_SET:
{
rt_uint32_t freq;
rt_uint16_t val;
/* set timer frequence */
freq = *((rt_uint32_t *)arg);
/* time init */
RCC_GetClocksFreq(&RCC_ClockStruct);
val = RCC_ClockStruct.SYSCLK_Freq / freq;
TMR_DIVConfig(tim, val - 1, TMR_DIVReloadMode_Immediate);
}
break;
default:
{
result = -RT_ENOSYS;
}
break;
}
return result;
}
static const struct rt_hwtimer_info _info = TMR_DEV_INFO_CONFIG;
static const struct rt_hwtimer_ops _ops =
{
.init = at32_timer_init,
.start = at32_timer_start,
.stop = at32_timer_stop,
.count_get = at32_timer_counter_get,
.control = at32_timer_ctrl,
};
#ifdef BSP_USING_HWTMR2
void TMR2_GLOBAL_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
if(TMR_GetINTStatus(TMR2, TMR_INT_Overflow) == SET)
{
rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR2_INDEX].time_device);
TMR_ClearITPendingBit(TMR2, TMR_INT_Overflow);
}
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_HWTMR3
void TMR3_GLOBAL_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
if(TMR_GetINTStatus(TMR3, TMR_INT_Overflow) == SET)
{
rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR3_INDEX].time_device);
TMR_ClearITPendingBit(TMR3, TMR_INT_Overflow);
}
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_HWTMR4
void TMR4_GLOBAL_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
if(TMR_GetINTStatus(TMR4, TMR_INT_Overflow) == SET)
{
rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR4_INDEX].time_device);
TMR_ClearITPendingBit(TMR4, TMR_INT_Overflow);
}
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_HWTMR5
void TMR5_GLOBAL_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
if(TMR_GetINTStatus(TMR5, TMR_INT_Overflow) == SET)
{
rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR5_INDEX].time_device);
TMR_ClearITPendingBit(TMR5, TMR_INT_Overflow);
}
/* leave interrupt */
rt_interrupt_leave();
}
#endif
static int rt_hw_hwtimer_init(void)
{
int i = 0;
int result = RT_EOK;
for (i = 0; i < sizeof(at32_hwtimer_obj) / sizeof(at32_hwtimer_obj[0]); i++)
{
at32_hwtimer_obj[i].time_device.info = &_info;
at32_hwtimer_obj[i].time_device.ops = &_ops;
if (rt_device_hwtimer_register(&at32_hwtimer_obj[i].time_device, at32_hwtimer_obj[i].name, at32_hwtimer_obj[i].tim_handle) == RT_EOK)
{
LOG_D("%s register success", at32_hwtimer_obj[i].name);
}
else
{
LOG_E("%s register failed", at32_hwtimer_obj[i].name);
result = -RT_ERROR;
}
}
return result;
}
INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
#endif /* BSP_USING_HWTIMER */

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-03-16 Leo first version
*/
#ifndef __TMR_CONFIG_H__
#define __TMR_CONFIG_H__
#include <rtthread.h>
#include <drivers/hwtimer.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef TMR_DEV_INFO_CONFIG
#define TMR_DEV_INFO_CONFIG \
{ \
.maxfreq = 1000000, \
.minfreq = 4000, \
.maxcnt = 0xFFFF, \
.cntmode = HWTIMER_CNTMODE_UP, \
}
#endif /* TIM_DEV_INFO_CONFIG */
#ifdef BSP_USING_HWTMR2
#ifndef TMR2_CONFIG
#define TMR2_CONFIG \
{ \
.tim_handle = TMR2, \
.tim_irqn = TMR2_GLOBAL_IRQn, \
.name = "timer2", \
}
#endif /* TMR2_CONFIG */
#endif /* BSP_USING_HWTMR2 */
#ifdef BSP_USING_HWTMR3
#ifndef TMR3_CONFIG
#define TMR3_CONFIG \
{ \
.tim_handle = TMR3, \
.tim_irqn = TMR3_GLOBAL_IRQn, \
.name = "timer3", \
}
#endif /* TMR3_CONFIG */
#endif /* BSP_USING_HWTMR3 */
#ifdef BSP_USING_HWTMR4
#ifndef TMR4_CONFIG
#define TMR4_CONFIG \
{ \
.tim_handle = TMR4, \
.tim_irqn = TMR4_GLOBAL_IRQn, \
.name = "timer4", \
}
#endif /* TMR4_CONFIG */
#endif /* BSP_USING_HWTMR4 */
#ifdef BSP_USING_HWTMR5
#ifndef TMR5_CONFIG
#define TMR5_CONFIG \
{ \
.tim_handle = TMR5, \
.tim_irqn = TMR5_GLOBAL_IRQn, \
.name = "timer5", \
}
#endif /* TMR5_CONFIG */
#endif /* BSP_USING_HWTMR5 */
#ifdef __cplusplus
}
#endif
#endif /* __TMR_CONFIG_H__ */

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-01-09 shelton first version
*/
/*
* NOTE: DO NOT include this file on the header file.
*/
#ifndef LOG_TAG
#define DBG_TAG "drv"
#else
#define DBG_TAG LOG_TAG
#endif /* LOG_TAG */
#ifdef DRV_DEBUG
#define DBG_LVL DBG_LOG
#else
#define DBG_LVL DBG_INFO
#endif /* DRV_DEBUG */
#include <rtdbg.h>

View File

@ -0,0 +1,291 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-1-13 Leo first version
*/
#include <board.h>
#include "drv_pwm.h"
#ifdef RT_USING_PWM
#if !defined(BSP_USING_TIM1_CH1) && !defined(BSP_USING_TIM1_CH2) && \
!defined(BSP_USING_TIM1_CH3) && !defined(BSP_USING_TIM1_CH4) && \
!defined(BSP_USING_TIM2_CH1) && !defined(BSP_USING_TIM2_CH2) && \
!defined(BSP_USING_TIM2_CH3) && !defined(BSP_USING_TIM2_CH4) && \
!defined(BSP_USING_TIM3_CH1) && !defined(BSP_USING_TIM3_CH2) && \
!defined(BSP_USING_TIM3_CH3) && !defined(BSP_USING_TIM3_CH4)
#error "Please define at least one BSP_USING_TIMx_CHx"
#endif
#endif /* RT_USING_PWM */
#define DRV_DEBUG
#define LOG_TAG "drv.pwm"
#include <drv_log.h>
#define MAX_PERIOD 65535
struct rt_device_pwm pwm_device;
struct at32_pwm
{
struct rt_device_pwm pwm_device;
TMR_Type* tim_handle;
rt_uint8_t channel;
char *name;
};
static struct at32_pwm at32_pwm_obj[] =
{
#ifdef BSP_USING_TIM1_CH1
PWM1_CONFIG,
#endif
#ifdef BSP_USING_TIM1_CH2
PWM2_CONFIG,
#endif
#ifdef BSP_USING_TIM1_CH3
PWM3_CONFIG,
#endif
#ifdef BSP_USING_TIM1_CH4
PWM4_CONFIG,
#endif
#ifdef BSP_USING_TIM2_CH1
PWM5_CONFIG,
#endif
#ifdef BSP_USING_TIM2_CH2
PWM6_CONFIG,
#endif
#ifdef BSP_USING_TIM2_CH3
PWM7_CONFIG,
#endif
#ifdef BSP_USING_TIM2_CH4
PWM8_CONFIG,
#endif
#ifdef BSP_USING_TIM3_CH1
PWM9_CONFIG,
#endif
#ifdef BSP_USING_TIM3_CH2
PWM10_CONFIG,
#endif
#ifdef BSP_USING_TIM3_CH3
PWM11_CONFIG,
#endif
#ifdef BSP_USING_TIM3_CH4
PWM12_CONFIG,
#endif
};
static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
static struct rt_pwm_ops drv_ops =
{
drv_pwm_control
};
static rt_err_t drv_pwm_enable(TMR_Type* TIMx, struct rt_pwm_configuration *configuration, rt_bool_t enable)
{
/* Get the value of channel */
rt_uint32_t channel = configuration->channel;
if (!enable)
{
if(channel == 1)
{
TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable);
}
else if(channel == 2)
{
TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Disable);
}
else if(channel == 3)
{
TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Disable);
}
else if(channel == 4)
{
TIM_CCxCmd(TIMx, TIM_Channel_4, TIM_CCx_Disable);
}
}
else
{
if(channel == 1)
{
TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable);
}
else if(channel == 2)
{
TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable);
}
else if(channel == 3)
{
TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable);
}
else if(channel == 4)
{
TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable);
}
}
/* TIMx enable counter */
TIM_Cmd(TIMx, ENABLE);
return RT_EOK;
}
static rt_err_t drv_pwm_get(TMR_Type* TIMx, struct rt_pwm_configuration *configuration)
{
RCC_ClockType RCC_Clockstruct;
rt_uint32_t ar, div, cc1, cc2, cc3, cc4;
rt_uint32_t channel = configuration->channel;
rt_uint64_t tim_clock;
ar = TIMx->AR;
div = TIMx->DIV;
cc1 = TIMx->CC1;
cc2 = TIMx->CC2;
cc3 = TIMx->CC3;
cc4 = TIMx->CC4;
RCC_GetClocksFreq(&RCC_Clockstruct);
tim_clock = RCC_Clockstruct.APB2CLK_Freq;
/* Convert nanosecond to frequency and duty cycle. */
tim_clock /= 1000000UL;
configuration->period = (ar + 1) * (div + 1) * 1000UL / tim_clock;
if(channel == 1)
configuration->pulse = (cc1 + 1) * (div + 1) * 1000UL / tim_clock;
if(channel == 2)
configuration->pulse = (cc2 + 1) * (div+ 1) * 1000UL / tim_clock;
if(channel == 3)
configuration->pulse = (cc3 + 1) * (div + 1) * 1000UL / tim_clock;
if(channel == 4)
configuration->pulse = (cc4 + 1) * (div + 1) * 1000UL / tim_clock;
return RT_EOK;
}
static rt_err_t drv_pwm_set(TMR_Type* TIMx, struct rt_pwm_configuration *configuration)
{
TIM_TimerBaseInitType TIM_TIMeBaseStructure;
TIM_OCInitType TIM_OCInitStructure;
rt_uint32_t period, pulse;
rt_uint64_t psc;
/* Get the channel number */
rt_uint32_t channel = configuration->channel;
/* Init timer pin and enable clock */
at32_msp_tmr_init(TIMx);
/* Convert nanosecond to frequency and duty cycle. */
period = (unsigned long long)configuration->period ;
psc = period / MAX_PERIOD + 1;
period = period / psc;
/* TIMe base configuration */
TIM_TimeBaseStructInit(&TIM_TIMeBaseStructure);
TIM_TIMeBaseStructure.TIM_Period = period;
TIM_TIMeBaseStructure.TIM_DIV = psc - 1;
TIM_TIMeBaseStructure.TIM_ClockDivision = 0;
TIM_TIMeBaseStructure.TIM_CounterMode = TIM_CounterDIR_Up;
TIM_TimeBaseInit(TIMx, &TIM_TIMeBaseStructure);
pulse = (unsigned long long)configuration->pulse;
/* PWM1 Mode configuration: Channel1 */
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = pulse;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
if(channel == 1)
{
TIM_OC1Init(TIMx, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Enable);
}
else if(channel == 2)
{
TIM_OC2Init(TIMx, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIMx, TIM_OCPreload_Enable);
}
else if(channel == 3)
{
TIM_OC3Init(TIMx, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIMx, TIM_OCPreload_Enable);
}
else if(channel == 4)
{
TIM_OC4Init(TIMx, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIMx, TIM_OCPreload_Enable);
}
TIM_ARPreloadConfig(TIMx, ENABLE);
#if defined (SOC_SERIES_AT32F415)
if(TIMx == TIM1)
#else
if(TIMx == TIM1 || TIMx == TIM8)
#endif
{
TIM_CtrlPWMOutputs(TIMx,ENABLE);
}
return RT_EOK;
}
static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
{
struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
TIM_Type *TIMx = (TIM_Type *)device->parent.user_data;
switch (cmd)
{
case PWM_CMD_ENABLE:
return drv_pwm_enable(TIMx, configuration, RT_TRUE);
case PWM_CMD_DISABLE:
return drv_pwm_enable(TIMx, configuration, RT_FALSE);
case PWM_CMD_SET:
return drv_pwm_set(TIMx, configuration);
case PWM_CMD_GET:
return drv_pwm_get(TIMx, configuration);
default:
return RT_EINVAL;
}
}
static int rt_hw_pwm_init(void)
{
int i = 0;
int result = RT_EOK;
for(i = 0; i < sizeof(at32_pwm_obj) / sizeof(at32_pwm_obj[0]); i++)
{
if(rt_device_pwm_register(&at32_pwm_obj[i].pwm_device, at32_pwm_obj[i].name, &drv_ops, at32_pwm_obj[i].tim_handle) == RT_EOK)
{
LOG_D("%s register success", at32_pwm_obj[i].name);
}
else
{
LOG_D("%s register failed", at32_pwm_obj[i].name);
result = -RT_ERROR;
}
}
return result;
}
INIT_BOARD_EXPORT(rt_hw_pwm_init);

View File

@ -0,0 +1,157 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-1-13 Leo first version
*/
#ifndef __PWM_CONFIG_H__
#define __PWM_CONFIG_H__
#include <rtthread.h>
#include <drivers/rt_drv_pwm.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_TMR1_CH1
#ifndef PWM1_CONFIG
#define PWM1_CONFIG \
{ \
.tim_handle = TMR1, \
.name = "tmr1pwm1", \
.channel = 1 \
}
#endif /* PWM1_CONFIG */
#endif /* BSP_USING_TMR1_CH1 */
#ifdef BSP_USING_TMR1_CH2
#ifndef PWM2_CONFIG
#define PWM2_CONFIG \
{ \
.tim_handle = TMR1, \
.name = "tmr1pwm2", \
.channel = 2 \
}
#endif /* PWM2_CONFIG */
#endif /* BSP_USING_TMR1_CH2 */
#ifdef BSP_USING_TMR1_CH3
#ifndef PWM3_CONFIG
#define PWM3_CONFIG \
{ \
.tim_handle = TMR1, \
.name = "tmr1pwm3", \
.channel = 3 \
}
#endif /* PWM3_CONFIG */
#endif /* BSP_USING_TMR1_CH3 */
#ifdef BSP_USING_TMR1_CH4
#ifndef PWM4_CONFIG
#define PWM4_CONFIG \
{ \
.tim_handle = TMR1, \
.name = "tmr1pwm4", \
.channel = 4 \
}
#endif /* PWM4_CONFIG */
#endif /* BSP_USING_TMR1_CH4 */
#ifdef BSP_USING_TMR2_CH1
#ifndef PWM5_CONFIG
#define PWM5_CONFIG \
{ \
.tim_handle = TMR2, \
.name = "tmr2pwm1", \
.channel = 1 \
}
#endif /* PWM5_CONFIG */
#endif /* BSP_USING_TMR2_CH1 */
#ifdef BSP_USING_TMR2_CH2
#ifndef PWM6_CONFIG
#define PWM6_CONFIG \
{ \
.tim_handle = TMR2, \
.name = "tmr2pwm2", \
.channel = 2 \
}
#endif /* PWM6_CONFIG */
#endif /* BSP_USING_TMR2_CH2 */
#ifdef BSP_USING_TMR2_CH3
#ifndef PWM7_CONFIG
#define PWM7_CONFIG \
{ \
.tim_handle = TMR2, \
.name = "tmr2pwm3", \
.channel = 3 \
}
#endif /* PWM7_CONFIG */
#endif /* BSP_USING_TMR2_CH3 */
#ifdef BSP_USING_TMR2_CH4
#ifndef PWM8_CONFIG
#define PWM8_CONFIG \
{ \
.tim_handle = TMR2, \
.name = "tmr2pwm4", \
.channel = 4 \
}
#endif /* PWM8_CONFIG */
#endif /* BSP_USING_TMR2_CH4 */
#ifdef BSP_USING_TMR3_CH1
#ifndef PWM9_CONFIG
#define PWM9_CONFIG \
{ \
.tim_handle = TMR3, \
.name = "tmr3pwm1", \
.channel = 1 \
}
#endif /* PWM9_CONFIG */
#endif /* BSP_USING_TMR3_CH1 */
#ifdef BSP_USING_TMR3_CH2
#ifndef PWM10_CONFIG
#define PWM10_CONFIG \
{ \
.tim_handle = TMR3, \
.name = "tmr3pwm2", \
.channel = 2 \
}
#endif /* PWM10_CONFIG */
#endif /* BSP_USING_TMR3_CH2 */
#ifdef BSP_USING_TMR3_CH3
#ifndef PWM11_CONFIG
#define PWM11_CONFIG \
{ \
.tim_handle = TMR3, \
.name = "tmr3pwm3", \
.channel = 3 \
}
#endif /* PWM11_CONFIG */
#endif /* BSP_USING_TMR3_CH3 */
#ifdef BSP_USING_TMR3_CH4
#ifndef PWM12_CONFIG
#define PWM12_CONFIG \
{ \
.tim_handle = TMR3, \
.name = "tmr3pwm4", \
.channel = 4 \
}
#endif /* PWM12_CONFIG */
#endif /* BSP_USING_TMR3_CH4 */
#ifdef __cplusplus
}
#endif
#endif /* __PWM_CONFIG_H__ */

View File

@ -0,0 +1,220 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-01-09 shelton first version
*/
#include <board.h>
#include "drv_soft_i2c.h"
#ifdef RT_USING_I2C
#define LOG_TAG "drv.i2c"
#include <drv_log.h>
#if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && !defined(BSP_USING_I2C4)
#error "Please define at least one BSP_USING_I2Cx"
/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */
#endif
static const struct n32_soft_i2c_config soft_i2c_config[] =
{
#ifdef BSP_USING_I2C1
I2C1_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C2
I2C2_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C3
I2C3_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C4
I2C4_BUS_CONFIG,
#endif
};
static struct n32_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])];
/**
* This function initializes the i2c pin.
*
* @param Stm32 i2c dirver class.
*/
static void n32_i2c_gpio_init(struct n32_i2c *i2c)
{
struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)i2c->ops.data;
rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD);
rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD);
rt_pin_write(cfg->scl, PIN_HIGH);
rt_pin_write(cfg->sda, PIN_HIGH);
}
/**
* This function sets the sda pin.
*
* @param Stm32 config class.
* @param The sda pin state.
*/
static void n32_set_sda(void *data, rt_int32_t state)
{
struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data;
if (state)
{
rt_pin_write(cfg->sda, PIN_HIGH);
}
else
{
rt_pin_write(cfg->sda, PIN_LOW);
}
}
/**
* This function sets the scl pin.
*
* @param Stm32 config class.
* @param The scl pin state.
*/
static void n32_set_scl(void *data, rt_int32_t state)
{
struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data;
if (state)
{
rt_pin_write(cfg->scl, PIN_HIGH);
}
else
{
rt_pin_write(cfg->scl, PIN_LOW);
}
}
/**
* This function gets the sda pin state.
*
* @param The sda pin state.
*/
static rt_int32_t n32_get_sda(void *data)
{
struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data;
return rt_pin_read(cfg->sda);
}
/**
* This function gets the scl pin state.
*
* @param The scl pin state.
*/
static rt_int32_t n32_get_scl(void *data)
{
struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data;
return rt_pin_read(cfg->scl);
}
/**
* The time delay function.
*
* @param microseconds.
*/
static void n32_udelay(rt_uint32_t us)
{
rt_uint32_t ticks;
rt_uint32_t told, tnow, tcnt = 0;
rt_uint32_t reload = SysTick->LOAD;
ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
told = SysTick->VAL;
while (1)
{
tnow = SysTick->VAL;
if (tnow != told)
{
if (tnow < told)
{
tcnt += told - tnow;
}
else
{
tcnt += reload - tnow + told;
}
told = tnow;
if (tcnt >= ticks)
{
break;
}
}
}
}
static const struct rt_i2c_bit_ops n32_bit_ops_default =
{
.data = RT_NULL,
.set_sda = n32_set_sda,
.set_scl = n32_set_scl,
.get_sda = n32_get_sda,
.get_scl = n32_get_scl,
.udelay = n32_udelay,
.delay_us = 1,
.timeout = 100
};
/**
* if i2c is locked, this function will unlock it
*
* @param at32 config class
*
* @return RT_EOK indicates successful unlock.
*/
static rt_err_t n32_i2c_bus_unlock(const struct n32_soft_i2c_config *cfg)
{
rt_int32_t i = 0;
if (PIN_LOW == rt_pin_read(cfg->sda))
{
while (i++ < 9)
{
rt_pin_write(cfg->scl, PIN_HIGH);
n32_udelay(100);
rt_pin_write(cfg->scl, PIN_LOW);
n32_udelay(100);
}
}
if (PIN_LOW == rt_pin_read(cfg->sda))
{
return -RT_ERROR;
}
return RT_EOK;
}
/* I2C initialization function */
int rt_hw_i2c_init(void)
{
rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct n32_i2c);
rt_err_t result;
for (int i = 0; i < obj_num; i++)
{
i2c_obj[i].ops = n32_bit_ops_default;
i2c_obj[i].ops.data = (void*)&soft_i2c_config[i];
i2c_obj[i].i2c_bus.priv = &i2c_obj[i].ops;
n32_i2c_gpio_init(&i2c_obj[i]);
result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c_bus, soft_i2c_config[i].bus_name);
RT_ASSERT(result == RT_EOK);
n32_i2c_bus_unlock(&soft_i2c_config[i]);
LOG_D("software simulation %s init done, pin scl: %d, pin sda %d",
soft_i2c_config[i].bus_name,
soft_i2c_config[i].scl,
soft_i2c_config[i].sda);
}
return RT_EOK;
}
INIT_BOARD_EXPORT(rt_hw_i2c_init);
#endif /* RT_USING_I2C */

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-01-09 shelton first version
*/
#ifndef __DRV_I2C__
#define __DRV_I2C__
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
/* at32 config class */
struct n32_soft_i2c_config
{
rt_uint8_t scl;
rt_uint8_t sda;
const char *bus_name;
};
/* at32 i2c dirver class */
struct n32_i2c
{
struct rt_i2c_bit_ops ops;
struct rt_i2c_bus_device i2c_bus;
};
#ifdef BSP_USING_I2C1
#define I2C1_BUS_CONFIG \
{ \
.scl = BSP_I2C1_SCL_PIN, \
.sda = BSP_I2C1_SDA_PIN, \
.bus_name = "i2c1", \
}
#endif
#ifdef BSP_USING_I2C2
#define I2C2_BUS_CONFIG \
{ \
.scl = BSP_I2C2_SCL_PIN, \
.sda = BSP_I2C2_SDA_PIN, \
.bus_name = "i2c2", \
}
#endif
#ifdef BSP_USING_I2C3
#define I2C3_BUS_CONFIG \
{ \
.scl = BSP_I2C3_SCL_PIN, \
.sda = BSP_I2C3_SDA_PIN, \
.bus_name = "i2c3", \
}
#endif
#ifdef BSP_USING_I2C4
#define I2C4_BUS_CONFIG \
{ \
.scl = BSP_I2C4_SCL_PIN, \
.sda = BSP_I2C4_SDA_PIN, \
.bus_name = "i2c4", \
}
#endif
int rt_hw_i2c_init(void);
#endif

View File

@ -0,0 +1,350 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-01-09 shelton first version
*/
#include <board.h>
#include "drv_spi.h"
#ifdef RT_USING_SPI
#if !defined(BSP_USING_SPI1) && !defined(BSP_USING_SPI2) && \
!defined(BSP_USING_SPI3) && !defined(BSP_USING_SPI4)
#error "Please define at least one SPIx"
#endif
//#define DEBUG
#define ARR_LEN(__N) (sizeof(__N) / sizeof(__N[0]))
#ifdef DEBUG
#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__)
#else
#define DEBUG_PRINTF(...)
#endif
/* private rt-thread spi ops function */
static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration);
static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message);
static struct rt_spi_ops n32_spi_ops =
{
configure,
xfer
};
/**
* Attach the spi device to SPI bus, this function must be used after initialization.
*/
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_Module *cs_gpiox, uint16_t cs_gpio_pin)
{
RT_ASSERT(bus_name != RT_NULL);
RT_ASSERT(device_name != RT_NULL);
rt_err_t result;
struct rt_spi_device *spi_device;
struct n32_spi_cs *cs_pin;
/* initialize the cs pin && select the slave*/
GPIO_InitType GPIO_InitStruct;
GPIO_InitStruct.Pin = cs_gpio_pin;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitPeripheral(cs_gpiox, &GPIO_InitStruct);
GPIO_SetBits(cs_gpiox, cs_gpio_pin);
/* attach the device to spi bus*/
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
RT_ASSERT(spi_device != RT_NULL);
cs_pin = (struct n32_spi_cs *)rt_malloc(sizeof(struct n32_spi_cs));
RT_ASSERT(cs_pin != RT_NULL);
cs_pin->GPIOx = cs_gpiox;
cs_pin->GPIO_Pin = cs_gpio_pin;
result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
if (result != RT_EOK)
{
DEBUG_PRINTF("%s attach to %s faild, %d\n", device_name, bus_name, result);
}
RT_ASSERT(result == RT_EOK);
DEBUG_PRINTF("%s attach to %s done", device_name, bus_name);
return result;
}
static rt_err_t configure(struct rt_spi_device* device,
struct rt_spi_configuration* configuration)
{
struct rt_spi_bus * spi_bus = (struct rt_spi_bus *)device->bus;
struct n32_spi *spi_instance = (struct n32_spi *)spi_bus->parent.user_data;
SPI_InitType SPI_InitStruct;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL);
n32_msp_spi_init(spi_instance->config->spix);
/* data_width */
if(configuration->data_width <= 8)
{
SPI_InitStruct.DataLen = SPI_DATA_SIZE_8BITS;
}
else if(configuration->data_width <= 16)
{
SPI_InitStruct.DataLen = SPI_DATA_SIZE_16BITS;
}
else
{
return RT_EIO;
}
/* baudrate */
{
uint32_t spi_apb_clock;
uint32_t max_hz;
RCC_ClocksType RCC_Clocks;
max_hz = configuration->max_hz;
RCC_GetClocksFreqValue(&RCC_Clocks);
DEBUG_PRINTF("sys freq: %d\n", RCC_Clocks.SysclkFreq);
DEBUG_PRINTF("max freq: %d\n", max_hz);
if (spi_instance->config->spix == SPI1)
{
spi_apb_clock = RCC_Clocks.Pclk2Freq;
DEBUG_PRINTF("pclk2 freq: %d\n", RCC_Clocks.Pclk2Freq);
}
else
{
spi_apb_clock = RCC_Clocks.Pclk1Freq;
DEBUG_PRINTF("pclk1 freq: %d\n", RCC_Clocks.Pclk1Freq);
}
if(max_hz >= spi_apb_clock/2)
{
SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_2;
}
else if (max_hz >= spi_apb_clock/4)
{
SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_4;
}
else if (max_hz >= spi_apb_clock/8)
{
SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_8;
}
else if (max_hz >= spi_apb_clock/16)
{
SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_16;
}
else if (max_hz >= spi_apb_clock/32)
{
SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_32;
}
else if (max_hz >= spi_apb_clock/64)
{
SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_64;
}
else if (max_hz >= spi_apb_clock/128)
{
SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_128;
}
else
{
/* min prescaler 256 */
SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_256;
}
} /* baudrate */
switch(configuration->mode & RT_SPI_MODE_3)
{
case RT_SPI_MODE_0:
SPI_InitStruct.CLKPHA = SPI_CLKPHA_FIRST_EDGE;
SPI_InitStruct.CLKPOL = SPI_CLKPOL_LOW;
break;
case RT_SPI_MODE_1:
SPI_InitStruct.CLKPHA = SPI_CLKPHA_SECOND_EDGE;
SPI_InitStruct.CLKPOL = SPI_CLKPOL_LOW;
break;
case RT_SPI_MODE_2:
SPI_InitStruct.CLKPHA = SPI_CLKPHA_FIRST_EDGE;
SPI_InitStruct.CLKPOL = SPI_CLKPOL_HIGH;
break;
case RT_SPI_MODE_3:
SPI_InitStruct.CLKPHA = SPI_CLKPHA_SECOND_EDGE;
SPI_InitStruct.CLKPOL = SPI_CLKPOL_HIGH;
break;
}
/* MSB or LSB */
if(configuration->mode & RT_SPI_MSB)
{
SPI_InitStruct.FirstBit = SPI_FB_MSB;
}
else
{
SPI_InitStruct.FirstBit = SPI_FB_LSB;
}
SPI_InitStruct.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
SPI_InitStruct.SpiMode = SPI_MODE_MASTER;
SPI_InitStruct.NSS = SPI_NSS_SOFT;
/* init SPI */
SPI_Init(spi_instance->config->spix, &SPI_InitStruct);
/* Enable SPI_MASTER */
SPI_Enable(spi_instance->config->spix, ENABLE);
SPI_EnableCalculateCrc(spi_instance->config->spix, DISABLE);
return RT_EOK;
};
static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message)
{
struct rt_spi_bus * at32_spi_bus = (struct rt_spi_bus *)device->bus;
struct n32_spi *spi_instance = (struct n32_spi *)at32_spi_bus->parent.user_data;
struct rt_spi_configuration * config = &device->config;
struct n32_spi_cs * at32_spi_cs = device->parent.user_data;
RT_ASSERT(device != NULL);
RT_ASSERT(message != NULL);
/* take CS */
if(message->cs_take)
{
GPIO_ResetBits(at32_spi_cs->GPIOx, at32_spi_cs->GPIO_Pin);
DEBUG_PRINTF("spi take cs\n");
}
{
if(config->data_width <= 8)
{
const rt_uint8_t * send_ptr = message->send_buf;
rt_uint8_t * recv_ptr = message->recv_buf;
rt_uint32_t size = message->length;
DEBUG_PRINTF("spi poll transfer start: %d\n", size);
while(size--)
{
rt_uint8_t data = 0xFF;
if(send_ptr != RT_NULL)
{
data = *send_ptr++;
}
// Todo: replace register read/write by at32 lib
//Wait until the transmit buffer is empty
while(RESET == SPI_I2S_GetStatus(spi_instance->config->spix, SPI_I2S_TE_FLAG));
// Send the byte
SPI_I2S_TransmitData(spi_instance->config->spix, data);
//Wait until a data is received
while(RESET == SPI_I2S_GetStatus(spi_instance->config->spix, SPI_I2S_RNE_FLAG));
// Get the received data
data = SPI_I2S_ReceiveData(spi_instance->config->spix);
if(recv_ptr != RT_NULL)
{
*recv_ptr++ = data;
}
}
DEBUG_PRINTF("spi poll transfer finsh\n");
}
else if(config->data_width <= 16)
{
const rt_uint16_t * send_ptr = message->send_buf;
rt_uint16_t * recv_ptr = message->recv_buf;
rt_uint32_t size = message->length;
while(size--)
{
rt_uint16_t data = 0xFF;
if(send_ptr != RT_NULL)
{
data = *send_ptr++;
}
//Wait until the transmit buffer is empty
while(RESET == SPI_I2S_GetStatus(spi_instance->config->spix, SPI_I2S_TE_FLAG));
// Send the byte
SPI_I2S_TransmitData(spi_instance->config->spix, data);
//Wait until a data is received
while(RESET == SPI_I2S_GetStatus(spi_instance->config->spix, SPI_I2S_RNE_FLAG));
// Get the received data
data = SPI_I2S_ReceiveData(spi_instance->config->spix);
if(recv_ptr != RT_NULL)
{
*recv_ptr++ = data;
}
}
}
}
/* release CS */
if(message->cs_release)
{
GPIO_SetBits(at32_spi_cs->GPIOx, at32_spi_cs->GPIO_Pin);
DEBUG_PRINTF("spi release cs\n");
}
return message->length;
};
static struct n32_spi_config configs[] = {
#ifdef BSP_USING_SPI1
{SPI1, "spi1"},
#endif
#ifdef BSP_USING_SPI2
{SPI2, "spi2"},
#endif
#ifdef BSP_USING_SPI3
{SPI3, "spi3"},
#endif
#ifdef BSP_USING_SPI4
{SPI4, "spi4"},
#endif
};
static struct n32_spi spis[sizeof(configs) / sizeof(configs[0])] = {0};
/** \brief init and register at32 spi bus.
*
* \param SPI: at32 SPI, e.g: SPI1,SPI2,SPI3.
* \param spi_bus_name: spi bus name, e.g: "spi1"
* \return
*
*/
int rt_hw_spi_init(void)
{
int i;
rt_err_t result;
rt_size_t obj_num = sizeof(spis) / sizeof(struct n32_spi);
for (i = 0; i < obj_num; i++)
{
spis[i].config = &configs[i];
spis[i].spi_bus.parent.user_data = (void *)&spis[i];
result = rt_spi_bus_register(&(spis[i].spi_bus), spis[i].config->spi_name, &n32_spi_ops);
}
return result;
}
INIT_BOARD_EXPORT(rt_hw_spi_init);
#endif

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-01-09 shelton first version
*/
#ifndef __DRV_SPI__
#define __DRV_SPI__
#include <rtthread.h>
#include <drivers/spi.h>
#include "n32g45x.h"
struct n32_spi_config
{
SPI_Module *spix;
const char *spi_name;
};
struct n32_spi
{
struct n32_spi_config *config;
struct rt_spi_bus spi_bus;
};
struct n32_spi_cs
{
GPIO_Module *GPIOx;
uint32_t GPIO_Pin;
};
/* public function */
int rt_hw_spi_init(void);
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_Module *cs_gpiox, uint16_t cs_gpio_pin);
#endif // __DRV_SPI__

View File

@ -0,0 +1,124 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-01-22 shelton first version
*/
#include <board.h>
#include <drivers/watchdog.h>
#ifdef RT_USING_WDT
#define LSI_VALUE 40000
//#define DRV_DEBUG
#define LOG_TAG "drv.wdt"
#include <drv_log.h>
struct at32_wdt_obj
{
IWDG_Type *instance;
rt_uint32_t Prescaler;
rt_uint32_t Reload;
rt_uint16_t is_start;
};
static struct at32_wdt_obj at32_wdt;
static struct rt_watchdog_ops ops;
static rt_watchdog_t watchdog;
static rt_err_t wdt_init(rt_watchdog_t *wdt)
{
return RT_EOK;
}
static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
{
switch (cmd)
{
/* feed the watchdog */
case RT_DEVICE_CTRL_WDT_KEEPALIVE:
IWDG_ReloadCounter();
break;
/* set watchdog timeout */
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
#if defined(LSI_VALUE)
if(LSI_VALUE)
{
at32_wdt.Reload = (*((rt_uint32_t*)arg)) * LSI_VALUE / 256 ;
}
else
{
LOG_E("Please define the value of LSI_VALUE!");
}
if(at32_wdt.Reload > 0xFFF)
{
LOG_E("wdg set timeout parameter too large, please less than %ds",0xFFF * 256 / LSI_VALUE);
return -RT_EINVAL;
}
#else
#error "Please define the value of LSI_VALUE!"
#endif
if(at32_wdt.is_start)
{
IWDG_KeyRegWrite(IWDG_KeyRegWrite_Enable);
IWDG_SetPrescaler(at32_wdt.Prescaler);
IWDG_SetReload(at32_wdt.Reload);
IWDG_KeyRegWrite(IWDG_KeyRegWrite_Disable);
IWDG_Enable();
}
break;
case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
#if defined(LSI_VALUE)
if(LSI_VALUE)
{
(*((rt_uint32_t*)arg)) = at32_wdt.Reload * 256 / LSI_VALUE;
}
else
{
LOG_E("Please define the value of LSI_VALUE!");
}
#else
#error "Please define the value of LSI_VALUE!"
#endif
break;
case RT_DEVICE_CTRL_WDT_START:
IWDG_KeyRegWrite(IWDG_KeyRegWrite_Enable);
IWDG_SetPrescaler(at32_wdt.Prescaler);
IWDG_SetReload(at32_wdt.Reload);
IWDG_KeyRegWrite(IWDG_KeyRegWrite_Disable);
IWDG_Enable();
at32_wdt.is_start = 1;
break;
default:
LOG_W("This command is not supported.");
return -RT_ERROR;
}
return RT_EOK;
}
int rt_hw_wdt_init(void)
{
at32_wdt.instance = IWDG;
at32_wdt.Prescaler = IWDG_Psc_256;
at32_wdt.Reload = 0x00000FFF;
at32_wdt.is_start = 0;
ops.init = &wdt_init;
ops.control = &wdt_control;
watchdog.ops = &ops;
/* register watchdog device */
if (rt_hw_watchdog_register(&watchdog, "wdt", RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK)
{
LOG_E("wdt device register failed.");
return -RT_ERROR;
}
LOG_D("wdt device register success.");
return RT_EOK;
}
INIT_BOARD_EXPORT(rt_hw_wdt_init);
#endif /* RT_USING_WDT */

3
bsp/n32g452xx/README.md Executable file
View File

@ -0,0 +1,3 @@
# n32g452xx
:)

View File

@ -23,7 +23,7 @@ menu "On-chip Peripheral Drivers"
select RT_USING_PIN
default y
config RT_USING_ON_CHIP_FLASH
config BSP_USING_ON_CHIP_FLASH
bool "Enable on-chip FLASH"
default n
@ -44,6 +44,120 @@ menu "On-chip Peripheral Drivers"
bool "Enable UART3"
default n
endif
menuconfig BSP_USING_PWM
bool "Enable PWM"
default n
select RT_USING_PWM
if BSP_USING_PWM
menuconfig BSP_USING_TIM1
bool "Enable timer1 output PWM"
default n
if BSP_USING_TIM1
config BSP_USING_TIM1_CH1
bool "Enable TIM1 channel1 PWM"
default n
config BSP_USING_TIM1_CH4
bool "Enable TIM1 channel4 PWM"
default n
endif
menuconfig BSP_USING_TIM2
bool "Enable timer2 output PWM"
default n
if BSP_USING_TIM2
config BSP_USING_TIM2_CH1
bool "Enable TIM2 channel1 PWM"
default n
config BSP_USING_TIM2_CH2
bool "Enable TIM2 channel2 PWM"
default n
endif
endif
menuconfig BSP_USING_HWTIMER
bool "Enable HWTIMER"
default n
select RT_USING_HWTIMER
if BSP_USING_HWTIMER
config BSP_USING_HWTIM3
bool "Enable hardware timer3"
default n
config BSP_USING_HWTIM4
bool "Enable hardware timer4"
default n
config BSP_USING_HWTIM5
bool "Enable hardware timer5"
default n
endif
menuconfig BSP_USING_SPI
bool "Enable SPI BUS"
default n
select RT_USING_SPI
if BSP_USING_SPI
config BSP_USING_SPI1
bool "Enable SPI1 BUS"
default n
config BSP_USING_SPI2
bool "Enable SPI2 BUS"
default n
endif
menuconfig BSP_USING_I2C1
bool "Enable I2C1 BUS (software simulation)"
default n
select RT_USING_I2C
select RT_USING_I2C_BITOPS
select RT_USING_PIN
if BSP_USING_I2C1
config BSP_I2C1_SCL_PIN
int "i2c1 scl pin number"
range 0 63
default 22
config BSP_I2C1_SDA_PIN
int "I2C1 sda pin number"
range 0 63
default 23
endif
menuconfig BSP_USING_ADC
bool "Enable ADC"
default n
select RT_USING_ADC
if BSP_USING_ADC
config BSP_USING_ADC1
bool "Enable ADC1"
default n
config BSP_USING_ADC2
bool "Enable ADC2"
default n
endif
menuconfig BSP_USING_CAN
bool "Enable CAN"
default n
select RT_USING_CAN
if BSP_USING_CAN
config BSP_USING_CAN1
bool "using CAN1"
default n
config BSP_USING_CAN2
bool "using CAN2"
default n
endif
menuconfig BSP_USING_SDIO
bool "Enable SDIO"
default n
select RT_USING_SDIO
if BSP_USING_SDIO
config BSP_USING_SDIO1
bool "Enable SDIO1"
default n
endif
endmenu
endmenu

View File

@ -9,9 +9,11 @@ cwd = GetCurrentDir()
# add general drivers
src = Split('''
board.c
msp/n32_msp.c
''')
path = [cwd]
path += [cwd + '/msp']
startup_path_prefix = SDK_LIB

View File

@ -5,13 +5,18 @@
*
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard first implementation
* 2018-11-06 balanceTWK first version
*/
#include <stdint.h>
#include <rthw.h>
#include <rtthread.h>
#include <board.h>
#ifdef BSP_USING_SRAM
#include "drv_sram.h"
#endif
/**
* @brief This function is executed in case of error occurrence.
* @param None
@ -51,9 +56,9 @@ void SysTick_Handler(void)
}
/**
* This function will initial N32 board.
* This function will initial AT32 board.
*/
void rt_hw_board_init(void)
void rt_hw_board_init()
{
/* NVIC Configuration */
#define NVIC_VTOR_MASK 0x3FFFFF80
@ -75,9 +80,9 @@ void rt_hw_board_init(void)
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#ifdef RT_USING_HEAP
rt_system_heap_init((void*)HEAP_BEGIN, (void*)HEAP_END);
#ifdef BSP_USING_SRAM
rt_system_heap_init((void *)EXT_SRAM_BEGIN, (void *)EXT_SRAM_END);
#else
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
}
/*@}*/

View File

@ -5,41 +5,45 @@
*
* Change Logs:
* Date Author Notes
* 2009-09-22 Bernard add board.h to this bsp
* 2020-01-15 shelton first version
* 2021-02-09 shelton add flash macros
*/
// <<< Use Configuration Wizard in Context Menu >>>
#ifndef __BOARD_H__
#define __BOARD_H__
#include <n32g45x.h>
#include "n32_msp.h"
// <o> Internal SRAM memory size[Kbytes]
// <i>Default: 80
#ifdef __ICCARM__
// Use *.icf ram symbal, to avoid hardcode.
extern char __ICFEDIT_region_RAM_end__;
#define N32_SRAM_END &__ICFEDIT_region_RAM_end__
#else
#define N32_SRAM_SIZE 80
#define N32_SRAM_END (0x20000000 + N32_SRAM_SIZE * 1024)
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __CC_ARM
/* Just only support for AT32F40xxG */
#define N32_FLASH_START_ADRESS ((uint32_t)0x08000000)
#define FLASH_PAGE_SIZE (2 * 1024)
#define N32_FLASH_SIZE (256 * 1024)
#define N32_FLASH_END_ADDRESS ((uint32_t)(N32_FLASH_START_ADRESS + N32_FLASH_SIZE))
/* Internal SRAM memory size[Kbytes] <80>, Default: 80*/
#define N32_SRAM_SIZE (80)
#define N32_SRAM_END (0x20000000 + N32_SRAM_SIZE * 1024)
#if defined(__CC_ARM) || defined(__CLANG_ARM)
extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit)
#define HEAP_BEGIN ((void *)&Image$$RW_IRAM1$$ZI$$Limit)
#elif __ICCARM__
#pragma section="HEAP"
#define HEAP_BEGIN (__segment_end("HEAP"))
#pragma section="CSTACK"
#define HEAP_BEGIN (__segment_end("CSTACK"))
#else
extern int __bss_end;
#define HEAP_BEGIN (&__bss_end)
#define HEAP_BEGIN ((void *)&__bss_end)
#endif
#define HEAP_END N32_SRAM_END
void rt_hw_board_init(void);
#define HEAP_END N32_SRAM_END
#ifdef __cplusplus
}
#endif
//*** <<< end of configuration section >>> ***
#endif /* __BOARD_H__ */

View File

@ -0,0 +1,295 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-04-13 shelton first version
*/
#include <rtthread.h>
#include "n32g45x.h"
#include "n32_msp.h"
#ifdef BSP_USING_UART
void n32_msp_usart_init(void *Instance)
{
GPIO_InitType GPIO_InitCtlStruct;
USART_Module *USARTx = (USART_Module *)Instance;
GPIO_InitStruct(&GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Speed = GPIO_Speed_50MHz;
#ifdef BSP_USING_UART1
if(USART1 == USARTx)
{
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_USART1, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitCtlStruct.Pin = GPIO_PIN_9;
GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitCtlStruct.Pin = GPIO_PIN_10;
GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct);
}
#endif
#ifdef BSP_USING_UART2
if(USART2 == USARTx)
{
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_USART2, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitCtlStruct.Pin = GPIO_PIN_2;
GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitCtlStruct.Pin = GPIO_PIN_3;
GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct);
}
#endif
#ifdef BSP_USING_UART3
if(USART3 == USARTx)
{
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_USART3, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitCtlStruct.Pin = GPIO_PIN_10;
GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitCtlStruct.Pin = GPIO_PIN_11;
GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct);
}
#endif
/* Add others */
}
#endif /* BSP_USING_SERIAL */
#ifdef BSP_USING_SPI
void n32_msp_spi_init(void *Instance)
{
GPIO_InitType GPIO_InitCtlStruct;
SPI_Module *SPIx = (SPI_Module *)Instance;
GPIO_InitStruct(&GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Speed = GPIO_Speed_50MHz;
#ifdef BSP_USING_SPI1
if(SPI1 == SPIx)
{
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_SPI1, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitCtlStruct.Pin = GPIO_PIN_4;
GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitCtlStruct.Pin = GPIO_PIN_5 | GPIO_PIN_7;
GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitCtlStruct.Pin = GPIO_PIN_6;
GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct);
}
#endif
#ifdef BSP_USING_SPI2
if(SPI2 == SPIx)
{
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_SPI2, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitCtlStruct.Pin = GPIO_PIN_12;
GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitCtlStruct.Pin = GPIO_PIN_13 | GPIO_PIN_15;
GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitCtlStruct.Pin = GPIO_PIN_14;
GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct);
}
#endif
/* Add others */
}
#endif /* BSP_USING_SPI */
#ifdef BSP_USING_SDIO
void n32_msp_sdio_init(void *Instance)
{
GPIO_InitType GPIO_InitCtlStructure;
SDIO_Module *SDIOx = (SDIO_Module *)Instance;
GPIO_InitStruct(&GPIO_InitCtlStructure);
GPIO_InitCtlStructure.GPIO_Speed = GPIO_Speed_50MHz;
if(SDIO == SDIOx)
{
/* if used dma ... */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA2, ENABLE);
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_SDIO, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC | RCC_APB2_PERIPH_GPIOD, ENABLE);
GPIO_InitCtlStructure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
GPIO_InitCtlStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStructure);
GPIO_InitCtlStructure.Pin = GPIO_PIN_2;
GPIO_InitCtlStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitPeripheral(GPIOD, &GPIO_InitCtlStructure);
}
}
#endif /* BSP_USING_SDIO */
#ifdef BSP_USING_PWM
void n32_msp_tmr_init(void *Instance)
{
GPIO_InitType GPIO_InitCtlStructure;
GPIO_InitStruct(&GPIO_InitCtlStructure);
TIM_Module *TIMx = (TIM_Module *)Instance;
if(TIMx == TIM1)
{
/* TIM1 clock enable */
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_TIM1, ENABLE);
/* GPIOA clock enable */
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
/* GPIOA Configuration:TIM1 Channel1 and Channel4 as alternate function push-pull */
GPIO_InitCtlStructure.Pin = GPIO_PIN_8 | GPIO_PIN_11;
GPIO_InitCtlStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitCtlStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStructure);
}
if(TIMx == TIM2)
{
/* TIM2 clock enable */
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM2, ENABLE);
/* GPIOA clock enable */
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
/* GPIOA Configuration:TIM2 Channel1 and Channel2 as alternate function push-pull */
GPIO_InitCtlStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitCtlStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitCtlStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStructure);
}
/* Add others */
}
#endif /* BSP_USING_PWM */
#ifdef BSP_USING_ADC
void n32_msp_adc_init(void *Instance)
{
GPIO_InitType GPIO_InitCtlStruct;
GPIO_InitStruct(&GPIO_InitCtlStruct);
ADC_Module *ADCx = (ADC_Module *)Instance;
#ifdef BSP_USING_ADC1
if(ADCx == ADC1)
{
/* ADC1 & GPIO clock enable */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1, ENABLE);
ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV8);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE);
/* Configure ADC Channel as analog input */
GPIO_InitCtlStruct.Pin = GPIO_PIN_0;
GPIO_InitCtlStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStruct);
}
#endif
#ifdef BSP_USING_ADC2
if(ADCx == ADC2)
{
/* ADC2 & GPIO clock enable */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC2, ENABLE);
ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV8);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE);
/* Configure ADC Channel as analog input */
GPIO_InitCtlStruct.Pin = GPIO_PIN_1;
GPIO_InitCtlStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStruct);
}
#endif
}
#endif /* BSP_USING_ADC */
#ifdef BSP_USING_HWTIMER
void n32_msp_hwtmr_init(void *Instance)
{
TIM_Module *TIMx = (TIM_Module *)Instance;
#ifdef BSP_USING_HWTIM3
if(TIMx == TIM3)
{
/* TIM3 clock enable */
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM3, ENABLE);
}
#endif
#ifdef BSP_USING_HWTIM4
if(TIMx == TIM4)
{
/* TIM4 clock enable */
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM4, ENABLE);
}
#endif
#ifdef BSP_USING_HWTIM5
if(TIMx == TIM5)
{
/* TIM5 clock enable */
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM5, ENABLE);
}
#endif
}
#endif
#ifdef BSP_USING_CAN
void n32_msp_can_init(void *Instance)
{
GPIO_InitType GPIO_InitCtlStruct;
CAN_Module *CANx = (CAN_Module *)Instance;
GPIO_InitStruct(&GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Speed = GPIO_Speed_50MHz;
#ifdef BSP_USING_CAN1
if(CAN1 == CANx)
{
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN1, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitCtlStruct.Pin = GPIO_PIN_12;
GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitCtlStruct.Pin = GPIO_PIN_11;
GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct);
}
#endif
#ifdef BSP_USING_CAN2
if(CAN2 == CANx)
{
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN2, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
// GPIO_PinsRemapConfig(AFIO_MAP6_CAN2_0001, ENABLE);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitCtlStruct.Pin = GPIO_PIN_6;
GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct);
GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitCtlStruct.Pin = GPIO_PIN_5;
GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct);
}
#endif
}
#endif /* BSP_USING_CAN */

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-04-13 shelton first version
*/
#ifndef __N32_MSP_H__
#define __N32_MSP_H__
void n32_msp_usart_init(void *Instance);
void n32_msp_spi_init(void *Instance);
void n32_msp_tmr_init(void *Instance);
void n32_msp_sdio_init(void *Instance);
void n32_msp_adc_init(void *Instance);
void n32_msp_hwtmr_init(void *Instance);
void n32_msp_can_init(void *Instance);
#endif /* __N32_MSP_H__ */

View File

@ -88,7 +88,11 @@
#define RT_USING_SERIAL_V1
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_I2C
#define RT_USING_I2C_BITOPS
#define RT_USING_PIN
#define RT_USING_ADC
#define RT_USING_SPI
/* Using USB */
@ -97,7 +101,7 @@
#define RT_USING_LIBC
#define RT_USING_POSIX
#define RT_LIBC_FIXED_TIMEZONE 8
#define RT_LIBC_DEFAULT_TIMEZONE 8
/* Network */
@ -182,7 +186,19 @@
/* On-chip Peripheral Drivers */
#define RT_USING_GPIO
#define BSP_USING_ON_CHIP_FLASH
#define RT_USING_UART
#define RT_USING_UART1
#define RT_USING_UART2
#define RT_USING_UART3
#define BSP_USING_SPI
#define BSP_USING_SPI1
#define BSP_USING_SPI2
#define BSP_USING_I2C1
#define BSP_I2C1_SCL_PIN 22
#define BSP_I2C1_SDA_PIN 23
#define BSP_USING_ADC
#define BSP_USING_ADC1
#define BSP_USING_ADC2
#endif