mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-15 10:58:54 +00:00
v1.1.1
This commit is contained in:
13
bsp/examples/test-camera/SConscript
Normal file
13
bsp/examples/test-camera/SConscript
Normal file
@@ -0,0 +1,13 @@
|
||||
Import('AIC_ROOT')
|
||||
Import('PRJ_KERNEL')
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
CPPPATH = []
|
||||
src = []
|
||||
if GetDepend('AIC_CAMERA_DRV_TEST') and GetDepend('RT_USING_FINSH'):
|
||||
src = Glob('*.c')
|
||||
|
||||
group = DefineGroup('test-camera', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
150
bsp/examples/test-camera/test_camera.c
Normal file
150
bsp/examples/test-camera/test_camera.c
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2024, ArtInChip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Authors: matteo <duanmt@artinchip.com>
|
||||
*/
|
||||
#include <finsh.h>
|
||||
#include <strings.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "aic_common.h"
|
||||
#include "aic_core.h"
|
||||
#include "drv_camera.h"
|
||||
|
||||
struct camera_cmd {
|
||||
char *name;
|
||||
int (*handle1)(rt_device_t dev, u32 arg);
|
||||
int (*handle2)(rt_device_t dev, bool arg);
|
||||
};
|
||||
|
||||
static struct camera_cmd g_camera_cmds[] = {
|
||||
{"channel", camera_set_channel},
|
||||
{"fps", camera_set_fps},
|
||||
{"contrast", camera_set_contrast},
|
||||
{"brightness", camera_set_brightness},
|
||||
{"saturation", camera_set_saturation},
|
||||
{"hue", camera_set_hue},
|
||||
{"sharpness", camera_set_sharpness},
|
||||
{"denoise", camera_set_denoise},
|
||||
{"quality", camera_set_quality},
|
||||
{"autogain", camera_set_autogain},
|
||||
{"aec_val", camera_set_aec_val},
|
||||
{"exposure", camera_set_exposure},
|
||||
|
||||
{"gain_ctrl", NULL, camera_set_gain_ctrl},
|
||||
{"whitebal", NULL, camera_set_whitebal},
|
||||
{"awb", NULL, camera_set_awb},
|
||||
{"aec2", NULL, camera_set_aec2},
|
||||
{"dcw", NULL, camera_set_dcw},
|
||||
{"bpc", NULL, camera_set_bpc},
|
||||
{"wpc", NULL, camera_set_wpc},
|
||||
{"h_flip", NULL, camera_set_h_flip},
|
||||
{"v_flip", NULL, camera_set_v_flip},
|
||||
{"colorbar", NULL, camera_set_colorbar},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
static const char sopts[] = "c:v:lh";
|
||||
static const struct option lopts[] = {
|
||||
{"command", required_argument, NULL, 'c'},
|
||||
{"value", required_argument, NULL, 'v'},
|
||||
{"list", no_argument, NULL, 'l'},
|
||||
{"usage", no_argument, NULL, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
printf("Usage: %s [options]: \n", program);
|
||||
printf("\t -c, --command\t\tioctl command of Camera device\n");
|
||||
printf("\t -v, --value\t\tthe value of the command argument\n");
|
||||
printf("\t -l, --list\t\tList all the supported command\n");
|
||||
printf("\t -h, --usage \n");
|
||||
printf("\n");
|
||||
printf("Example: %s -f nv16 -c 1\n", program);
|
||||
}
|
||||
|
||||
struct camera_cmd *camera_scan_cmd(char *arg)
|
||||
{
|
||||
struct camera_cmd *cmd = g_camera_cmds;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(g_camera_cmds); i++, cmd++) {
|
||||
if (cmd->name && !strncasecmp(cmd->name, arg, strlen(cmd->name)))
|
||||
return cmd;
|
||||
}
|
||||
printf("Invalid command: %s\n", arg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void camera_list_cmds(void)
|
||||
{
|
||||
struct camera_cmd *cmd = g_camera_cmds;
|
||||
int i;
|
||||
|
||||
printf("Supported Camera ioctl commands:\n");
|
||||
for (i = 0; i < ARRAY_SIZE(g_camera_cmds); i++, cmd++) {
|
||||
if (cmd->name)
|
||||
printf("%2d. %s\n", i, cmd->name);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static rt_err_t cmd_test_camera(int argc, char **argv)
|
||||
{
|
||||
struct camera_cmd *cmd = NULL;
|
||||
rt_device_t dev = NULL;
|
||||
u32 val = 0;
|
||||
int c, ret = 0;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
cmd = camera_scan_cmd(optarg);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
val = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
camera_list_cmds();
|
||||
return 0;
|
||||
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cmd)
|
||||
return -RT_EINVAL;
|
||||
|
||||
dev = rt_device_find(CAMERA_DEV_NAME);
|
||||
if (!dev) {
|
||||
pr_err("Failed to find camera device\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) < 0) {
|
||||
pr_err("Failed to open camera device\n");
|
||||
return -RT_EBUSY;
|
||||
}
|
||||
|
||||
printf("Try to set %s %d\n", cmd->name, val);
|
||||
if (cmd->handle1)
|
||||
ret = cmd->handle1(dev, val);
|
||||
else if (cmd->handle2)
|
||||
ret = cmd->handle2(dev, (bool)val);
|
||||
|
||||
if (ret)
|
||||
pr_err("Failed to set %s %ld, return %d\n", cmd->name, val, ret);
|
||||
|
||||
rt_device_close(dev);
|
||||
return RT_EOK;
|
||||
}
|
||||
MSH_CMD_EXPORT_ALIAS(cmd_test_camera, test_camera, test Camera);
|
||||
13
bsp/examples/test-dce/SConscript
Normal file
13
bsp/examples/test-dce/SConscript
Normal file
@@ -0,0 +1,13 @@
|
||||
Import('AIC_ROOT')
|
||||
Import('PRJ_KERNEL')
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
CPPPATH = []
|
||||
src = []
|
||||
if GetDepend('AIC_DCE_DRV_TEST') and GetDepend('RT_USING_FINSH'):
|
||||
src = Glob('*.c')
|
||||
|
||||
group = DefineGroup('test-dce', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
180
bsp/examples/test-dce/test_dce.c
Normal file
180
bsp/examples/test-dce/test_dce.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) 2024, ArtInChip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-09-29 junlong.chen first implementation.
|
||||
* 2024-09-29 junlong.chen ArtInChip
|
||||
*/
|
||||
#include <finsh.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include "aic_core.h"
|
||||
#include "aic_log.h"
|
||||
#include "hal_dce.h"
|
||||
#include "aic_crc32.h"
|
||||
#include <hwcrypto.h>
|
||||
#include <hw_crc.h>
|
||||
|
||||
u8 default_data[] = "It is test data";
|
||||
|
||||
static int software_checksum(u8 *buf, u32 size)
|
||||
{
|
||||
u32 i, val, sum, rest, cnt;
|
||||
u8 *p;
|
||||
u32 *p32, *pe32;
|
||||
|
||||
p = buf;
|
||||
i = 0;
|
||||
sum = 0;
|
||||
cnt = size >> 2;
|
||||
|
||||
if ((unsigned long)buf & 0x3) {
|
||||
for (i = 0; i < cnt; i++) {
|
||||
p = &buf[i * 4];
|
||||
val = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
|
||||
sum += val;
|
||||
}
|
||||
} else {
|
||||
p32 = (u32 *)buf;
|
||||
pe32 = p32 + cnt;
|
||||
while (p32 < pe32) {
|
||||
sum += *p32;
|
||||
p32++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate not 32 bit aligned part */
|
||||
rest = size - (cnt << 2);
|
||||
p = &buf[cnt * 4];
|
||||
val = 0;
|
||||
for (i = 0; i < rest; i++)
|
||||
val += (p[i] << (i * 8));
|
||||
sum += val;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static int hardware_checksum(u8 *data, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
hal_dce_checksum_start(data, len);
|
||||
ret = hal_dce_checksum_wait();
|
||||
if (!ret)
|
||||
return hal_dce_checksum_result();
|
||||
else
|
||||
printf("\t%s error: time out\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hardware_crc32(u8 *data, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
hal_dce_crc32_start(0, data, len);
|
||||
ret = hal_dce_crc32_wait();
|
||||
if (!ret)
|
||||
return hal_dce_crc32_result();
|
||||
else
|
||||
printf("\t%s error: time out\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hardware_rtt_crc32(u8 *data, int len)
|
||||
{
|
||||
struct rt_hwcrypto_ctx *ctx;
|
||||
int result = 0;
|
||||
struct hwcrypto_crc_cfg cfg = {
|
||||
.last_val = 0,
|
||||
.poly = 0x04C11DB7,
|
||||
.width = 32,
|
||||
.xorout = 0,
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
ctx = rt_hwcrypto_crc_create(rt_hwcrypto_dev_default(), HWCRYPTO_CRC_CRC32);
|
||||
rt_hwcrypto_crc_cfg(ctx, &cfg);
|
||||
result = rt_hwcrypto_crc_update(ctx, data, len);
|
||||
rt_hwcrypto_crc_destroy(ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
void int_to_bcd(int num, int *bcd) {
|
||||
int index = 0;
|
||||
while (num != 0) {
|
||||
bcd[index] = num % 16;
|
||||
num /= 16;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
printf("Usage: %s [options]: \n", program);
|
||||
printf("\tParameter 1 is the address of the data to be verified,");
|
||||
printf("\n\tparameter 2 is the length of the data to be verified \n");
|
||||
printf("\n");
|
||||
printf("Example: \n");
|
||||
printf("\t%s 0x80040000 0x100 (test data from ram)\n", program);
|
||||
printf("\t%s (test default data)\n", program);
|
||||
}
|
||||
|
||||
static void cmd_test_dce(int argc, char **argv)
|
||||
{
|
||||
int sw_check_sum, sw_crc32, hw_check_sum, hw_crc32, hw_rtt_crc32, data_len;
|
||||
int version[3] = {0};
|
||||
u8 *data;
|
||||
|
||||
if (!(argc == 1 || argc == 3)) {
|
||||
printf("Usage error\n");
|
||||
usage(argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (argc == 3) {
|
||||
data = (u8 *)strtoul(argv[1], NULL, 0);
|
||||
data_len = strtoul(argv[2], NULL, 0);
|
||||
} else {
|
||||
data = default_data;
|
||||
data_len = sizeof(default_data);
|
||||
}
|
||||
|
||||
if ((u32)data % 4 || data_len % 4) {
|
||||
printf("data and data_len need 4 byte alignment\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hal_dce_init();
|
||||
|
||||
int_to_bcd(hal_get_version(), version);
|
||||
printf("\tDCE version: %d.%d.%d\n", version[2], version[1], version[0]);
|
||||
if (argc == 3)
|
||||
printf("\tdata_addr: 0x%08x, data_len: 0x%08x\n", (int)data, data_len);
|
||||
else
|
||||
printf("\tdata:%s, data_len: 0x%08x\n", data, data_len);
|
||||
sw_check_sum = software_checksum(data, data_len);
|
||||
sw_crc32 = (int)crc32(0, data, data_len);
|
||||
printf("\tsoftware: check_sum 0x%08x, crc32 0x%08x\n", sw_check_sum,
|
||||
sw_crc32);
|
||||
|
||||
hw_check_sum = hardware_checksum(data, data_len);
|
||||
hw_crc32 = hardware_crc32(data, data_len);
|
||||
hw_rtt_crc32 = hardware_rtt_crc32(data, data_len);
|
||||
printf("\thardware: check_sum 0x%08x, crc32 0x%08x, rtt_crc32 0x%08x\n",
|
||||
hw_check_sum, hw_crc32, hw_rtt_crc32);
|
||||
|
||||
if (sw_check_sum != hw_check_sum || sw_crc32 != hw_crc32 ||
|
||||
sw_crc32 != hw_rtt_crc32)
|
||||
printf("\tDCE calculate failed\n");
|
||||
else
|
||||
printf("\tDCE calculate OK\n");
|
||||
|
||||
hal_dce_deinit();
|
||||
return;
|
||||
}
|
||||
|
||||
MSH_CMD_EXPORT_ALIAS(cmd_test_dce, test_dce, test Dce);
|
||||
@@ -106,7 +106,7 @@ int get_fb_info(void)
|
||||
|
||||
ret = mpp_fb_ioctl(g_fb, AICFB_GET_SCREENINFO, &g_fb_info);
|
||||
if (ret < 0)
|
||||
pr_err("ioctl() failed! errno: -%d\n", -ret);
|
||||
pr_err("Failed to get screen info! errno: -%d\n", -ret);
|
||||
#endif
|
||||
pr_info("Screen width: %d, height %d\n",
|
||||
g_fb_info.width, g_fb_info.height);
|
||||
@@ -125,7 +125,7 @@ int set_ui_layer_alpha(int val)
|
||||
alpha.value = val;
|
||||
ret = mpp_fb_ioctl(g_fb, AICFB_UPDATE_ALPHA_CONFIG, &alpha);
|
||||
if (ret < 0)
|
||||
pr_err("ioctl() failed! errno: -%d\n", -ret);
|
||||
pr_err("Failed to update alpha! errno: -%d\n", -ret);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@@ -137,7 +137,7 @@ int sensor_get_fmt(void)
|
||||
|
||||
ret = mpp_dvp_ioctl(DVP_IN_G_FMT, &f);
|
||||
if (ret < 0) {
|
||||
pr_err("ioctl() failed! err -%d\n", -ret);
|
||||
pr_err("Failed to get sensor format! err -%d\n", -ret);
|
||||
// return -1;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ int dvp_subdev_set_fmt(void)
|
||||
|
||||
ret = mpp_dvp_ioctl(DVP_IN_S_FMT, &g_vdata.src_fmt);
|
||||
if (ret < 0) {
|
||||
pr_err("ioctl() failed! err -%d\n", -ret);
|
||||
pr_err("Failed to set DVP in-format! err -%d\n", -ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ int dvp_cfg(int width, int height, int format)
|
||||
|
||||
ret = mpp_dvp_ioctl(DVP_OUT_S_FMT, &f);
|
||||
if (ret < 0) {
|
||||
pr_err("ioctl() failed! err -%d\n", -ret);
|
||||
pr_err("Failed to set DVP out-format! err -%d\n", -ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -183,10 +183,10 @@ int dvp_cfg(int width, int height, int format)
|
||||
|
||||
int dvp_request_buf(struct vin_video_buf *vbuf)
|
||||
{
|
||||
int i;
|
||||
int i, min_num = 3;
|
||||
|
||||
if (mpp_dvp_ioctl(DVP_REQ_BUF, (void *)vbuf) < 0) {
|
||||
pr_err("ioctl() failed!\n");
|
||||
pr_err("Failed to request buf!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -199,6 +199,16 @@ int dvp_request_buf(struct vin_video_buf *vbuf)
|
||||
vbuf->planes[i * vbuf->num_planes + 1].len);
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_ROTATION
|
||||
if (g_vdata.rotation)
|
||||
min_num++;
|
||||
#endif
|
||||
|
||||
if (vbuf->num_buffers < min_num) {
|
||||
pr_err("The number of video buf must >= %d!\n", min_num);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -221,7 +231,7 @@ void dvp_release_buf(int num)
|
||||
int dvp_queue_buf(int index)
|
||||
{
|
||||
if (mpp_dvp_ioctl(DVP_Q_BUF, (void *)(ptr_t)index) < 0) {
|
||||
pr_err("ioctl() failed!\n");
|
||||
pr_err("Q failed! Maybe buf state is invalid.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -234,7 +244,7 @@ int dvp_dequeue_buf(int *index)
|
||||
|
||||
ret = mpp_dvp_ioctl(DVP_DQ_BUF, (void *)index);
|
||||
if (ret < 0) {
|
||||
pr_err("ioctl() failed! err -%d\n", -ret);
|
||||
pr_err("DQ failed! Maybe cannot receive data from Camera. err -%d\n", -ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -247,7 +257,7 @@ int dvp_start(void)
|
||||
|
||||
ret = mpp_dvp_ioctl(DVP_STREAM_ON, NULL);
|
||||
if (ret < 0) {
|
||||
pr_err("ioctl() failed! err -%d\n", -ret);
|
||||
pr_err("Failed to start streaming! err -%d\n", -ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -260,7 +270,7 @@ int dvp_stop(void)
|
||||
|
||||
ret = mpp_dvp_ioctl(DVP_STREAM_OFF, NULL);
|
||||
if (ret < 0) {
|
||||
pr_err("ioctl() failed! err -%d\n", -ret);
|
||||
pr_err("Failed to stop streaming! err -%d\n", -ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -277,7 +287,7 @@ int video_layer_disable(void)
|
||||
layer.enable = 0;
|
||||
ret = mpp_fb_ioctl(g_fb, AICFB_UPDATE_LAYER_CONFIG, &layer);
|
||||
if (ret < 0)
|
||||
pr_err("g_fb ioctl AICFB_UPDATE_LAYER_CONFIG failed !");
|
||||
pr_err("Failed to disable video layer!");
|
||||
|
||||
#endif
|
||||
return ret;
|
||||
@@ -403,7 +413,7 @@ int video_layer_set(struct aic_dvp_data *vdata, int index)
|
||||
}
|
||||
|
||||
if (mpp_fb_ioctl(g_fb, AICFB_UPDATE_LAYER_CONFIG, &layer) < 0) {
|
||||
pr_err("ioctl() failed!\n");
|
||||
pr_err("Failed to update layer config!\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,7 @@ src = []
|
||||
if GetDepend('AIC_QSPI_DRV_TEST') and GetDepend('RT_USING_FINSH'):
|
||||
src = Glob('test_qspidev.c')
|
||||
src += Glob('test_spibit.c')
|
||||
src += Glob('test_spi.c')
|
||||
src += Glob('test_spi_async.c')
|
||||
if GetDepend('AIC_QSPI_DRV_V11') and GetDepend('AIC_CHIP_D13X'):
|
||||
src += Glob('test_spislave*.c')
|
||||
|
||||
319
bsp/examples/test-qspi/test_spi.c
Normal file
319
bsp/examples/test-qspi/test_spi.c
Normal file
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
* Copyright (c) 2024, ArtInChip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Authors: Jiji Chen <jiji.chen@artinchip.com>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <finsh.h>
|
||||
#include <rtdevice.h>
|
||||
#include <aic_core.h>
|
||||
|
||||
#define USAGE \
|
||||
"test_spi help : Get this information.\n" \
|
||||
"test_spi attach <bus name> <dev name> : Attach device to SPI bus.\n" \
|
||||
"test_spi init <name> <mode> <freq> : Initialize SPI for device.\n" \
|
||||
"test_spi send <len> : Send data.\n" \
|
||||
"example:\n" \
|
||||
"test_spi attach spi3 spidev\n" \
|
||||
"test_spi init spidev 0 50000000\n" \
|
||||
"test_spi send 32\n" \
|
||||
"test_spi transfer 32\n" \
|
||||
"test_spi send_recv 33 128\n" \
|
||||
|
||||
|
||||
static void spi_usage(void)
|
||||
{
|
||||
printf("%s", USAGE);
|
||||
}
|
||||
|
||||
static void show_speed(char *msg, u32 len, u32 us)
|
||||
{
|
||||
u32 tmp, speed;
|
||||
|
||||
/* Split to serval step to avoid overflow */
|
||||
tmp = 1000 * len;
|
||||
tmp = tmp / us;
|
||||
tmp = 1000 * tmp;
|
||||
speed = tmp / 1024;
|
||||
|
||||
printf("%s: %d byte, %d us -> %d KB/s\n", msg, len, us, speed);
|
||||
}
|
||||
|
||||
static void hex_dump(uint8_t *data, unsigned long len)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
printf("\n");
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i && (i % 16) == 0)
|
||||
printf("\n");
|
||||
printf("%02x ", data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static struct rt_spi_device *g_spi;
|
||||
|
||||
|
||||
static int test_spi_attach(int argc, char **argv)
|
||||
{
|
||||
struct rt_spi_device *spi_device = RT_NULL;
|
||||
char *bus_name, *dev_name;
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
if (argc != 3) {
|
||||
spi_usage();
|
||||
return -1;
|
||||
}
|
||||
bus_name = argv[1];
|
||||
dev_name = argv[2];
|
||||
|
||||
RT_ASSERT(bus_name != RT_NULL);
|
||||
RT_ASSERT(dev_name != RT_NULL);
|
||||
|
||||
spi_device =
|
||||
(struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
|
||||
if (spi_device == RT_NULL) {
|
||||
printf("malloc failed.\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
result = rt_spi_bus_attach_device(spi_device, dev_name,
|
||||
bus_name, RT_NULL);
|
||||
|
||||
if (result != RT_EOK && spi_device != NULL)
|
||||
rt_free(spi_device);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_spi_init(int argc, char **argv)
|
||||
{
|
||||
struct rt_spi_configuration spi_cfg;
|
||||
struct rt_device *dev;
|
||||
char *name;
|
||||
int ret = 0;
|
||||
|
||||
if (argc != 4) {
|
||||
printf("Argument error, please see help information.\n");
|
||||
return -1;
|
||||
}
|
||||
name = argv[1];
|
||||
|
||||
g_spi = (struct rt_spi_device *)rt_device_find(name);
|
||||
if (!g_spi) {
|
||||
printf("Failed to get device in name %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev = (struct rt_device *)g_spi;
|
||||
if (dev->type != RT_Device_Class_SPIDevice) {
|
||||
g_spi = NULL;
|
||||
printf("%s is not SPI device.\n", name);
|
||||
return -1;
|
||||
}
|
||||
rt_memset(&spi_cfg, 0, sizeof(spi_cfg));
|
||||
spi_cfg.mode = atol(argv[2]);
|
||||
spi_cfg.max_hz = atol(argv[3]);
|
||||
ret = rt_spi_configure(g_spi, &spi_cfg);
|
||||
if (ret < 0) {
|
||||
printf("qspi configure failure.\n");
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_spi_send_recv(int argc, char **argv)
|
||||
{
|
||||
unsigned long send_len, recv_len, align_len, start_us;
|
||||
uint8_t *send_buf, *recv_buf;
|
||||
rt_err_t ret;
|
||||
|
||||
if (!g_spi) {
|
||||
printf("SPI device is not init yet.\n");
|
||||
return;
|
||||
}
|
||||
if (argc < 3) {
|
||||
printf("Argument is not correct, please see help for more information.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
send_len = 0;
|
||||
send_len = strtoul(argv[1], NULL, 0);
|
||||
recv_len = strtoul(argv[2], NULL, 0);
|
||||
|
||||
/* transfer len can not be 0 */
|
||||
if (!send_len || !recv_len)
|
||||
return;
|
||||
|
||||
align_len = roundup(send_len, CACHE_LINE_SIZE);
|
||||
send_buf = aicos_malloc_align(0, align_len, CACHE_LINE_SIZE);
|
||||
u8 *temp = send_buf;
|
||||
int k;
|
||||
for (k = 0; k < send_len; k++) {
|
||||
*temp = k & 0xff;
|
||||
temp++;
|
||||
}
|
||||
align_len = roundup(recv_len, CACHE_LINE_SIZE);
|
||||
recv_buf = aicos_malloc_align(0, align_len, CACHE_LINE_SIZE);
|
||||
rt_memset(recv_buf, 0xee, recv_len);
|
||||
|
||||
if (send_buf == NULL || recv_buf == NULL) {
|
||||
printf("Low memory!\n");
|
||||
return;
|
||||
} else {
|
||||
printf("send len %ld, recv len %ld\n", send_len, recv_len);
|
||||
}
|
||||
|
||||
rt_spi_take_bus((struct rt_spi_device *)g_spi);
|
||||
start_us = aic_get_time_us();
|
||||
ret = rt_spi_send_then_recv(g_spi, (void *)send_buf, send_len, (void *)recv_buf, recv_len);
|
||||
show_speed("spi send recv speed", send_len + recv_len, aic_get_time_us() - start_us);
|
||||
if (ret != 0) {
|
||||
printf("Send_recv data failed. ret = %ld\n", ret);
|
||||
}
|
||||
rt_spi_release_bus((struct rt_spi_device *)g_spi);
|
||||
if (send_buf)
|
||||
aicos_free_align(0, send_buf);
|
||||
if (recv_buf) {
|
||||
printf("receive data:\n");
|
||||
hex_dump(recv_buf, recv_len);
|
||||
printf("\n");
|
||||
aicos_free_align(0, recv_buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_spi_send(int argc, char **argv)
|
||||
{
|
||||
unsigned long data_len, align_len, start_us;
|
||||
uint8_t *data;
|
||||
rt_size_t ret;
|
||||
|
||||
if (!g_spi) {
|
||||
printf("SPI device is not init yet.\n");
|
||||
return;
|
||||
}
|
||||
if (argc < 2) {
|
||||
printf("Argument is not correct, please see help for more information.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
data_len = 0;
|
||||
data_len = strtoul(argv[1], NULL, 0);
|
||||
data = RT_NULL;
|
||||
if (data_len) {
|
||||
align_len = roundup(data_len, CACHE_LINE_SIZE);
|
||||
data = aicos_malloc_align(0, align_len, CACHE_LINE_SIZE);
|
||||
u8 *temp = data;
|
||||
int k;
|
||||
for (k = 0; k < data_len; k++) {
|
||||
*temp = k & 0xff;
|
||||
temp++;
|
||||
}
|
||||
}
|
||||
if (data == NULL) {
|
||||
printf("Low memory!\n");
|
||||
return;
|
||||
} else {
|
||||
printf("data len %ld\n", data_len);
|
||||
}
|
||||
|
||||
rt_spi_take_bus((struct rt_spi_device *)g_spi);
|
||||
start_us = aic_get_time_us();
|
||||
ret = rt_spi_transfer(g_spi, (void *)data, NULL, data_len);
|
||||
show_speed("spi send speed", data_len, aic_get_time_us() - start_us);
|
||||
if (ret != data_len) {
|
||||
printf("Send data failed. ret 0x%x\n", (int)ret);
|
||||
}
|
||||
rt_spi_release_bus((struct rt_spi_device *)g_spi);
|
||||
if (data)
|
||||
aicos_free_align(0, data);
|
||||
}
|
||||
|
||||
static void test_spi_treansfer(int argc, char **argv)
|
||||
{
|
||||
unsigned long data_len, align_len, start_us;
|
||||
uint8_t *data, *recv;
|
||||
rt_size_t ret;
|
||||
|
||||
if (!g_spi) {
|
||||
printf("SPI device is not init yet.\n");
|
||||
return;
|
||||
}
|
||||
if (argc < 2) {
|
||||
printf("Argument is not correct, please see help for more information.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
data_len = 0;
|
||||
data_len = strtoul(argv[1], NULL, 0);
|
||||
data = RT_NULL;
|
||||
if (data_len) {
|
||||
align_len = roundup(data_len, CACHE_LINE_SIZE);
|
||||
data = aicos_malloc_align(0, align_len, CACHE_LINE_SIZE);
|
||||
recv = aicos_malloc_align(0, align_len, CACHE_LINE_SIZE);
|
||||
u8 *temp = data;
|
||||
int k;
|
||||
for (k = 0; k < data_len; k++) {
|
||||
*temp = k & 0xff;
|
||||
temp++;
|
||||
}
|
||||
rt_memset(recv, 0xee, align_len);
|
||||
}
|
||||
if (data == NULL) {
|
||||
printf("Low memory!\n");
|
||||
return;
|
||||
} else {
|
||||
printf("data len %ld\n", data_len);
|
||||
}
|
||||
|
||||
rt_spi_take_bus((struct rt_spi_device *)g_spi);
|
||||
start_us = aic_get_time_us();
|
||||
ret = rt_spi_transfer(g_spi, (void *)data, (void *)recv, data_len);
|
||||
show_speed("spi transfer speed", data_len, aic_get_time_us() - start_us);
|
||||
if (ret != data_len) {
|
||||
printf("Transfer data failed. ret 0x%x\n", (int)ret);
|
||||
}
|
||||
rt_spi_release_bus((struct rt_spi_device *)g_spi);
|
||||
if (data)
|
||||
aicos_free_align(0, data);
|
||||
|
||||
if (recv) {
|
||||
printf("receive data:\n");
|
||||
hex_dump(recv, data_len);
|
||||
printf("\n");
|
||||
aicos_free_align(0, recv);
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_test_spi(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
goto help;
|
||||
|
||||
if (!rt_strcmp(argv[1], "help")) {
|
||||
goto help;
|
||||
} else if (!rt_strcmp(argv[1], "attach")) {
|
||||
test_spi_attach(argc - 1, &argv[1]);
|
||||
return;
|
||||
} else if (!rt_strcmp(argv[1], "init")) {
|
||||
test_spi_init(argc - 1, &argv[1]);
|
||||
return;
|
||||
} else if (!rt_strcmp(argv[1], "send_recv")) {
|
||||
test_spi_send_recv(argc - 1, &argv[1]);
|
||||
return;
|
||||
} else if (!rt_strcmp(argv[1], "send")) {
|
||||
test_spi_send(argc - 1, &argv[1]);
|
||||
return;
|
||||
} else if (!rt_strcmp(argv[1], "transfer")) {
|
||||
test_spi_treansfer(argc - 1, &argv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
help:
|
||||
spi_usage();
|
||||
}
|
||||
|
||||
MSH_CMD_EXPORT_ALIAS(cmd_test_spi, test_spi, Test SPI);
|
||||
@@ -32,8 +32,8 @@
|
||||
/* All data should be 4 bytes aligned. */
|
||||
#define CMD_SIZE 4
|
||||
#define STATUS_SIZE 4
|
||||
#define PKT_SIZE TEST_BUF_SIZE
|
||||
// #define PKT_SIZE 256
|
||||
// #define PKT_SIZE TEST_BUF_SIZE
|
||||
#define PKT_SIZE 256
|
||||
|
||||
int test_qspi_slave_controller_init(u32 id, u32 bus_width,
|
||||
qspi_slave_async_cb cb, void *priv,
|
||||
|
||||
@@ -28,27 +28,38 @@ struct qspirecv_state {
|
||||
u32 bus_width;
|
||||
qspi_slave_handle handle;
|
||||
u8 *work_buf;
|
||||
u8 *tx_buf;
|
||||
u32 data_len;
|
||||
};
|
||||
|
||||
static struct qspirecv_state g_state;
|
||||
|
||||
extern void slave_dump_data(char *msg, u8 *buf, u32 len);
|
||||
#define USAGE \
|
||||
"spirecv help : Get this information.\n" \
|
||||
"spirecv start <spi_id> <bus_width> <rxtx> <data_len>\n" \
|
||||
" rxtx: 0(default) - rx only; 1 - tx only; 2 - full duplex transfer, bus_width should be 1.\n" \
|
||||
" data_len: 256 as default, the len master transfer should be 4 align, if not, you have to set it.\n" \
|
||||
"spirecv stop : stop the spi slave using.\n" \
|
||||
"example:\n" \
|
||||
"spirecv start 3 1 2 2048\n" \
|
||||
"spirecv stop\n" \
|
||||
|
||||
static void qspi_usage(void)
|
||||
{
|
||||
printf("%s", USAGE);
|
||||
}
|
||||
|
||||
|
||||
static int recv_new_data(struct qspirecv_state *state, u8 *buf, u32 len)
|
||||
static int recv_new_data(struct qspirecv_state *state, u8 *tx, u8 *rx, u32 len)
|
||||
{
|
||||
struct qspi_transfer t;
|
||||
int ret;
|
||||
|
||||
memset(&t, 0, sizeof(t));
|
||||
t.rx_data = buf;
|
||||
t.tx_data = tx;
|
||||
t.rx_data = rx;
|
||||
t.data_len = len;
|
||||
|
||||
// memset(buf, 0, len);
|
||||
// printf("%s, reset rx fifo\n", __func__);
|
||||
hal_qspi_slave_fifo_reset(&state->handle, HAL_QSPI_RX_FIFO);
|
||||
ret = hal_qspi_slave_transfer_async(&state->handle, &t);
|
||||
if (ret < 0)
|
||||
@@ -61,6 +72,7 @@ static void qspirecv_slave_async_callback(qspi_slave_handle *h, void *priv)
|
||||
struct qspirecv_state *state = priv;
|
||||
int status, cnt;
|
||||
u32 *p32, cksum;
|
||||
u8 *p;
|
||||
|
||||
status = hal_qspi_slave_get_status(&state->handle);
|
||||
cnt = 0;
|
||||
@@ -69,18 +81,43 @@ static void qspirecv_slave_async_callback(qspi_slave_handle *h, void *priv)
|
||||
* status OK:
|
||||
* TRANSFER DONE or CS INVALID
|
||||
*/
|
||||
// p = state->work_buf;
|
||||
p = state->work_buf;
|
||||
cnt = hal_qspi_slave_transfer_count(&state->handle);
|
||||
printf("%s, status %d, cnt %d\n", __func__, status, cnt);
|
||||
p32 = (void *)state->work_buf;
|
||||
cksum = 0;
|
||||
for (int i = 0; i<PKT_SIZE/4; i++) {
|
||||
cksum += *p32;
|
||||
p32++;
|
||||
if (state->work_buf) {
|
||||
p32 = (void *)state->work_buf;
|
||||
cksum = 0;
|
||||
for (int i = 0; i<g_state.data_len/4; i++) {
|
||||
cksum += *p32;
|
||||
p32++;
|
||||
}
|
||||
printf("cksum 0x%x\n", cksum);
|
||||
slave_dump_data("Recv data", p, cnt);
|
||||
}
|
||||
printf("cksum 0x%x\n", cksum);
|
||||
recv_new_data(state, state->work_buf, PKT_SIZE);
|
||||
// slave_dump_data("Data", p, cnt);
|
||||
|
||||
if (g_state.work_buf) {
|
||||
aicos_free_align(0, g_state.work_buf);
|
||||
g_state.work_buf = aicos_malloc_align(0, g_state.data_len, CACHE_LINE_SIZE);
|
||||
|
||||
if (g_state.work_buf == NULL) {
|
||||
printf("malloc failure.\n");
|
||||
return;
|
||||
}
|
||||
rt_memset(g_state.work_buf, 0x2E, g_state.data_len);
|
||||
}
|
||||
if (g_state.tx_buf) {
|
||||
aicos_free_align(0, g_state.tx_buf);
|
||||
g_state.tx_buf = aicos_malloc_align(0, g_state.data_len, CACHE_LINE_SIZE);
|
||||
|
||||
if (g_state.tx_buf == NULL) {
|
||||
printf("malloc failure.\n");
|
||||
return;
|
||||
}
|
||||
rt_memset(g_state.tx_buf, 0x2E, g_state.data_len);
|
||||
rt_memset(g_state.tx_buf, 0xA4, 16);
|
||||
}
|
||||
|
||||
recv_new_data(state, state->tx_buf, state->work_buf, g_state.data_len);
|
||||
} else {
|
||||
/* Error process */
|
||||
printf("%s, status %d\n", __func__, status);
|
||||
@@ -89,7 +126,7 @@ static void qspirecv_slave_async_callback(qspi_slave_handle *h, void *priv)
|
||||
|
||||
static int test_qspirecv_start(int argc, char **argv)
|
||||
{
|
||||
unsigned long val;
|
||||
unsigned long val, rxtx = 0;
|
||||
int ret;
|
||||
|
||||
if (argc < 2) {
|
||||
@@ -99,13 +136,45 @@ static int test_qspirecv_start(int argc, char **argv)
|
||||
val = strtol(argv[1], NULL, 10);
|
||||
g_state.qspi_id = val;
|
||||
g_state.bus_width = 1; // Default is 1
|
||||
if (g_state.work_buf == NULL)
|
||||
g_state.work_buf =
|
||||
aicos_malloc_align(0, TEST_BUF_SIZE, CACHE_LINE_SIZE);
|
||||
if (argc >= 3) {
|
||||
val = strtol(argv[2], NULL, 10);
|
||||
g_state.bus_width = val;
|
||||
}
|
||||
|
||||
if (argc >= 4) {
|
||||
rxtx = strtol(argv[3], NULL, 10);
|
||||
}
|
||||
|
||||
if (argc >= 5)
|
||||
g_state.data_len = strtol(argv[4], NULL, 10);
|
||||
else
|
||||
g_state.data_len = PKT_SIZE;
|
||||
|
||||
/* rx or Full duplex mode */
|
||||
if (rxtx == 0 || rxtx == 2) {
|
||||
if (g_state.work_buf == NULL)
|
||||
g_state.work_buf = aicos_malloc_align(0, g_state.data_len, CACHE_LINE_SIZE);
|
||||
|
||||
if (g_state.work_buf == NULL) {
|
||||
printf("malloc failure.\n");
|
||||
return -1;
|
||||
}
|
||||
rt_memset(g_state.work_buf, 0x2E, g_state.data_len);
|
||||
}
|
||||
|
||||
/* tx or Full duplex mode */
|
||||
if (rxtx == 1 || rxtx == 2) {
|
||||
if (g_state.tx_buf == NULL)
|
||||
g_state.tx_buf = aicos_malloc_align(0, g_state.data_len, CACHE_LINE_SIZE);
|
||||
|
||||
if (g_state.tx_buf == NULL) {
|
||||
printf("malloc failure.\n");
|
||||
return -1;
|
||||
}
|
||||
rt_memset(g_state.tx_buf, 0x2E, g_state.data_len);
|
||||
rt_memset(g_state.tx_buf, 0xA4, 16);
|
||||
}
|
||||
|
||||
ret = test_qspi_slave_controller_init(g_state.qspi_id, g_state.bus_width,
|
||||
qspirecv_slave_async_callback, &g_state,
|
||||
&g_state.handle);
|
||||
@@ -115,7 +184,7 @@ static int test_qspirecv_start(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* Start with waiting command */
|
||||
recv_new_data(&g_state, g_state.work_buf, PKT_SIZE);
|
||||
recv_new_data(&g_state, g_state.tx_buf, g_state.work_buf, g_state.data_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -126,6 +195,10 @@ static int test_qspirecv_stop(int argc, char **argv)
|
||||
aicos_free_align(0, g_state.work_buf);
|
||||
g_state.work_buf = NULL;
|
||||
}
|
||||
if (g_state.tx_buf) {
|
||||
aicos_free_align(0, g_state.tx_buf);
|
||||
g_state.tx_buf = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -147,5 +220,4 @@ help:
|
||||
qspi_usage();
|
||||
}
|
||||
|
||||
|
||||
MSH_CMD_EXPORT_ALIAS(cmd_test_qspislave_receiver, spirecv, Test QSPI Slave);
|
||||
|
||||
Reference in New Issue
Block a user