提交 1731a6cd 编写于 作者: whik1194's avatar whik1194

1.Modify project directory structure

2.Add support for GPIO and UART peripherals
3.Add pin and serial device driver support
4.Put pictures in local folder
5.Modify README file
上级 02c6c92a
/*******************************************************************************
* (c) Copyright 2014 Microsemi SoC Products Group. All rights reserved.
*
* Keil-MDK specific system initialization.
*
* SVN $Revision: 7375 $
* SVN $Date: 2015-05-01 14:57:40 +0100 (Fri, 01 May 2015) $
*/
#ifdef MSCC_NO_RELATIVE_PATHS
#include "m2sxxx.h"
#else
#include "..\m2sxxx.h"
#endif
#define ENVM_BASE_ADDRESS 0x60000000U
#define MDDR_BASE_ADDRESS 0xA0000000U
//extern unsigned int Image$$ER_RW$$Base;
//extern unsigned int Image$$ER_RO$$Base;
/*==============================================================================
* The __low_level_init() function is called after SystemInit. Therefore, the
* external RAM should be configured at this stage if it is used.
*/
/* void low_level_init(void)
{
volatile unsigned int rw_region_base;
volatile unsigned int readonly_region_base;
rw_region_base = (unsigned int)&Image$$ER_RW$$Base;
if (rw_region_base >= MDDR_BASE_ADDRESS)
{
/ --------------------------------------------------------------------------
* Remap MDDR to address 0x00000000.
/
SYSREG->ESRAM_CR = 0u;
SYSREG->ENVM_REMAP_BASE_CR = 0u;
SYSREG->DDR_CR = 1u;
}
readonly_region_base = (unsigned int)&Image$$ER_RO$$Base;
SCB->VTOR = readonly_region_base;
} */
/*******************************************************************************
* (c) Copyright 2013 Microsemi SoC Products Group. All rights reserved.
*
* Redirection of the standard library I/O to one of the SmartFusion2
* MMUART.
*
* SVN $Revision: 7375 $
* SVN $Date: 2015-05-01 14:57:40 +0100 (Fri, 01 May 2015) $
*/
/*==============================================================================
* The content of this source file will only be compiled if either one of the
* following two defined symbols are defined in the project settings:
* - MICROSEMI_STDIO_THRU_MMUART0
* - MICROSEMI_STDIO_THRU_MMUART1
*
*/
#ifdef MICROSEMI_STDIO_THRU_MMUART0
#ifndef MICROSEMI_STDIO_THRU_UART
#define MICROSEMI_STDIO_THRU_UART
#endif
#endif /* MICROSEMI_STDIO_THRU_MMUART0 */
#ifdef MICROSEMI_STDIO_THRU_MMUART1
#ifndef MICROSEMI_STDIO_THRU_UART
#define MICROSEMI_STDIO_THRU_UART
#endif
#endif /* MICROSEMI_STDIO_THRU_MMUART1 */
/*==============================================================================
* Actual implementation.
*/
#ifdef MICROSEMI_STDIO_THRU_UART
#include <stdio.h>
#include <rt_misc.h>
#include "m2sxxx.h"
#include "mss_uart.h"
#include "core_uart_apb.h"
/*
* The baud rate will default to 57600 baud if no baud rate is specified though the
* MICROSEMI_STDIO_BAUD_RATE define.
*/
#ifndef MICROSEMI_STDIO_BAUD_RATE
#define MICROSEMI_STDIO_BAUD_RATE MSS_UART_115200_BAUD
#endif
#ifdef MICROSEMI_STDIO_THRU_MMUART0
static mss_uart_instance_t * const gp_my_uart = &g_mss_uart0;
#else
static mss_uart_instance_t * const gp_my_uart = &g_mss_uart1;
#endif
/*==============================================================================
* Flag used to indicate if the UART driver needs to be initialized.
*/
static int g_stdio_uart_init_done = 0;
#define LSR_THRE_MASK 0x20u
/*
* Disable semihosting apis
*/
#pragma import(__use_no_semihosting_swi)
/*==============================================================================
* sendchar()
*/
int sendchar(int ch)
{
uint32_t tx_ready;
//第一次调用时,初始化串口
if(!g_stdio_uart_init_done)
{
MSS_UART_init(gp_my_uart,
MICROSEMI_STDIO_BAUD_RATE,
MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY);
g_stdio_uart_init_done = 1;
}
do {
tx_ready = gp_my_uart->hw_reg->LSR & LSR_THRE_MASK;
} while(!tx_ready);
gp_my_uart->hw_reg->THR = ch;
return (ch);
}
/*==============================================================================
*
*/
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;
/*==============================================================================
* fputc()
*/
int fputc(int ch, FILE *f)
{
return (sendchar(ch));
}
/*==============================================================================
* fgetc()
*/
int fgetc(FILE *f)
{
uint8_t rx_size;
uint8_t rx_byte;
do {
rx_size = MSS_UART_get_rx(gp_my_uart, &rx_byte, 1);
} while(0u == rx_size);
return rx_byte;
}
/*==============================================================================
* ferror()
*/
int ferror(FILE *f)
{
/* Your implementation of ferror */
return EOF;
}
/*==============================================================================
* _ttywrch()
*/
void _ttywrch(int ch)
{
sendchar(ch);
}
/*==============================================================================
* _sys_exit()
*/
void _sys_exit(int return_code)
{
for(;;)
{
; /* endless loop */
}
}
#endif /* MICROSEMI_STDIO_THRU_UART */
......@@ -2,29 +2,41 @@
### 1. BSP简介
移植 RT-Thread 操作系统到 一款 **FPGA 芯片——M2S010** 上,该芯片属于 [Microsemi](https://www.microsemi.com/)(现Microchip)SmartFusion2系列,是一款**智能混合型FPGA**,片上除了 FPGA Fabric 逻辑部分,还包括一个 ARM® Cortex™-M3 内核的 MCU,主频最高 166MHz ,256KB eNVM,64KB eSRAM,集成GPIO、UART、I2C、SPI、CAN、USB等基本外设。
移植 RT-Thread 操作系统到一款 **FPGA 芯片——M2S010** ,该芯片属于 [Microsemi](https://www.microsemi.com/)(现Microchip)SmartFusion2系列,是一款**智能混合型FPGA**,片上除了 FPGA Fabric 逻辑部分,还包括一个 **ARM® Cortex™-M3 内核的 MCU**,主频最高 166MHz ,256KB eNVM,64KB eSRAM,集成GPIO、UART、I2C、SPI、CAN、USB等基本外设。
> 关于 Microsemi,第三大 FPGA 厂商,原 Actel 半导体,2010 年,Microsemi 收购 Actel,2018 年, Microchip 收购 Microsemi。
SmartFusion2 内部框图
![](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/Microsemi_Smartfusion2_BD.jpg)
![Microsemi_Smartfusion2_BD](figures/Microsemi_Smartfusion2_BD.jpg)
### 2. 使用说明
### 2. 外设支持
#### 2.1 FPGA 工程设计
移植了 RT-Thread 内核,支持线程调度、线程间同步和通信等,目前已经完成了PIN、Serial设备驱动,FinSH组件默认使用uart0设备。
FPGA 部分使用 SmartDesign 图形化设计,不需要写 HDL 代码,时钟来自外部 50M 晶体输入,PLL 倍频 100M 提供给 MCU 使用,顶层配置如下图所示:
| **片上外设** | **支持情况** | **备注** |
| :----------------- | :----------: | :------------------------------------- |
| GPIO | 支持 | GPIO_0/1输出,GPIO_2/3输入 |
| UART | 支持 | MMUART0 & MMUART1|
| SPI | 暂不支持 | |
| I2C | 暂不支持 | |
| RTC | 暂不支持 | |
| PWM | 暂不支持 | |
| USB | 暂不支持 | |
### 3. 使用说明
![](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/2020-06-02_114736.jpg)
#### 3.1 FPGA 工程设计
MSS 部分仅使用到了GPIO 和UART0,其他外设未启用,两个 GPIO 配置成输出模式
FPGA 部分使用 SmartDesign 图形化设计,不需要写 HDL 代码,时钟来自外部 50M 晶体输入,PLL 倍频 100M 提供给 MCU 使用,顶层配置如下图所示
![](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/2020-06-02_114816.jpg)
![](figures/top_sd.jpg)
配置完成的 FPGA 工程文件下载:[fpga_project.rar](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/fpga_project.rar)
MSS 部分仅使用到了GPIO 和UART,GPIO_0和GPIO_1配置成输出输出模式用于驱动LED,GPIO_2和GPIO_3配置成输入模式,用于读取按键输入。
#### 2.2 ARM 程序设计
配置完成的 FPGA 工程文件下载:[sf2_fpga_prj.rar](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/sf2_fpga_prj.rar)
#### 3.2 ARM 程序设计
ARM 程序使用 Keil MDK 5.26 开发,需要安装 M2S 系列芯片支持包:[Microsemi.M2Sxxx.1.0.64.pack](http://www.actel-ip.com/repositories/CMSIS-Pack/Microsemi.M2Sxxx.1.0.64.pack)
......@@ -32,25 +44,24 @@ ARM 程序使用 Keil MDK 5.26 开发,需要安装 M2S 系列芯片支持包
在官方生成的示例工程目录下,添加 RT-Thread 相关组件,并实现一些对接函数,最终的文件结构:
![](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/2020-06-04_213532.png)
![](figures/files.jpg)
### 3. 下载和运行
### 4. 下载和运行
为了能使用 ARM 调试器连接到 ARM 内核,而不是 FPGA,需要把 JTAG_SEL 引脚置为低电平。使用 ARM 调试器,如 JLink,对应连接 JTAG 口的 TMS、TCK、GND 引脚,如果连接正常,可以检测到 ARM 芯片,如下图所示:
![](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/2020-06-02_115130.jpg)
![](figures/jlink-ob.jpg)
配置对应的 Flash 编程算法:
![](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/2020-06-02_115115.jpg)
![](figures/flash.jpg)
下载完成:
![](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/2020-06-02_115216.jpg)
![](figures/finished.jpg)
如果编译 & 烧写无误,下载完成或者按下复位按键之后,会在串口上看到 RT-Thread 的启动 LOG 信息:
```c
\ | /
- RT - Thread Operating System
......@@ -59,20 +70,9 @@ ARM 程序使用 Keil MDK 5.26 开发,需要安装 M2S 系列芯片支持包
msh >
```
![](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/2020-06-02_115305.jpg)
### 4. 外设支持
目前仅移植了 RT-Thread 内核,支持线程调度、线程间同步和通信等,支持 Finsh 组件,PIN、Serial 等设备驱动将会在以后添加。
### 5. 资料下载
独立的工程文件下载:
- FPGA 工程下载:[fpga_project.rar](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/fpga_project.rar)
- ARM 工程下载:[smartfusion_rtt-master-4.0.3.rar](https://wcc-blog.oss-cn-beijing.aliyuncs.com/Libero/RT-Thread/smartfusion_rtt-master-4.0.3.rar)
![](figures/log.jpg)
### 6. 注意事项
### 5. 注意事项
- FPGA 开发环境基于 Libero V11.8.2.4,向上兼容,不支持低版本 IDE。
- ARM 开发环境基于 Keil MDK 5.26,如果使用SoftConsole IDE ,需要修改 `libcpu` 内的文件。
......@@ -80,13 +80,12 @@ msh >
- 使用 SoftConsole 开发环境可以直接使用官方的 Flash Pro 调试器进行 ARM 程序的调试。
- 内核时钟需要和 FPGA 中 MSS 配置的对应,Libero 自动生成的时钟文件,可以直接替换`bsp\smartfusion2\libraries\sys_config`文件夹下的文件 。
### 7. 参考资料
### 6. 参考资料
- [学习路线 - RT-Thread 文档中心](https://www.rt-thread.org/document/site/)
- [Microsemi Libero系列中文教程](https://blog.csdn.net/whik1194/article/details/102901710)
### 8. 联系我
### 7. 联系我
- 邮箱:wangchao149@foxmail.com
- 主页:www.wangchaochao.top
- 微信:wcc149
- Github:[whik](https://github.com/whik)
- E-Mail:wangchao149@foxmail.com
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#define LED0_PIN 0
#define LED1_PIN 1
#define SW0_PIN 2
#define SW1_PIN 3
extern void sw0_isr(void *args);
extern void sw1_isr(void *args);
int main(void)
{
int count = 1;
rt_pin_attach_irq(SW0_PIN, PIN_IRQ_MODE_RISING, sw0_isr, RT_NULL);
rt_pin_attach_irq(SW1_PIN, PIN_IRQ_MODE_RISING, sw1_isr, RT_NULL);
rt_pin_irq_enable(SW0_PIN, PIN_IRQ_ENABLE);
rt_pin_irq_enable(SW1_PIN, PIN_IRQ_ENABLE);
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
while(count++)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_pin_write(LED1_PIN, PIN_HIGH);
rt_thread_mdelay(100);
rt_pin_write(LED0_PIN, PIN_LOW);
rt_pin_write(LED1_PIN, PIN_LOW);
rt_thread_mdelay(100);
}
return RT_EOK;
}
......@@ -20,13 +20,7 @@
#define _SYSTICK_CALIB (*(rt_uint32_t *)(_SCB_BASE + 0xC))
#define _SYSTICK_PRI (*(rt_uint8_t *)(0xE000ED23UL))
// Updates the variable SystemCoreClock and must be called
// whenever the core clock is changed during program execution.
extern void SystemCoreClockUpdate(void);
// Holds the system core clock, which is the system clock
// frequency supplied to the SysTick timer and the processor
// core clock.
extern uint32_t SystemCoreClock;
static uint32_t _SysTick_Config(rt_uint32_t ticks)
......@@ -66,14 +60,16 @@ void rt_hw_board_init()
/* System Tick Configuration */
_SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
//#ifdef RT_USING_CONSOLE
// rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
//#endif
#ifdef RT_USING_CONSOLE
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
......
#include "config.h"
void sw0_isr(void *args)
{
rt_kprintf("sw_0 is trigger \r\n");
rt_thread_mdelay(400);
}
void sw1_isr(void *args)
{
rt_kprintf("sw_1 is trigger \r\n");
rt_thread_mdelay(400);
}
/* hardware initialization */
void boardInit(void)
{
/* disable watchdog timer */
SYSREG->WDOG_CR = 0;
}
INIT_BOARD_EXPORT(boardInit);
/* custom finish command */
extern uint32_t SystemCoreClock;
void sayHello(void)
{
rt_kprintf("Hello RT-Thread! By Microsemi SmartFusion2 Family FPGA-M2S010.\r\n");
rt_kprintf("MSS System Core Clock: %d Hz.\r\n", SystemCoreClock);
}
MSH_CMD_EXPORT(sayHello, "say hello to console");
#ifndef __INIT_H__
#define __INIT_H__
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include "mss_gpio.h"
#include "mss_uart.h"
......@@ -7,10 +7,9 @@
#include <rthw.h>
#include <rtthread.h>
void sw0_isr(void *args);
void sw1_isr(void *args);
void boardInit(void);
void MSS_UART_polled_tx_byte(mss_uart_instance_t *this_uart, const uint8_t byte);
void rt_hw_console_output(const char *str);
char rt_hw_console_getchar(void);
void sayHello(void);
#endif
......@@ -12,6 +12,11 @@ del *.map /s
del *.lst /s
del *.dep /s
del *.build_log.htm /s
del *.bak
del *.bak /s
del *.sct /s
del *.axf /s
del JLinkLog.txt /s
del SConscript /s
echo 编译产生的其他文件已经删除
#include <rtthread.h>
#include <rtdevice.h>
#include <rthw.h>
#include "mss_gpio.h"
#include "drv_gpio.h"
#ifdef BSP_USING_GPIO
static struct rt_pin_irq_hdr sf2_pin_irq_hdr_tab[] =
{
/* pin, hdr, mode, args */
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
};
/* configure an individual GPIO port */
static void sf2_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
uint32_t config;
switch (mode)
{
case PIN_MODE_OUTPUT:
config = MSS_GPIO_OUTPUT_MODE;
break;
case PIN_MODE_INPUT:
config = MSS_GPIO_INPUT_MODE;
break;
default:
config = MSS_GPIO_INOUT_MODE;
break;
}
MSS_GPIO_config((mss_gpio_id_t )pin, config);
}
static int sf2_pin_read(rt_device_t dev, rt_base_t pin)
{
uint32_t value;
value = MSS_GPIO_get_inputs() & (1<<pin);
return ((value) ? PIN_HIGH : PIN_LOW);
}
static void sf2_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
if (value == PIN_HIGH)
MSS_GPIO_set_output((mss_gpio_id_t )pin, 1);
else
MSS_GPIO_set_output((mss_gpio_id_t )pin, 0);
}
static rt_err_t sf2_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
rt_base_t level;
level = rt_hw_interrupt_disable();
if (sf2_pin_irq_hdr_tab[pin].pin == pin &&
sf2_pin_irq_hdr_tab[pin].hdr == hdr &&
sf2_pin_irq_hdr_tab[pin].mode == mode &&
sf2_pin_irq_hdr_tab[pin].args == args)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
if (sf2_pin_irq_hdr_tab[pin].pin != -1)
{
rt_hw_interrupt_enable(level);
return -RT_EBUSY;
}
sf2_pin_irq_hdr_tab[pin].pin = pin;
sf2_pin_irq_hdr_tab[pin].hdr = hdr;
sf2_pin_irq_hdr_tab[pin].mode = mode;
sf2_pin_irq_hdr_tab[pin].args = args;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t sf2_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
rt_base_t level;
level = rt_hw_interrupt_disable();
if (sf2_pin_irq_hdr_tab[pin].pin == -1)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
sf2_pin_irq_hdr_tab[pin].pin = -1;
sf2_pin_irq_hdr_tab[pin].hdr = RT_NULL;
sf2_pin_irq_hdr_tab[pin].mode = 0;
sf2_pin_irq_hdr_tab[pin].args = RT_NULL;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t sf2_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
{
uint32_t mode;
rt_base_t level;
if (enabled == PIN_IRQ_ENABLE)
{
level = rt_hw_interrupt_disable();
if (sf2_pin_irq_hdr_tab[pin].pin == -1)
{
rt_hw_interrupt_enable(level);
return -RT_ENOSYS;
}
switch(sf2_pin_irq_hdr_tab[pin].mode)
{
case PIN_IRQ_MODE_RISING :
mode = MSS_GPIO_IRQ_EDGE_POSITIVE;
break;
case PIN_IRQ_MODE_FALLING :
mode = MSS_GPIO_IRQ_EDGE_NEGATIVE;
break;
case PIN_IRQ_MODE_RISING_FALLING:
mode = MSS_GPIO_IRQ_EDGE_BOTH;
break;
case PIN_IRQ_MODE_HIGH_LEVEL :
mode = MSS_GPIO_IRQ_LEVEL_HIGH;
break;
case PIN_IRQ_MODE_LOW_LEVEL:
mode = MSS_GPIO_IRQ_LEVEL_LOW;
break;
}
MSS_GPIO_config((mss_gpio_id_t )pin, MSS_GPIO_INPUT_MODE | mode);
MSS_GPIO_enable_irq((mss_gpio_id_t )pin);
rt_hw_interrupt_enable(level);
}
else if (enabled == PIN_IRQ_DISABLE)
{
MSS_GPIO_config((mss_gpio_id_t )pin, MSS_GPIO_INPUT_MODE);
MSS_GPIO_disable_irq((mss_gpio_id_t )pin);
}
else
return -RT_ENOSYS;
return RT_EOK;
}
static const struct rt_pin_ops sf2_pin_ops =
{
sf2_pin_mode,
sf2_pin_write,
sf2_pin_read,
sf2_pin_attach_irq,
sf2_pin_detach_irq,
sf2_pin_irq_enable
};
int rt_hw_pin_init(void)
{
rt_err_t result = RT_EOK;
MSS_GPIO_init();
result = rt_device_pin_register("pin", &sf2_pin_ops, RT_NULL);
RT_ASSERT(result == RT_EOK);
return result;
}
INIT_BOARD_EXPORT(rt_hw_pin_init);
rt_inline void pin_irq_hdr(int pin)
{
MSS_GPIO_clear_irq((mss_gpio_id_t )pin);
if (sf2_pin_irq_hdr_tab[pin].hdr)
sf2_pin_irq_hdr_tab[pin].hdr(sf2_pin_irq_hdr_tab[pin].args);
}
void GPIO0_IRQHandler( void )
{
/* enter interrupt */
rt_interrupt_enter();
pin_irq_hdr(0);
/* leave interrupt */
rt_interrupt_leave();
}
void GPIO1_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(1);
rt_interrupt_leave();
}
void GPIO2_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(2);
rt_interrupt_leave();
}
void GPIO3_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(3);
rt_interrupt_leave();
}
void GPIO4_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(4);
rt_interrupt_leave();
}
void GPIO5_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(5);
rt_interrupt_leave();
}
void GPIO6_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(6);
rt_interrupt_leave();
}
void GPIO7_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(7);
rt_interrupt_leave();
}
void GPIO8_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(8);
rt_interrupt_leave();
}
void GPIO9_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(9);
rt_interrupt_leave();
}
void GPIO10_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(10);
rt_interrupt_leave();
}
void GPIO11_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(11);
rt_interrupt_leave();
}
void GPIO12_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(12);
rt_interrupt_leave();
}
void GPIO13_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(13);
rt_interrupt_leave();
}
void GPIO14_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(14);
rt_interrupt_leave();
}
void GPIO15_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(15);
rt_interrupt_leave();
}
void GPIO16_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(16);
rt_interrupt_leave();
}
void GPIO17_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(17);
rt_interrupt_leave();
}
void GPIO18_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(18);
rt_interrupt_leave();
}
void GPIO19_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(19);
rt_interrupt_leave();
}
void GPIO20_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(20);
rt_interrupt_leave();
}
void GPIO21_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(21);
rt_interrupt_leave();
}
void GPIO22_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(22);
rt_interrupt_leave();
}
void GPIO23_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(23);
rt_interrupt_leave();
}
void GPIO24_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(24);
rt_interrupt_leave();
}
void GPIO25_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(25);
rt_interrupt_leave();
}
void GPIO26_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(26);
rt_interrupt_leave();
}
void GPIO27_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(27);
rt_interrupt_leave();
}
void GPIO28_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(28);
rt_interrupt_leave();
}
void GPIO29_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(29);
rt_interrupt_leave();
}
void GPIO30_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(30);
rt_interrupt_leave();
}
void GPIO31_IRQHandler( void )
{
rt_interrupt_enter();
pin_irq_hdr(31);
rt_interrupt_leave();
}
#endif
#ifndef __DRV_GPIO_H__
#define __DRV_GPIO_H__
int rt_hw_pin_init(void);
#endif
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_uart.h"
struct sf2_uart
{
mss_uart_instance_t *uart;
IRQn_Type irq;
};
struct sf2_uart uart0=
{
&g_mss_uart0,
UART0_IRQn,
};
struct rt_serial_device serial0;
void uart0_rx_handler(mss_uart_instance_t *this_uart)
{
/* enter interrupt */
rt_interrupt_enter();
rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND);
/* leave interrupt */
rt_interrupt_leave();
}
struct sf2_uart uart1=
{
&g_mss_uart1,
UART1_IRQn,
};
struct rt_serial_device serial1;
void uart1_rx_handler(mss_uart_instance_t *this_uart)
{
/* enter interrupt */
rt_interrupt_enter();
rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND);
/* leave interrupt */
rt_interrupt_leave();
}
static rt_err_t sf2_uart_configure(struct rt_serial_device *serial,
struct serial_configure *cfg)
{
uint32_t baudRate;
uint8_t datBits, parity, stopBits;
uint8_t config;
struct sf2_uart *uart;
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
uart = (struct sf2_uart *)serial->parent.user_data;
switch(cfg->data_bits)
{
case DATA_BITS_5: datBits = MSS_UART_DATA_5_BITS; break;
case DATA_BITS_6: datBits = MSS_UART_DATA_6_BITS; break;
case DATA_BITS_7: datBits = MSS_UART_DATA_7_BITS; break;
case DATA_BITS_8: datBits = MSS_UART_DATA_8_BITS; break;
default: datBits = MSS_UART_DATA_8_BITS; break;
}
switch(cfg->parity)
{
case PARITY_NONE: parity = MSS_UART_NO_PARITY; break;
case PARITY_EVEN: parity = MSS_UART_EVEN_PARITY; break;
case PARITY_ODD : parity = MSS_UART_ODD_PARITY; break;
default : parity = MSS_UART_NO_PARITY; break;
}
switch(cfg->stop_bits)
{
case STOP_BITS_1: stopBits = MSS_UART_ONE_STOP_BIT; break;
case STOP_BITS_2: stopBits = MSS_UART_TWO_STOP_BITS; break;
case STOP_BITS_3: stopBits = MSS_UART_ONEHALF_STOP_BIT; break;
default : stopBits = MSS_UART_ONE_STOP_BIT;
}
baudRate = cfg->baud_rate;
config = datBits | parity | stopBits;
MSS_UART_init(uart->uart, baudRate, config);
if(uart->uart == &g_mss_uart0)
MSS_UART_set_rx_handler(uart->uart, uart0_rx_handler, MSS_UART_FIFO_SINGLE_BYTE);
else
MSS_UART_set_rx_handler(uart->uart, uart1_rx_handler, MSS_UART_FIFO_SINGLE_BYTE);
return RT_EOK;
}
static rt_err_t sf2_uart_control(struct rt_serial_device *serial,
int cmd, void *arg)
{
struct sf2_uart* uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct sf2_uart*)serial->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
NVIC_DisableIRQ(uart->irq);
break;
case RT_DEVICE_CTRL_SET_INT:
NVIC_EnableIRQ(uart->irq);
break;
}
return RT_EOK;
}
static int sf2_uart_putc(struct rt_serial_device *serial, char c)
{
struct sf2_uart* uart;
uint32_t tx_ready;
RT_ASSERT(serial != RT_NULL);
uart = (struct sf2_uart*)serial->parent.user_data;
do {
tx_ready = uart->uart->hw_reg->LSR & 0x20u;
} while(!tx_ready);
uart->uart->hw_reg->THR = c;
return 1;
}
static int sf2_uart_getc(struct rt_serial_device *serial)
{
int ch = -1;
uint8_t err_status;
struct sf2_uart* uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct sf2_uart*)serial->parent.user_data;
err_status = MSS_UART_get_rx_status(uart->uart);
if(MSS_UART_NO_ERROR == err_status)
MSS_UART_get_rx(uart->uart, (uint8_t *)&ch, 1);
return ch;
}
static const struct rt_uart_ops sf2_uart_ops =
{
sf2_uart_configure,
sf2_uart_control,
sf2_uart_putc,
sf2_uart_getc,
};
int rt_hw_uart_init(void)
{
rt_err_t result = RT_EOK;
struct sf2_uart* uart;
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
#ifdef BSP_USING_UART0
uart = &uart0;
serial0.ops = &sf2_uart_ops;
/* default config: 115200, 8, no, 1 */
serial0.config = config;
result = rt_hw_serial_register(&serial0, "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart);
RT_ASSERT(result == RT_EOK);
#endif
#ifdef BSP_USING_UART1
uart = &uart1;
serial1.ops = &sf2_uart_ops;
/* default config: 115200, 8, no, 1 */
serial1.config = config;
result = rt_hw_serial_register(&serial1, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart);
RT_ASSERT(result == RT_EOK);
#endif
return result;
}
INIT_BOARD_EXPORT(rt_hw_uart_init);
#ifndef __DRV_UART_H__
#define __DRV_UART_H__
#include "mss_uart.h"
void uart_rx_handler(mss_uart_instance_t *this_uart);
void uart0_rx_handler(mss_uart_instance_t * this_uart);
void uart1_rx_handler(mss_uart_instance_t * this_uart);
int rt_hw_uart_init(void);
#endif
/*******************************************************************************
* (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
*
* SVN $Revision: 5258 $
* SVN $Date: 2013-03-21 18:11:02 +0530 (Thu, 21 Mar 2013) $
*/
#ifndef __CPU_TYPES_H
#define __CPU_TYPES_H 1
#include <stdint.h>
/*------------------------------------------------------------------------------
*/
typedef unsigned int size_t;
/*------------------------------------------------------------------------------
* addr_t: address type.
* Used to specify the address of peripherals present in the processor's memory
* map.
*/
typedef unsigned int addr_t;
/*------------------------------------------------------------------------------
* psr_t: processor state register.
* Used by HAL_disable_interrupts() and HAL_restore_interrupts() to store the
* processor's state between disabling and restoring interrupts.
*/
typedef unsigned int psr_t;
#endif /* __CPU_TYPES_H */
;-------------------------------------------------------------------------------
; (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
;
; Interrupt disabling/restoration for critical section protection.
;
; SVN $Revision: 5261 $
; SVN $Date: 2013-03-21 19:52:41 +0530 (Thu, 21 Mar 2013) $
;
AREA |.text|, CODE, READONLY
EXPORT HAL_disable_interrupts
EXPORT HAL_restore_interrupts
;-------------------------------------------------------------------------------
;
;
HAL_disable_interrupts \
PROC
mrs r0, PRIMASK
cpsid I
bx lr
ENDP
;-------------------------------------------------------------------------------
;
;
HAL_restore_interrupts \
PROC
msr PRIMASK, r0
bx lr
ENDP
END
/*******************************************************************************
* (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
*
* Hardware registers access macros.
*
* THE MACROS DEFINED IN THIS FILE ARE DEPRECATED. DO NOT USED FOR NEW
* DEVELOPMENT.
*
* These macros are used to access peripheral's registers. They allow access to
* 8, 16 and 32 bit wide registers. All accesses to peripheral registers should
* be done through these macros in order to ease porting accross different
* processors/bus architectures.
*
* Some of these macros also allow to access a specific register field.
*
* SVN $Revision: 5258 $
* SVN $Date: 2013-03-21 18:11:02 +0530 (Thu, 21 Mar 2013) $
*/
#ifndef __HW_REGISTER_MACROS_H
#define __HW_REGISTER_MACROS_H 1
/*------------------------------------------------------------------------------
* 32 bits registers access:
*/
#define HW_get_uint32_reg(BASE_ADDR, REG_OFFSET) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
#define HW_set_uint32_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
#define HW_set_uint32_reg_field(BASE_ADDR, FIELD, VALUE) \
(*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
( \
(uint32_t) \
( \
(*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
(uint32_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
) \
)
#define HW_get_uint32_reg_field( BASE_ADDR, FIELD ) \
(( (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
/*------------------------------------------------------------------------------
* 32 bits memory access:
*/
#define HW_get_uint32(BASE_ADDR) (*((uint32_t volatile *)(BASE_ADDR)))
#define HW_set_uint32(BASE_ADDR, VALUE) (*((uint32_t volatile *)(BASE_ADDR)) = (VALUE))
/*------------------------------------------------------------------------------
* 16 bits registers access:
*/
#define HW_get_uint16_reg(BASE_ADDR, REG_OFFSET) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
#define HW_set_uint16_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
#define HW_set_uint16_reg_field(BASE_ADDR, FIELD, VALUE) \
(*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
( \
(uint16_t) \
( \
(*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
(uint16_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
) \
)
#define HW_get_uint16_reg_field( BASE_ADDR, FIELD ) \
(( (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
/*------------------------------------------------------------------------------
* 8 bits registers access:
*/
#define HW_get_uint8_reg(BASE_ADDR, REG_OFFSET) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
#define HW_set_uint8_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
#define HW_set_uint8_reg_field(BASE_ADDR, FIELD, VALUE) \
(*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
( \
(uint8_t) \
( \
(*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
(uint8_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
) \
)
#define HW_get_uint8_reg_field( BASE_ADDR, FIELD ) \
(( (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
/*------------------------------------------------------------------------------
* 8 bits memory access:
*/
#define HW_get_uint8(BASE_ADDR) (*((uint8_t volatile *)(BASE_ADDR)))
#define HW_set_uint8(BASE_ADDR, VALUE) (*((uint8_t volatile *)(BASE_ADDR)) = (VALUE))
#endif /* __HW_REGISTER_MACROS_H */
/*******************************************************************************
* (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
*
* Legacy Actel HAL Cortex NVIC control functions.
* The use of these functions should be replaced by calls to the equivalent
* CMSIS function in your application code.
*
* SVN $Revision: 7375 $
* SVN $Date: 2015-05-01 19:27:40 +0530 (Fri, 01 May 2015) $
*/
#include "cortex_nvic.h"
#ifdef MSCC_NO_RELATIVE_PATHS
#include "mss_assert.h"
#else
#include "../../CMSIS/mss_assert.h"
#endif
/***************************************************************************//**
*
*/
void NVIC_init( void )
{
/*
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
* functions is obsolete on SmartFusion2 devices.
*
* Simply remove the call to NVIC_init() from your application code.
*/
ASSERT(0);
}
/***************************************************************************//**
*
*/
void NVIC_set_handler
(
uint32_t interrupt_number,
hal_nvic_irq_handler_t handler
)
{
/*
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
* functions is obsolete on SmartFusion2 devices.
*
* Please remove the call to NVIC_set_handler() from your application code
* and provide a function using one of the following function prototypes to
* handle interrupts from peripherals implemeted in the SmartFusion2 FPGA
* fabric:
* - void FabricIrq0_IRQHandler(void)
* - void FabricIrq1_IRQHandler(void)
* - void FabricIrq2_IRQHandler(void)
* - void FabricIrq3_IRQHandler(void)
* - void FabricIrq4_IRQHandler(void)
* - void FabricIrq5_IRQHandler(void)
* - void FabricIrq6_IRQHandler(void)
* - void FabricIrq7_IRQHandler(void)
* - void FabricIrq8_IRQHandler(void)
* - void FabricIrq9_IRQHandler(void)
* - void FabricIrq10_IRQHandler(void)
* - void FabricIrq11_IRQHandler(void)
* - void FabricIrq12_IRQHandler(void)
* - void FabricIrq13_IRQHandler(void)
* - void FabricIrq14_IRQHandler(void)
* - void FabricIrq15_IRQHandler(void)
* The function to implement depends on which MSS_INT_F2M[n] signal is used
* in your Libero design to connect the interrupt signal of the peripheral
* generating the interrupt.
*/
ASSERT(0);
}
/***************************************************************************//**
*
*/
void NVIC_set_priority
(
uint32_t interrupt_number,
uint8_t priority_level
)
{
/*
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
* functions is obsolete on SmartFusion2 devices.
*
* Please replace calls to NVIC_set_priority() with a call to the CMSIS
* void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) function where
* IRQn is one of the following values:
* - FabricIrq0_IRQn
* - FabricIrq1_IRQn
* - FabricIrq2_IRQn
* - FabricIrq3_IRQn
* - FabricIrq4_IRQn
* - FabricIrq5_IRQn
* - FabricIrq6_IRQn
* - FabricIrq7_IRQn
* - FabricIrq8_IRQn
* - FabricIrq9_IRQn
* - FabricIrq10_IRQn
* - FabricIrq11_IRQn
* - FabricIrq12_IRQn
* - FabricIrq13_IRQn
* - FabricIrq14_IRQn
* - FabricIrq15_IRQn
*/
ASSERT(0);
}
/***************************************************************************//**
*
*/
void NVIC_enable_interrupt( uint32_t interrupt_number )
{
/*
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
* functions is obsolete on SmartFusion2 devices.
*
* Please replace calls to NVIC_enable_interrupt() with a call to the CMSIS
* void NVIC_EnableIRQ(IRQn_Type IRQn) function where IRQn is one of the
* following values:
* - FabricIrq0_IRQn
* - FabricIrq1_IRQn
* - FabricIrq2_IRQn
* - FabricIrq3_IRQn
* - FabricIrq4_IRQn
* - FabricIrq5_IRQn
* - FabricIrq6_IRQn
* - FabricIrq7_IRQn
* - FabricIrq8_IRQn
* - FabricIrq9_IRQn
* - FabricIrq10_IRQn
* - FabricIrq11_IRQn
* - FabricIrq12_IRQn
* - FabricIrq13_IRQn
* - FabricIrq14_IRQn
* - FabricIrq15_IRQn
*/
ASSERT(0);
}
/***************************************************************************//**
*
*/
void NVIC_disable_interrupt( uint32_t interrupt_number )
{
/*
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
* functions is obsolete on SmartFusion2 devices.
*
* Please replace calls to NVIC_disable_interrupt() with a call to the CMSIS
* void NVIC_DisableIRQ(IRQn_Type IRQn) function where IRQn is one of the
* following values:
* - FabricIrq0_IRQn
* - FabricIrq1_IRQn
* - FabricIrq2_IRQn
* - FabricIrq3_IRQn
* - FabricIrq4_IRQn
* - FabricIrq5_IRQn
* - FabricIrq6_IRQn
* - FabricIrq7_IRQn
* - FabricIrq8_IRQn
* - FabricIrq9_IRQn
* - FabricIrq10_IRQn
* - FabricIrq11_IRQn
* - FabricIrq12_IRQn
* - FabricIrq13_IRQn
* - FabricIrq14_IRQn
* - FabricIrq15_IRQn
*/
ASSERT(0);
}
/***************************************************************************//**
*
*/
void NVIC_clear_interrupt( uint32_t interrupt_number )
{
/*
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
* functions is obsolete on SmartFusion2 devices.
*
* Please replace calls to NVIC_clear_interrupt() with a call to the CMSIS
* void NVIC_ClearPendingIRQ(IRQn_Type IRQn) function where IRQn is one of the
* following values:
* - FabricIrq0_IRQn
* - FabricIrq1_IRQn
* - FabricIrq2_IRQn
* - FabricIrq3_IRQn
* - FabricIrq4_IRQn
* - FabricIrq5_IRQn
* - FabricIrq6_IRQn
* - FabricIrq7_IRQn
* - FabricIrq8_IRQn
* - FabricIrq9_IRQn
* - FabricIrq10_IRQn
* - FabricIrq11_IRQn
* - FabricIrq12_IRQn
* - FabricIrq13_IRQn
* - FabricIrq14_IRQn
* - FabricIrq15_IRQn
*/
ASSERT(0);
}
/*******************************************************************************
* (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
*
* Legacy Actel HAL Cortex NVIC control functions.
* The use of these functions should be replaced by calls to the equivalent
* CMSIS function in your application code.
*
* SVN $Revision: 5257 $
* SVN $Date: 2013-03-21 17:54:10 +0530 (Thu, 21 Mar 2013) $
*/
#ifndef CORTEX_NVIC_H_
#define CORTEX_NVIC_H_
#include <stdint.h>
typedef void (*hal_nvic_irq_handler_t)(void);
/*------------------------------------------------------------------------------
*
*/
void NVIC_init( void );
/*------------------------------------------------------------------------------
*
*/
void NVIC_set_handler
(
uint32_t interrupt_number,
hal_nvic_irq_handler_t handler
);
/*------------------------------------------------------------------------------
*
*/
void NVIC_set_priority
(
uint32_t interrupt_number,
uint8_t priority_level
);
/*------------------------------------------------------------------------------
*
*/
void NVIC_enable_interrupt( uint32_t interrupt_number );
/*------------------------------------------------------------------------------
*
*/
void NVIC_disable_interrupt( uint32_t interrupt_number );
/*------------------------------------------------------------------------------
*
*/
void NVIC_clear_interrupt( uint32_t interrupt_number );
#endif /*CORTEX_NVIC_H_*/
/*******************************************************************************
* (c) Copyright 2012-2016 Microsemi SoC Products Group. All rights reserved.
*
* SmartFusion2 COMBLK access functions.
*
* SVN $Revision: 8345 $
* SVN $Date: 2016-03-23 11:53:04 +0530 (Wed, 23 Mar 2016) $
*/
#ifndef __MSS_COMBLK_H_
#define __MSS_COMBLK_H_ 1
#include "../../CMSIS/m2sxxx.h"
#include "mss_comblk_page_handler.h"
#ifdef __cplusplus
extern "C" {
#endif
/*------------------------------------------------------------------------------
*
*/
typedef void(*comblk_completion_handler_t)(uint8_t * p_response, uint16_t response_size);
typedef void (*comblk_async_event_handler_t)(uint8_t event_opcode);
/*------------------------------------------------------------------------------
*
*/
void MSS_COMBLK_init
(
comblk_async_event_handler_t async_event_handler,
uint8_t* p_response
);
/*------------------------------------------------------------------------------
*
*/
void MSS_COMBLK_send_cmd_with_ptr
(
uint8_t cmd_opcode,
uint32_t cmd_params_ptr,
uint8_t * p_response,
uint16_t response_size,
comblk_completion_handler_t completion_handler
);
/*------------------------------------------------------------------------------
*
*/
void MSS_COMBLK_send_cmd
(
const uint8_t * p_cmd,
uint16_t cmd_size,
const uint8_t * p_data,
uint32_t data_size,
uint8_t * p_response,
uint16_t response_size,
comblk_completion_handler_t completion_handler
);
/*------------------------------------------------------------------------------
*
*/
void MSS_COMBLK_read
(
const uint8_t * p_data,
uint16_t cmd_size,
uint8_t * p_response,
uint16_t response_size,
comblk_completion_handler_t completion_handler
);
/*------------------------------------------------------------------------------
*
*/
void MSS_COMBLK_send_paged_cmd
(
const uint8_t * p_cmd,
uint16_t cmd_size,
uint8_t * p_response,
uint16_t response_size,
comblk_page_handler_t page_read_handler,
comblk_completion_handler_t completion_handler
);
#ifdef __cplusplus
}
#endif
#endif /* __MSS_COMBLK_H_ */
/*******************************************************************************
* (c) Copyright 2012-2016 Microsemi SoC Products Group. All rights reserved.
*
* SmartFusion2 MSS COM block driver, page handler callback function prototype.
*
* SVN $Revision: 8345 $
* SVN $Date: 2016-03-23 11:53:04 +0530 (Wed, 23 Mar 2016) $
*/
#ifndef __MSS_COMBLK_PAGE_HANDLER_H_
#define __MSS_COMBLK_PAGE_HANDLER_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*-------------------------------------------------------------------------*//**
The comblk_page_handler_t typedef specifies the function prototype of a COMBLK
page handler callback function. This callback is used by the system services
and COMBLK drivers as part of in-system programming (ISP) to retrieve the next
page of programming information to send to the SmartFusion2 System Controller
via the COMBLK.
The COMBLK page handler must be implemented by the application layer to return
the address of the next page of programming data to be sent to the
SmartFusion2 system controller. It must return the number of bytes contained
in the next page. Returning a value of zero indicates that all programming
data has been passed to the system services/COMBLK drivers.
@code
#define PAGE_LENGTH 512
uint8_t programming_data[PROG_DATA_LENGTH];
uint32_t prog_data_index = 0;
uint32_t page_read_handler
(
uint8_t const ** pp_next_page
)
{
uint32_t returned_page_length;
uint32_t remaining_length;
*pp_next_page = &programming_data[prog_data_index];
remaining_length = PROG_DATA_LENGTH - prog_data_index
if(remaining_length > PAGE_LENGTH)
{
returned_page_length = PAGE_LENGTH;
}
else
{
returned_page_length = remaining_length;
prog_data_index = PROG_DATA_LENGTH;
}
return returned_page_length;
}
@endcode
*/
typedef uint32_t (*comblk_page_handler_t)(uint8_t const ** pp_next_page);
#ifdef __cplusplus
}
#endif
#endif /* __MSS_COMBLK_PAGE_HANDLER_H_ */
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x00000000 0x00040000 { ; load region size_region
ER_IROM1 0x00000000 0x00040000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x00010000 { ; RW data
.ANY (+RW +ZI)
}
}
/* RT-Thread config file */
#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__
#define RT_THREAD_PRIORITY_MAX 8
#define RT_TICK_PER_SECOND 1000
#define RT_ALIGN_SIZE 4
#define RT_NAME_MAX 8
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_USING_DEVICE
#define RT_USING_PIN
#define RT_USING_SERIAL
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLE_DEVICE_NAME "uart1"
#define BSP_USING_GPIO
#define BSP_USING_UART0
#define BSP_USING_UART1
#define RT_MAIN_THREAD_STACK_SIZE 512
#define RT_DEBUG_INIT 0
#define RT_TIMER_THREAD_PRIO 4
#define RT_TIMER_THREAD_STACK_SIZE 512
#define RT_USING_SEMAPHORE
#define RT_USING_MUTEX
#define RT_USING_EVENT
#define RT_USING_MAILBOX
#define RT_USING_MESSAGEQUEUE
#define RT_USING_HEAP
#define RT_USING_SMALL_MEM
#define RT_USING_FINSH
#define FINSH_USING_MSH
#define FINSH_USING_MSH_ONLY
#define __FINSH_THREAD_PRIORITY 5
#define FINSH_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX / 8 * __FINSH_THREAD_PRIORITY + 1)
#define FINSH_THREAD_STACK_SIZE 1024
#define FINSH_HISTORY_LINES 5
#define FINSH_USING_SYMTAB
#endif
此差异已折叠。
#include "config.h"
mss_uart_instance_t * const gp_my_uart0 = &g_mss_uart0;
/* gpio and uart0 initialization */
void boardInit(void)
{
/* mss gpio init */
MSS_GPIO_init();
MSS_GPIO_config(MSS_GPIO_0, MSS_GPIO_OUTPUT_MODE);
MSS_GPIO_config(MSS_GPIO_1, MSS_GPIO_OUTPUT_MODE);
/* mss uart0 init: 115200, 8, no, 1 */
MSS_UART_init(gp_my_uart0, MSS_UART_115200_BAUD,
MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
}
INIT_BOARD_EXPORT(boardInit);
/* mss uart0 transmit one byte data */
void MSS_UART_polled_tx_byte(mss_uart_instance_t *this_uart, const uint8_t byte)
{
uint32_t tx_ready;
do {
tx_ready = gp_my_uart0->hw_reg->LSR & 0x20u;
} while(!tx_ready);
gp_my_uart0->hw_reg->THR = byte;
}
/* docking finish component */
void rt_hw_console_output(const char *str)
{
while(*str != '\0')
{
if(*str == '\n')
MSS_UART_polled_tx_byte(gp_my_uart0, '\r');
MSS_UART_polled_tx_byte(gp_my_uart0, *str++);
while(!MSS_UART_tx_complete(&g_mss_uart0));
}
}
/* docking finish component */
char rt_hw_console_getchar(void)
{
char dat;
uint8_t rx_size;
do {
rx_size = MSS_UART_get_rx(gp_my_uart0, (uint8_t *)&dat, 1);
} while(0u == rx_size);
return dat;
}
/* custom finish command */
extern uint32_t SystemCoreClock;
void sayHello(void)
{
rt_kprintf("Hello RT-Thread! By SmartFusion2 M2S010\r\n");
rt_kprintf("MSS System Core Clock: %d\r\n", SystemCoreClock);
}
MSH_CMD_EXPORT(sayHello, "say hello to console");
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册