456 lines
12 KiB
C
456 lines
12 KiB
C
/****************************************************************************
|
||
|
||
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
||
|
||
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
||
be copied by any method or incorporated into another program without
|
||
the express written consent of Aerospace C.Power. This Information or any portion
|
||
thereof remains the property of Aerospace C.Power. The Information contained herein
|
||
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
||
liability for its use in any way and conveys no license or title under
|
||
any patent or copyright and makes no representation or warranty that this
|
||
Information is free from patent or copyright infringement.
|
||
|
||
****************************************************************************/
|
||
#include "iot_bitops.h"
|
||
#include "dtest_printf.h"
|
||
#include "cpu.h"
|
||
#include "ahb.h"
|
||
|
||
#if HW_PLATFORM > HW_PLATFORM_SIMU
|
||
#include "dbg_io.h"
|
||
#endif
|
||
|
||
#include "chip_reg_base.h"
|
||
#include "ahb_rf_s.h"
|
||
|
||
#include "uart.h"
|
||
#include "strformat.h"
|
||
#include "uart_e.h"
|
||
|
||
#include "mailbox.h"
|
||
#include "mailbox_hw.h"
|
||
#include "iot_irq.h"
|
||
|
||
#include "iot_spinlock.h"
|
||
|
||
extern void _core_start(void);
|
||
extern void _start(void);
|
||
|
||
#define TEST_NUMS 32
|
||
#define BUF_LEN 500
|
||
|
||
static char buf0[BUF_LEN];
|
||
static char buf1[BUF_LEN];
|
||
static char buf2[BUF_LEN];
|
||
|
||
extern struct uart_ctrl uart_e_ctrl;
|
||
#define my_g_uart_ctrl uart_e_ctrl
|
||
|
||
extern void mb_hw_init2(uint32_t ch);
|
||
void register_print_by_addr(uint32_t addr, int num);
|
||
|
||
void delay_sometime(void)
|
||
{
|
||
uint32_t loop;
|
||
loop = 0;
|
||
while(loop++ < 1000000) __asm volatile ("nop\n");
|
||
}
|
||
|
||
void core_working_loop(UART_PORT port, int pin_num, char *buf, int buf_len)
|
||
{
|
||
uint32_t cur_cpu = cpu_get_mhartid();
|
||
int str_len ;
|
||
int inc = 0;
|
||
|
||
// UART init
|
||
my_g_uart_ctrl.init(port);
|
||
my_g_uart_ctrl.config(port, 115200, UART_DATA_8_BITS, UART_STOP_BITS_1,
|
||
UART_PARITY_DISABLE);
|
||
|
||
iot_uart_set_pin(port, 0xff, pin_num);
|
||
|
||
while(1) {
|
||
str_len = iot_snprintf(buf, buf_len, "CPU %d : %d\r\n", cur_cpu, inc);
|
||
my_g_uart_ctrl.puts(port, (uint8_t*)buf, str_len);
|
||
inc ++;
|
||
if (inc > 10000) {
|
||
inc = 0;
|
||
}
|
||
delay_sometime();
|
||
}
|
||
}
|
||
|
||
void core0_mailbox_test(UART_PORT port, int pin_num, char *buf, int buf_len)
|
||
{
|
||
int str_len = 0;
|
||
int mailbox_ch = 1;
|
||
|
||
int read_counter;
|
||
int write_conter;
|
||
|
||
// UART init
|
||
my_g_uart_ctrl.init(port);
|
||
my_g_uart_ctrl.config(port, 115200, UART_DATA_8_BITS, UART_STOP_BITS_1,
|
||
UART_PARITY_DISABLE);
|
||
|
||
iot_uart_set_pin(port, 0xff, pin_num);
|
||
|
||
mb_hw_init();
|
||
mb_hw_init2(mailbox_ch);
|
||
|
||
if(mb_hw_is_empty(mailbox_ch)) {
|
||
iot_printf("mb %d is empty\r\n", mailbox_ch);
|
||
} else {
|
||
iot_printf("mb %d is not empty\r\n", mailbox_ch);
|
||
}
|
||
|
||
delay_sometime();
|
||
|
||
for (int i = 0; i < TEST_NUMS; i ++) {
|
||
mb_hw_write(mailbox_ch, 0xaaaaaaaa + i);
|
||
read_counter = mb_hw_get_counter_for_read(mailbox_ch);
|
||
write_conter = mb_hw_get_counter_for_write(mailbox_ch);
|
||
|
||
str_len = iot_snprintf(buf, buf_len,"read cnt = %d\r\n", read_counter);
|
||
str_len += iot_snprintf(buf + str_len, buf_len - str_len,"write cnt = %d\r\n", write_conter);
|
||
|
||
my_g_uart_ctrl.puts(port, (uint8_t*)buf, str_len);
|
||
delay_sometime();
|
||
}
|
||
|
||
str_len = iot_snprintf(buf , buf_len ,"\r\n\r\n", write_conter);
|
||
|
||
my_g_uart_ctrl.puts(port, (uint8_t*)buf, str_len);
|
||
|
||
for(int i = 0; i < TEST_NUMS; i ++) {
|
||
uint32_t read_value;
|
||
|
||
if (0 == mb_hw_read(mailbox_ch, &read_value) ) {
|
||
str_len = iot_snprintf(buf, buf_len,"read_value = %08x\r\n", read_value);
|
||
my_g_uart_ctrl.puts(port, (uint8_t*)buf, str_len);
|
||
}
|
||
read_counter = mb_hw_get_counter_for_read(mailbox_ch);
|
||
write_conter = mb_hw_get_counter_for_write(mailbox_ch);
|
||
|
||
str_len = iot_snprintf(buf, buf_len,"read cnt = %d\r\n", read_counter);
|
||
str_len += iot_snprintf(buf + str_len, buf_len - str_len,"write cnt = %d\r\n", write_conter);
|
||
|
||
my_g_uart_ctrl.puts(port, (uint8_t*)buf, str_len);
|
||
delay_sometime();
|
||
}
|
||
|
||
while(1);
|
||
}
|
||
|
||
void maibox_cb(int core_id)
|
||
{
|
||
UART_PORT port = (UART_PORT) core_id + 1; // +1:uart0 debug , uart1 --> core0
|
||
char *p_buf;
|
||
int str_len = 0;
|
||
uint32_t read_cnt;
|
||
|
||
switch(core_id) {
|
||
case 0:
|
||
p_buf = buf0;
|
||
break;
|
||
case 1:
|
||
p_buf = buf1;
|
||
break;
|
||
case 2:
|
||
p_buf = buf2;
|
||
break;
|
||
default :
|
||
p_buf = buf0;
|
||
break;
|
||
}
|
||
|
||
read_cnt = iot_mb_get_read_space(core_id);
|
||
if (0 != read_cnt) {
|
||
uint32_t data = 0;
|
||
|
||
iot_mb_read(core_id, &data);
|
||
|
||
str_len = iot_snprintf(p_buf, BUF_LEN,"rcvd from core%d %d\r\n", core_id, data);
|
||
my_g_uart_ctrl.puts(port, (uint8_t*)p_buf, str_len);
|
||
} else {
|
||
str_len = iot_snprintf(p_buf, BUF_LEN,"err :read cnt = %d\r\n", read_cnt);
|
||
my_g_uart_ctrl.puts(port, (uint8_t*)p_buf, str_len);
|
||
}
|
||
}
|
||
|
||
void mailbox_test(UART_PORT port, int pin_num, char *buf, int buf_len)
|
||
{
|
||
uint32_t s_data = 0;
|
||
char *p_buf;
|
||
int str_len;
|
||
|
||
/* UART init */
|
||
my_g_uart_ctrl.init(port);
|
||
my_g_uart_ctrl.config(port, 115200, UART_DATA_8_BITS, UART_STOP_BITS_1,
|
||
UART_PARITY_DISABLE);
|
||
|
||
iot_uart_set_pin(port, 0xff, pin_num);
|
||
|
||
/* mailbox init */
|
||
/*这里是smp架构,这里测试为了避免重复初始化直接调用mb_hw_init(),而不是iot_mb_init();*/
|
||
mb_hw_init();
|
||
iot_mb_open(maibox_cb);
|
||
|
||
uint32_t cur_cpu = cpu_get_mhartid();
|
||
switch(cur_cpu) {
|
||
case 0:
|
||
s_data = 1000; p_buf = buf0;
|
||
break;
|
||
case 1:
|
||
s_data = 2000; p_buf = buf1;
|
||
break;
|
||
case 2:
|
||
s_data = 3000; p_buf = buf2;
|
||
break;
|
||
}
|
||
|
||
while(1) {
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
|
||
str_len = iot_snprintf(p_buf, BUF_LEN,"core%d send %d\r\n", cur_cpu, s_data++);
|
||
my_g_uart_ctrl.puts(port, (uint8_t*)p_buf, str_len);
|
||
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
|
||
switch(cur_cpu) {
|
||
case 0:
|
||
if (iot_mb_get_write_space(1) > 0) {
|
||
iot_mb_write(1, s_data);
|
||
}
|
||
if (iot_mb_get_write_space(2) > 0) {
|
||
iot_mb_write(2, s_data);
|
||
}
|
||
break;
|
||
case 1:
|
||
|
||
if (iot_mb_get_write_space(2) >= 4) {
|
||
iot_mb_write(2, s_data);
|
||
}
|
||
if (iot_mb_get_write_space(0) >= 4) {
|
||
iot_mb_write(0, s_data);
|
||
}
|
||
break;
|
||
case 2:
|
||
if (iot_mb_get_write_space(0) >= 4) {
|
||
iot_mb_write(0, s_data);
|
||
}
|
||
if (iot_mb_get_write_space(1) >= 4) {
|
||
iot_mb_write(1, s_data);
|
||
}
|
||
|
||
break;
|
||
}
|
||
#if 0 /*是否打印某个mailbox的寄存器值*/
|
||
int test_ch = 2;
|
||
if (cur_cpu == test_ch) {
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
register_print_by_addr(MAILBOX_REG_BASEADDR | (test_ch << 5), 1);
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
|
||
register_print_by_addr(MAILBOX_REG_BASEADDR | (test_ch << 5) | 0x10, 4);
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
void nothing()
|
||
{
|
||
while(1);
|
||
}
|
||
|
||
int main(void)
|
||
{
|
||
uint32_t cur_cpu = cpu_get_mhartid();
|
||
|
||
#if 1 /*为1时,启动顺序是 core0 core2 core1.为0时启动顺序是core0 core1 core2*/
|
||
|
||
if (0 == cur_cpu) {
|
||
dbg_uart_init();
|
||
iot_spinlock_init();
|
||
uint32_t pc0 = (uint32_t) _start;
|
||
iot_printf("\r\nstart pc 0 = %08x\r\n", pc0);
|
||
|
||
ahb_core1_disable();
|
||
ahb_core2_disable();
|
||
|
||
ahb_core2_set_start((uint32_t) _core_start);
|
||
ahb_core2_enable();
|
||
ahb_core2_reset();
|
||
|
||
mailbox_test(UART_PT1, 26, buf0, sizeof(buf0)); // 8
|
||
} else if (2 == cur_cpu) {
|
||
|
||
ahb_core1_set_start((uint32_t) _core_start);
|
||
ahb_core1_enable();
|
||
ahb_core1_reset();
|
||
|
||
while(1) {
|
||
mailbox_test(UART_PT2, 27, buf1, sizeof(buf1)); // 7
|
||
}
|
||
} else {
|
||
|
||
while(1) {
|
||
mailbox_test(UART_PT3, 28, buf2, sizeof(buf2) ); // 10
|
||
}
|
||
}
|
||
|
||
#else
|
||
if (0 == cur_cpu) {
|
||
dbg_uart_init();
|
||
iot_spinlock_init();
|
||
uint32_t pc0 = (uint32_t) _start;
|
||
iot_printf("\r\nstart pc 0 = %08x\r\n", pc0);
|
||
|
||
ahb_core1_disable();
|
||
ahb_core2_disable();
|
||
|
||
ahb_core1_set_start((uint32_t) _core_start);
|
||
ahb_core1_enable();
|
||
ahb_core1_reset();
|
||
|
||
mailbox_test(UART_PT1, 26, buf0, sizeof(buf0)); // 8
|
||
} else if (1 == cur_cpu) {
|
||
ahb_core2_set_start((uint32_t) _core_start);
|
||
ahb_core2_enable();
|
||
ahb_core2_reset();
|
||
|
||
mailbox_test(UART_PT2, 27, buf1, sizeof(buf1)); // 7
|
||
}
|
||
else {
|
||
mailbox_test(UART_PT3, 28, buf2, sizeof(buf2) ); // 10
|
||
}
|
||
#endif
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
//--------------------------------下面是单核测试-----------------------------
|
||
|
||
void maibox_cb1(int core_id)
|
||
{
|
||
int test_ch = 0;
|
||
|
||
//注意这里读不能用 iot_mb_get_read_space()
|
||
uint32_t read_cnt = mb_hw_get_counter_for_read(test_ch);//
|
||
if (0 != read_cnt) {
|
||
uint32_t r_data = 0;
|
||
iot_mb_read(test_ch, &r_data);
|
||
iot_printf("rcvd %d\r\n", r_data);
|
||
} else {
|
||
iot_printf("err :read cnt = %d\r\n", read_cnt);
|
||
}
|
||
}
|
||
|
||
// 该函数只方便测试用,故用extern,用户需要使用 iot_mb_init
|
||
extern void mb_hw_init_with_ch(uint32_t ch);
|
||
|
||
void core0_poll_write_core0_int_rcv_test(void)
|
||
{
|
||
int test_ch = 0;
|
||
int s_data = 0;
|
||
|
||
iot_mb_init();
|
||
iot_mb_open(maibox_cb1);
|
||
|
||
while(1) {
|
||
iot_printf("write fifo %d\r\n", s_data);
|
||
mb_hw_write(test_ch, s_data ++ );
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
delay_sometime();
|
||
}
|
||
}
|
||
|
||
// core0 轮询发送,core0中断接收
|
||
int main1(void)
|
||
{
|
||
uint32_t cur_cpu = cpu_get_mhartid();
|
||
|
||
iot_interrupt_init(cur_cpu);
|
||
dbg_uart_init();
|
||
// 26 27 28
|
||
|
||
core0_poll_write_core0_int_rcv_test();
|
||
while(1);
|
||
}
|
||
//--------------------------------下面是打印寄存器----------------------------
|
||
|
||
void register_print_by_addr2(uint32_t addr, int num)
|
||
{
|
||
volatile uint32_t *p_addr = (volatile uint32_t *)addr;
|
||
char *p_buf;
|
||
int str_len = 0;
|
||
uint32_t cur_cpu = cpu_get_mhartid();
|
||
|
||
switch(cur_cpu) {
|
||
case 0:
|
||
p_buf = buf0;
|
||
break;
|
||
case 1:
|
||
p_buf = buf1;
|
||
break;
|
||
case 2:
|
||
p_buf = buf2;
|
||
break;
|
||
}
|
||
|
||
for(int i = 0; i < num; i++) {
|
||
str_len += iot_snprintf(p_buf, BUF_LEN - str_len,"%02x=%08x,",
|
||
(uint32_t)p_addr & 0xff, *p_addr);
|
||
|
||
p_addr ++;
|
||
}
|
||
str_len += iot_snprintf(p_buf, BUF_LEN - str_len,"\r\n");
|
||
UART_PORT port = (UART_PORT) cur_cpu;
|
||
my_g_uart_ctrl.puts(port, (uint8_t*)p_buf, str_len);
|
||
}
|
||
|
||
void register_print_by_addr(uint32_t addr, int num)
|
||
{
|
||
volatile uint32_t *p_addr = (volatile uint32_t *)addr;
|
||
|
||
iot_printf("base=%08x:", addr);
|
||
for(int i = 0; i < num; i++)
|
||
{
|
||
iot_printf("[%02x]=%04x_%04x,",
|
||
(uint32_t)p_addr & 0xff, (*p_addr) >> 16, (*p_addr) & 0xffff );
|
||
p_addr ++;
|
||
}
|
||
iot_printf("\r\n");
|
||
}
|
||
|
||
|
||
|